Registro de depuração

Por padrão, o ExoPlayer só registra erros. Para registrar eventos do player, use a classe EventLogger. A geração de registros extra que ele oferece pode ser útil para entender o que o player está fazendo, bem como para depurar problemas de reprodução. EventLogger implementa AnalyticsListener, para que você possa registrar uma instância com um ExoPlayer:

Kotlin

player.addAnalyticsListener(EventLogger())

Java

player.addAnalyticsListener(new EventLogger());

Para observar o registro, use a guia logcat do Android Studio. Você pode selecionar seu app como um processo depurável pelo nome do pacote (androidx.media3.demo.main se estiver usando o app de demonstração) e instruir a guia do Logcat a registrar apenas esse app selecionando show only selected application. É possível filtrar ainda mais os registros com a expressão EventLogger|ExoPlayerImpl para receber apenas registros de EventLogger e do próprio player.

Uma alternativa ao uso da guia logcat do Android Studio é usar o console. Exemplo:

adb logcat EventLogger:* ExoPlayerImpl:* *:s

Informações do jogador

A classe ExoPlayerImpl fornece duas linhas importantes sobre a versão do player, o dispositivo e o SO em que o app está sendo executado, as flags de recurso ativas e os módulos do ExoPlayer que foram carregados:

ExoPlayerImpl: Init 59a18ab [AndroidXMedia3/1.0.0-rc02] [flame, Pixel 4, Google, 33] [Canary:ON]
ExoPlayerImpl: Release 59a18ab [AndroidXMedia3/1.0.0-rc02] [flame, Pixel 4, Google, 33] [media3.common, media3.datasource, media3.ui, media3.exoplayer, media3.decoder, media3.exoplayer.dash, media3.extractor]

Estado de reprodução

As mudanças de estado do player são registradas em linhas como estas:

EventLogger: playWhenReady [eventTime=0.00, mediaPos=0.00, window=0, true, USER_REQUEST]
EventLogger: state [eventTime=0.01, mediaPos=0.00, window=0, BUFFERING]
EventLogger: state [eventTime=0.93, mediaPos=0.00, window=0, period=0, READY]
EventLogger: isPlaying [eventTime=0.93, mediaPos=0.00, window=0, period=0, true]
EventLogger: playWhenReady [eventTime=9.40, mediaPos=8.40, window=0, period=0, false, USER_REQUEST]
EventLogger: isPlaying [eventTime=9.40, mediaPos=8.40, window=0, period=0, false]
EventLogger: playWhenReady [eventTime=10.40, mediaPos=8.40, window=0, period=0, true, USER_REQUEST]
EventLogger: isPlaying [eventTime=10.40, mediaPos=8.40, window=0, period=0, true]
EventLogger: state [eventTime=20.40, mediaPos=18.40, window=0, period=0, ENDED]
EventLogger: isPlaying [eventTime=20.40, mediaPos=18.40, window=0, period=0, false]

Neste exemplo, a reprodução começa 0,93 segundo após o player ser preparado. O usuário pausa a reprodução após 9,4 segundos e a retoma um segundo depois, aos 10,4 segundos. A reprodução termina dez segundos depois, aos 20,4 segundos. Os elementos comuns entre colchetes são:

  • [eventTime=float]: o tempo de relógio desde a criação do player.
  • [mediaPos=float]: a posição de reprodução atual.
  • [window=int]: o índice da janela atual.
  • [period=int]: o período atual nessa janela.

Os elementos finais em cada linha indicam o valor do estado que está sendo informado.

Faixas de mídia

As informações da faixa são registradas quando as faixas disponíveis ou selecionadas mudam. Isso acontece pelo menos uma vez no início da reprodução. O exemplo a seguir mostra a geração de registros de faixa para um stream adaptativo:

EventLogger: tracks [eventTime=0.30, mediaPos=0.00, window=0, period=0,
EventLogger:   group [
EventLogger:     [X] Track:0, id=133, mimeType=video/avc, bitrate=261112, codecs=avc1.4d4015, res=426x240, fps=30.0, supported=YES
EventLogger:     [X] Track:1, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0, supported=YES
EventLogger:     [X] Track:2, id=135, mimeType=video/avc, bitrate=1204535, codecs=avc1.4d401f, res=854x480, fps=30.0, supported=YES
EventLogger:     [X] Track:3, id=160, mimeType=video/avc, bitrate=112329, codecs=avc1.4d400c, res=256x144, fps=30.0, supported=YES
EventLogger:     [ ] Track:4, id=136, mimeType=video/avc, bitrate=2400538, codecs=avc1.4d401f, res=1280x720, fps=30.0, supported=NO_EXCEEDS_CAPABILITIES
EventLogger:   ]
EventLogger:   group [
EventLogger:     [ ] Track:0, id=139, mimeType=audio/mp4a-latm, bitrate=48582, codecs=mp4a.40.5, channels=2, sample_rate=22050, supported=YES
EventLogger:     [X] Track:1, id=140, mimeType=audio/mp4a-latm, bitrate=127868, codecs=mp4a.40.2, channels=2, sample_rate=44100, supported=YES
EventLogger:   ]
EventLogger: ]

Neste exemplo, o player selecionou quatro das cinco faixas de vídeo disponíveis. A quinta faixa de vídeo não é selecionada porque excede os recursos do dispositivo, conforme indicado por supported=NO_EXCEEDS_CAPABILITIES. O player se adapta entre as faixas de vídeo selecionadas durante a reprodução. Quando o player se adapta de uma faixa para outra, isso é registrado em uma linha como esta:

EventLogger: downstreamFormat [eventTime=3.64, mediaPos=3.00, window=0, period=0, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0]

Essa linha de registro indica que o player mudou para a faixa de vídeo com resolução de 640x360 três segundos após o início da mídia.

Seleção do decodificador

Na maioria dos casos, o ExoPlayer renderiza mídia usando um MediaCodec adquirido da plataforma de base. Quando um decodificador é inicializado, isso é registrado em linhas como estas:

EventLogger: videoDecoderInitialized [0.77, 0.00, window=0, period=0, video, OMX.qcom.video.decoder.avc]
EventLogger: audioDecoderInitialized [0.79, 0.00, window=0, period=0, audio, OMX.google.aac.decoder]