Um player é o componente do app que facilita a reprodução de itens de mídia.
A interface Player da Media3
configura um contorno para a funcionalidade geralmente processada por um player. Isso inclui:
- Afetar os controles de reprodução, 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 reprodução aleatória, repetição, velocidade e volume
- Renderizar 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 da Media3 implementam a interface do player, por exemplo:
| Componente | Descrição e observações de comportamento |
|---|---|
ExoPlayer |
Uma API de player de mídia e a implementação padrão da interface Player. |
MediaController |
Interage com uma MediaSession para enviar comandos de reprodução. Se
seu Player e MediaSession estiverem em um
Service separado da Activity ou
Fragment em que a interface do player está, você poderá atribuir o
MediaController como o player do componente de interface, como PlayerView ou Player
Composable. As chamadas de método de reprodução e playlist são enviadas
ao seu Player pela sua 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 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.
|
ForwardingSimpleBasePlayer |
Uma subclasse SimpleBasePlayer projetada para encaminhar operações de reprodução
para outro Player permitindo as mesmas
personalizações de comportamento consistente 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 uma MediaSession não implemente a interface Player, ela exige um Player ao criar uma. O objetivo é fornecer acesso ao Player de outros processos ou linhas de execução.
Arquitetura de reprodução da Media3
Se você tiver acesso a um Player, chame os métodos dele diretamente para emitir comandos de reprodução. Você pode anunciar a reprodução e conceder o controle de reprodução de fontes externas implementando uma MediaSession. Essas fontes externas implementam um MediaController, que facilita a conexão a 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 hospedar 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 reprodução. Isso pode exigir o uso de um controlador de mídia.
Player desempenha um papel fundamental
na arquitetura da 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 de 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 de
MediaItempara reprodução. - Recupere com
getCurrentTimeline() - As instâncias de
Playerpodem fornecer métodos de operação de playlist, como adicionar ou remover umMediaIteme métodos de conveniência, comogetCurrentMediaItem().
- Uma sequência de instâncias de
- 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 do motivo da supressão da reprodução, se aplicável, mesmo que
playWhenReadysejatrue isPlaying: uma indicação de se o player está reproduzindo, que só serátruese o estado de reprodução forSTATE_READY,playWhenReadyfortruee a reprodução não for suprimida
- Posição de reprodução, incluindo:
- Índice atual do item de mídia:
O índice do
MediaItematual na playlist. isPlayingAd: uma indicação de se um anúncio inserido está sendo reproduzido.- Posição de reprodução atual:
A posição de reprodução atual no
MediaItemou 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 do vídeo,
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
detalhes sobre 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 configurar uma interface 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 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 faixa.
- Defina a velocidade do vídeo.
Implementações personalizadas de Player
Para criar um player personalizado, você pode estender o
SimpleBasePlayer
incluído na Media3. Essa classe fornece uma implementação básica da interface Player para reduzir o número de métodos que você precisa implementar ao mínimo.
Comece substituindo o método getState(). Esse método precisa preencher o estado atual do player quando chamado, incluindo:
- O conjunto de comandos disponíveis
- Propriedades de reprodução, como se o player deve começar a reproduzir 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 impor que o State seja criado com uma combinação válida de valores de estado. Ele também vai processar listeners e informar 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 player declara como disponíveis. Encontre o método de handler substituível que corresponde à funcionalidade que você quer implementar. Por exemplo,
substitua o handleSeek()
método 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, você pode usar
ForwardingSimpleBasePlayer para modificar o estado e o comportamento de um
Player atual. Consulte o guia na página de personalização para
mais detalhes.