O player é o componente do app que facilita a reprodução de itens de mídia.
A interface Player
da Media3
define uma descrição da funcionalidade que geralmente é processada pelo player. Isso
inclui:
- Afeta os controles de reprodução, como tocar, pausar e procurar
- Consultar propriedades da mídia em reprodução no momento, 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 o vídeo na tela
A Media3 também oferece uma implementação da interface Player
, chamada
ExoPlayer
.
Uma interface comum entre os componentes
Vários componentes da Media3 implementam a interface Player, por exemplo:
Component | Descrição e notas de 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
Player e MediaSession estiverem em um
Service separado do Activity ou
Fragment em que a interface do player reside, você pode atribuir seu
MediaController como o player 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 , ele 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. Ú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 Cast. O comportamento depende da sessão de transmissão subjacente.
|
Embora um MediaSession
não implemente a interface Player
, ele requer
uma Player
ao criar uma. A finalidade dele é fornecer acesso ao Player
por outros processos ou linhas de execução.
Arquitetura de reprodução da Media3
Se você tiver acesso a um Player
, chame os métodos 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 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, você precisa hospedar sua sessão de mídia e
o player em um MediaSessionService
ou MediaLibraryService
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 que você
use um controlador de mídia.
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
- Recuperar com
getPlaybackState()
. - O valor do estado definido pela interface é
STATE_IDLE
,STATE_BUFFERING
,STATE_READY
eSTATE_ENDED
.
- Recuperar 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 "Reproduzir/pausar", como:
playWhenReady
: uma indicação se o usuário quer abrir a mídia quando possível ou permanecer pausada.- Motivo de supressão de reprodução:
uma indicação do motivo pelo qual a reprodução foi suprimida, se aplicável, mesmo que
playWhenReady
sejatrue
isPlaying
: uma indicação se o player está sendo reproduzido, que só serátrue
se o estado da 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 se um anúncio inserido está sendo reproduzido.- 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 acesso às
faixas disponíveis,
metadados de mídia,
velocidade da 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 jogador para
saber mais sobre 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, por exemplo, para 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 muitas maneiras de manipular o estado e a reprodução
de controle:
- Controles de reprodução básicos,
como
play()
,pause()
,prepare()
estop()
. - Operações de playlist, como
addMediaItem()
ouremoveMediaItem()
. - Procurando 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 faixas.
- Defina a velocidade de reprodução.
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 ao mínimo o número de métodos que você precisa implementar.
Comece substituindo o método getState()
. Esse método precisa preencher o
estado atual do player quando chamado, incluindo:
- Conjunto de comandos disponíveis
- Propriedades de reprodução, por exemplo, se o player precisa começar a reprodução quando o
estado da reprodução é
STATE_READY
, o índice do item de mídia em reprodução no momento e a posição da 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
fará com que a State
seja criada com uma combinação
válida de valores de estado. Ele também processará os listeners e os informará
sobre as 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 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
.