Android

27 set, 2017

Custom ExoPlayer extra: Kotlin

Publicidade

O objetivo desse artigo é mostrar de forma prática como utilizar o framework Exoplayer da Google.

Por muito tempo tive dificuldade com esse framework devido a sua “complexidade” e falta de referências. Depois de apanhar muito, consegui utilizar em alguns projetos em produção. Resolvi compartilhar com os colegas devs para que não passem pelas mesmas dificuldades que passei de customização.

O que é o Exoplayer?

É um player alternativo ao MediaPlayer Api para tocar audios e videos locais ou pela internet. Ele suporta streams e é de fácil customização (segundo o Google).

Por que e para quê Exoplayer?

O ExoPlayer suporta recursos como transmissão dinâmica adaptativa incluindo DASH e SmoothStreaming, que não são suportados pelo MediaPlayer. E ao contrário do MediaPlayer, é de fácil customização. Por isso é recomendada sua utilização.

Mãos à obra my friends!

Adicione ao build gradle:

implementation 'com.google.android.exoplayer:exoplayer:r2.4.4'fei

Exemplo do player sem customização:

Como customizar o player? PlayerController

Primeiro vamos adicionar o ExoPlayer à nossa view:

<com.google.android.exoplayer2.ui.SimpleExoPlayerView
    android:id="@+id/simpleExoplayer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:controller_layout_id="@layout/exo_player_controllers"
    app:player_layout_id="@layout/exo_player_background">
</com.google.android.exoplayer2.ui.SimpleExoPlayerView>

A propriedade app:controller_layout_id serve para adicionarmos o nosso custom controllers ao nosso player.

Vamos lá

<TextView
    android:id="@+id/exo_position"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:layout_weight="0.15"/>

<com.google.android.exoplayer2.ui.DefaultTimeBar
    android:id="@+id/exo_progress"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:ad_marker_color="@color/colorAccent"
    app:scrubber_color="@color/bgAlpha"
    app:played_color="@color/colorAccent"
    android:layout_weight="1"/>

<TextView
    android:id="@+id/exo_duration"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:layout_weight="0.15"/>

<android.support.design.widget.FloatingActionButton
    android:id="@id/exo_play"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:padding="10dp"
    style="@style/ExoMediaButton.Play"
    android:layout_gravity="bottom|center"
    android:background="@drawable/btn_app"
    android:layout_marginBottom="20dp"/>

<android.support.design.widget.FloatingActionButton
    android:id="@id/exo_pause"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:padding="10dp"
    style="@style/ExoMediaButton.Pause"
    android:layout_gravity="bottom|center"
    android:background="@drawable/btn_app"
    android:layout_marginBottom="20dp"/>

exo_position: tempo corrente do aúdio/video. Colocamos em um TextView normal e conforme vai passando o tempo, ele se atualiza automaticamente.

exo_progress: barra de progresso, que nesse caso, foi usado a DefaultTimeBar, onde podemos setar algumas propriedades de cores, como no exemplo acima.

Obs: Já tentei utilizar várias libs de barra de progresso customizadas e setar o id exo_progress, porém, nunca tive sucesso. O problema é sempre o mesmo, o Exoplayer não consegue inflar a view por não ter compatibilidade (CircleProgress, CircularProgressBar utilizadas sem sucesso).

exo_duration: tempo total do aúdio/video.

exo_play: botão de play. Utilizei um FloatingActionButton.

exo_pause: botão pause, e da mesma forma que o play, também seta a imagem de pause.

Obs: Sempre coloque o pause e o play um sobre o outro, pois quando um é pressionado, o outro o substitui na mesma posição. Para as imagens do botão serem setadas, utilizamos o style que a própria lib nos fornece.

Segue outros controles que podem ser customizados:

<item name="exo_artwork" type="id"/>
<item name="exo_duration" type="id"/>
<item name="exo_ffwd" type="id"/>
<item name="exo_next" type="id"/>
<item name="exo_overlay" type="id"/>
<item name="exo_prev" type="id"/>
<item name="exo_rew" type="id"/>
<item name="exo_shutter" type="id"/>
<item name="exo_subtitles" type="id"/>

Mudar o background

Era uma vez um Androider que tinha um player para fazer, e que era apenas o botão de play e pause. Porém, o background padrão do Exoplayer é preto e ele não achou nada para poder mudar essa história.

Eis que por acaso foi encontrada uma propriedade do além:

app:player_layout_id=”@layout/exo_player_background”

E colocamos esse layout abaixo para salvar a pátria!

<?xml version="1.0" encoding="utf-8"?>

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <View android:id="@id/exo_controller_placeholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <FrameLayout android:id="@id/exo_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</merge>

Apenas deixei essas propriedades assim , vazias e sem nada, para retirar qualquer resquício de background. Caso alguém queira customizar esse background, fiquem à vontade.

Segue o link para saber mais sobre essa propriedades e outras mais para o layout do player.

Why Kotlin?

Esse projeto foi feito em Kotlin e pode não estar com as melhores skills de linguagem, porém, resolvi utilizar como uma maneira de estimular a galera a fazer o mesmo, pegar coisas que são bastante utilizadas no dia a dia dos amigos devs e passar para o amigo Kotlin e todo mundo aprende algo novo.

The End

O projeto está no Github e ele toca um simples .mp3. Qualquer dúvida chame e a gente. Conversamos, e um PR no repositório sempre é bem vindo.