Um player é o componente do app que facilita a reprodução de itens de mídia.
A interface Player
do Media3
define um esboço para a funcionalidade geralmente processada por um player. Isso
inclui:
- Afetando os controles de reprodução, como tocar, pausar e procurar
- Consultar propriedades da mídia em reprodução, como a posição de reprodução
- Gerenciar uma playlist/fila de itens de mídia
- Configurar propriedades de reprodução, como ordem aleatória, repetição, velocidade e volume
- Renderizar vídeos na tela
O Media3 também oferece uma implementação da interface Player
, chamada
ExoPlayer
.
Uma interface comum entre componentes
Vários componentes no Media3 implementam a interface do player, por exemplo:
Componente | Descrição e notas sobre o comportamento |
---|---|
ExoPlayer |
Uma API de player de mídia e a implementação padrão da interface Player . |
MediaController |
Interage com um MediaSession para enviar comandos de reprodução. Se
o Player e o MediaSession estiverem em um
Service separado do Activity ou do
Fragment em que a interface do jogador está, você poderá atribuir o
MediaController como o jogador da interface
PlayerView . As chamadas de método de reprodução e playlist são enviadas
para o Player pelo MediaSession .
|
MediaBrowser |
Além da funcionalidade oferecida por um
MediaController , interage com um
MediaLibrarySession para navegar pelo conteúdo de mídia disponível.
|
ForwardingPlayer |
Uma implementação de Player que encaminha chamadas de método para
outro Player . Use essa classe para suprimir ou modificar
operações específicas substituindo os respectivos métodos.
|
SimpleBasePlayer |
Uma implementação de Player que reduz o número de métodos
a serem implementados ao mínimo. Útil ao usar um player personalizado que você
quer conectar a um MediaSession .
|
CastPlayer |
Uma implementação de Player que se comunica com um app receptor
do Google Cast. O comportamento depende da sessão de transmissão.
|
Embora um MediaSession
não implemente a interface Player
, ele exige
um Player
ao criar um. O objetivo é fornecer acesso ao Player
de outros processos ou threads.
Arquitetura de reprodução do Media3
Se você tiver acesso a um Player
, chame os métodos dele diretamente para emitir
comandos de reprodução. É possível anunciar a reprodução e conceder o controle de reprodução
de fontes externas implementando um MediaSession
. Essas fontes externas
implementam um MediaController
, que facilita a conexão com uma sessão de mídia
e a emissão de solicitações de comando de reprodução.
Ao reproduzir mídia em segundo plano, é necessário armazenar a sessão de mídia e
o player em um MediaSessionService
ou MediaLibraryService
que é executado como um
serviço em primeiro plano. Se você fizer isso, poderá separar o player da atividade
no app que contém a interface do controle de reprodução. Isso pode exigir que
você use um controlador de mídia.
Estado do player
O estado de um media player que implementa a interface Player
consiste
principalmente em quatro categorias de informações:
- Estado da reprodução
- Recupere com
getPlaybackState()
. - O valor de estado definido pela interface é
STATE_IDLE
,STATE_BUFFERING
,STATE_READY
eSTATE_ENDED
.
- Recupere com
- Playlist de itens de mídia
- Uma sequência de instâncias
MediaItem
para reprodução. - Recuperar com
getCurrentTimeline()
- As instâncias de
Player
podem fornecer métodos de operação de playlist, como adicionar ou remover umMediaItem
e métodos de conveniência, comogetCurrentMediaItem()
.
- Uma sequência de instâncias
- Propriedades de reproduzir/pausar, como:
playWhenReady
: uma indicação de se o usuário quer que a mídia seja reproduzida quando possível ou se quer que ela fique pausada.- Motivo da supressão da reprodução:
uma indicação de por que a reprodução foi suprimida, se aplicável, mesmo que
playWhenReady
sejatrue
. isPlaying
: uma indicação de se o player está sendo reproduzido, que serátrue
apenas se o estado de reprodução forSTATE_READY
,playWhenReady
fortrue
e a reprodução não for suprimida.
- Posição da reprodução, incluindo:
- Índice atual do item de mídia:
o índice do
MediaItem
atual na playlist. isPlayingAd
: uma indicação de se um anúncio inserido está sendo veiculado.- Posição de reprodução atual:
a posição de reprodução atual no
MediaItem
atual ou no anúncio inserido.
- Índice atual do item de mídia:
o índice do
Além disso, a interface Player
permite o acesso às
faixas disponíveis,
metadados de mídia,
velocidade de reprodução,
volume e outras
propriedades auxiliares da reprodução.
Detectar mudanças
Use um Player.Listener
para detectar mudanças em um Player
. Consulte a documentação do ExoPlayer sobre
Eventos do player para
saber como criar e usar um listener.
A interface do listener não inclui callbacks para acompanhar a progressão de reprodução normal. Para monitorar continuamente o progresso da reprodução, como configurar uma interface de barra de progresso, consulte a posição atual em intervalos adequados.
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
Java
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
Controlar a reprodução
A interface Player
oferece várias maneiras de manipular o estado e controlar a
reprodução:
- Controles de reprodução básicos,
como
play()
,pause()
,prepare()
estop()
. - Operações de playlist, como
addMediaItem()
ouremoveMediaItem()
. - Procura para mudar o item ou a posição atual.
- Defina os modos de repetição e o modo de ordem aleatória.
- Atualize as preferências de seleção de faixa.
- Defina a velocidade de reprodução.
Implementações personalizadas de Player
Para criar um player personalizado, estenda o
SimpleBasePlayer
incluído no Media3. Essa classe oferece uma implementação básica da interface Player
para reduzir ao mínimo o número de métodos que você precisa implementar.
Comece modificando o método getState()
. Esse método precisa preencher o
estado atual do jogador quando chamado, incluindo:
- O conjunto de comandos disponíveis
- Propriedades de reprodução, como se o player precisa começar a reprodução quando o
estado de reprodução é
STATE_READY
, o índice do item de mídia que está sendo reproduzido e a posição de reprodução dentro do item atual
Kotlin
class CustomPlayer : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build() } }
Java
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build(); } }
SimpleBasePlayer
vai exigir que o State
seja criado com uma combinação
válida de valores de estado. Ele também processa listeners e informa
os listeners sobre mudanças de estado. Se você precisar acionar manualmente uma atualização de estado,
chame invalidateState()
.
Além do método getState()
, você só precisa implementar métodos usados
para comandos que o jogador declara como disponíveis. Encontre o método de manipulador
substituível que corresponde à funcionalidade que você quer implementar. Por exemplo,
substitua o método handleSeek()
para oferecer suporte a operações como COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
e COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
.