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 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 reprodução aleatória, repetição, velocidade e volume
- Renderização de vídeo na tela
A Media3 também oferece uma implementação da interface Player, chamada
ExoPlayer.
Uma interface comum entre componentes
Vários componentes na 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 os Player e MediaSession estiverem em um Service separado do Activity ou 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 seu 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.
|
CastPlayer |
Uma implementação de Player que se comunica com um app receptor do Cast. O comportamento depende da sessão do Cast subjacente.
|
Embora um MediaSession não implemente a interface Player, ele exige um Player ao ser criado. O objetivo é 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. Você pode 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 reprodução.
Ao reproduzir mídia em segundo plano, você precisa hospedar 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 UI para controle de reprodução. Isso pode exigir que você use um controlador de mídia.
Player desempenha um papel fundamental na arquitetura do Media3.Estado do player
O estado de um player de mídia que implementa a interface Player consiste principalmente em quatro categorias de informações:
- Estado da 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
MediaItempara reprodução. - Recuperar com
getCurrentTimeline() - As instâncias
Playerpodem fornecer métodos de operação de lista de reprodução, como adicionar ou remover umMediaIteme métodos convenientes, comogetCurrentMediaItem().
- Uma sequência de instâncias
- Propriedades de reprodução/pausa, como:
playWhenReady: uma indicação de se o usuário quer que a mídia seja reproduzida quando possível ou permaneça pausada.- Motivo da supressão da reprodução:
uma indicação de por que a reprodução foi suprimida, se aplicável, mesmo que
playWhenReadysejatrue isPlaying: uma indicação de se o player está reproduzindo conteúdo no momento, 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 se um anúncio inserido está sendo veiculado.- Posição de reprodução atual:
É a posição de reprodução atual no
MediaItemou 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,
metadados de mídia,
velocidade de reprodução,
volume e outras
propriedades auxiliares da reprodução.
Ouvir 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 rastrear a progressão normal da reprodução. Para monitorar continuamente o progresso da reprodução, como configurar uma UI 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 muitas maneiras de manipular o estado e controlar
a reprodução:
- Controles básicos de reprodução
como
play(),pause(),prepare()estop(). - Operações de playlist, como
addMediaItem()ouremoveMediaItem(). - Buscando para mudar o item ou a posição atual.
- Defina os modos de repetição e o modo aleatório.
- Atualize as preferências de seleção de faixas.
- Defina a velocidade de reprodução.
Implementações personalizadas de Player
Para criar um player personalizado, estenda o
SimpleBasePlayer
incluído na 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 for chamado, incluindo:
- O conjunto de comandos disponíveis
- Propriedades de reprodução, como se o player deve começar a tocar quando o
estado de reprodução for
STATE_READY, o índice do item de mídia em reprodução no momento 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 garantir que o State seja criado com uma combinação válida de valores de estado. Ele também processa listeners e informa
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 estar 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.
Modificar implementações do Player
Em vez de criar um Player completamente 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.