Um player é o componente do app que facilita a reprodução de itens de mídia.
A interface Player do Media3
configura um contorno para a funcionalidade geralmente processada por um player. Isso inclui:
- Afetar os controles de mídia, como reproduzir, pausar e buscar
- 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
- Renderização de vídeos para a 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 Player, por exemplo:
| Componente | Descrição e observações 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 uma
Service separada da Activity ou
Fragment em que a interface do player está, você poderá atribuir o
MediaController como o player para o
componente de interface, como o elemento combinável PlayerView ou Player. 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.
|
SimpleBasePlayer |
Uma implementação de Player que reduz ao mínimo o número de métodos
a serem implementados. Útil ao usar um player personalizado que você quer conectar a um MediaSession.
|
ForwardingSimpleBasePlayer |
Uma subclasse SimpleBasePlayer projetada para encaminhar operações de reprodução
para outro Player, permitindo as mesmas
personalizações de comportamento consistentes que SimpleBasePlayer. Use
essa classe para suprimir ou modificar operações de reprodução específicas.
|
RemoteCastPlayer |
Uma implementação de Player para controlar a reprodução em um app receptor do Cast remoto.
|
CastPlayer |
Uma implementação de Player para controlar a reprodução do Cast local e remota.
|
Embora um MediaSession não implemente a interface Player, ele exige
um Player ao ser criado. O objetivo dele é fornecer acesso ao Player
de outros processos ou linhas de execução.
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 sua reprodução e conceder controle de reprodução a 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 mídia.
Ao reproduzir mídia em segundo plano, é necessário alojar a sessão de mídia e
o player em um MediaSessionService ou MediaLibraryService que seja 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 para controle de mídia. Isso pode exigir que você use um controlador de mídia.
Player desempenha um papel fundamental
na arquitetura do Media3.Estado do jogador
O estado de um player de mídia que implementa a interface Player consiste
principalmente em quatro categorias de informações:
- Estado de reprodução
- Recupere com
getPlaybackState(). - Os valores de estado definidos pela interface são
STATE_IDLE,STATE_BUFFERING,STATE_READYeSTATE_ENDED.
- Recupere com
- Playlist de itens de mídia
- Uma sequência de instâncias de
MediaItempara reprodução. - Recuperar com
getCurrentTimeline() - As instâncias de
Playerpodem 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 de
- Propriedades de reprodução/pausa, como:
playWhenReady: uma indicação de que o usuário quer que a mídia seja reproduzida quando possível ou permaneça pausada.- Motivo da supressão de reprodução:
uma indicação do motivo da supressão de reprodução, se aplicável, mesmo que
playWhenReadysejatrue. isPlaying: uma indicação de que o player está em reprodução, que só serátruese o estado de reprodução forSTATE_READY,playWhenReadyfortruee a reprodução não for suprimida.
- Posição da reprodução, incluindo:
- Índice do item de mídia atual:
o índice do
MediaItematual na playlist. isPlayingAd: uma indicação de que um anúncio inserido está sendo reproduzido.- Posição de reprodução atual:
a posição de reprodução atual no
MediaItematual ou no anúncio inserido.
- Índice do item de mídia atual:
o índice do
Além disso, a interface Player permite o acesso às
faixas disponíveis,
aos metadados de mídia,
à velocidade do vídeo,
ao volume e a 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 normal da reprodução. Para monitorar continuamente o progresso da reprodução, como para configurar uma IU de barra de progresso, consulte a posição atual em intervalos adequados.
Kotlin
fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs, )
Java
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 mídia básicos,
como
play(),pause(),prepare()estop(). - Operações de playlist, como
addMediaItem()ouremoveMediaItem(). - Busca 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 do vídeo.
Implementações personalizadas de Player
Para criar um player personalizado, estenda o
SimpleBasePlayer
incluído no Media3. Essa classe fornece 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 iniciar a reprodução quando o
estado de reprodução for
STATE_READY, o índice do item de mídia em reprodução e a posição de reprodução no item atual.
Kotlin
class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(Commands.EMPTY) // 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
private static final class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(Commands.EMPTY) // 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 garantir que o State seja criado com uma combinação válida de valores de estado. Ele também vai processar listeners e informar
as mudanças de estado a eles. 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 player declara como disponíveis. Encontre o método de gerenciador 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.
Modificar implementações de Player
Em vez de criar um Player totalmente personalizado, use
ForwardingSimpleBasePlayer para modificar o estado e o comportamento de um
Player atual. Consulte o guia na página de personalização para
mais detalhes.