Registro de depuração

Por padrão, o ExoPlayer registra apenas erros. Para registrar eventos do player, a classe EventLogger pode ser usada. Os registros adicionais que ele fornece podem ser úteis para entender o que o player está fazendo, além de depurar problemas de reprodução. EventLogger implementa AnalyticsListener, então registrar uma instância com um ExoPlayer é fácil:

Kotlin

player.addAnalyticsListener(EventLogger())

Java

player.addAnalyticsListener(new EventLogger());

A maneira mais fácil de observar o registro é usando 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 informar à guia Logcat para registrar apenas esse app selecionando show only selected application. É possível filtrar ainda mais o registro com a expressão EventLogger|ExoPlayerImpl para receber apenas o registro de EventLogger e do próprio player.

Uma alternativa ao uso da guia Logcat do Android Studio é usar o console. Por 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 e os módulos do ExoPlayer que foram carregados:

ExoPlayerImpl: Init 59a18ab [AndroidXMedia3/1.0.0-rc02] [flame, Pixel 4, Google, 33]
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 no 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 retoma a reprodução um segundo depois, aos 10,4 segundos. A reprodução termina 10 segundos depois, aos 20,4 segundos. Os elementos comuns dentro dos colchetes são:

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

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 são alteradas. Isso acontece pelo menos uma vez no início da reprodução. O exemplo abaixo mostra o registro de faixas para um fluxo adaptável:

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 as capacidades do dispositivo, conforme indicado por supported=NO_EXCEEDS_CAPABILITIES. O player se adaptará entre as faixas de vídeo selecionadas durante a reprodução. Quando o jogador se adapta de uma faixa a outra, isso é registrado em uma linha como a abaixo:

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]

Esta linha de registro indica que o player mudou para a faixa de vídeo de resolução 640x360 aos três segundos de mídia.

Seleção do decodificador

Na maioria dos casos, o ExoPlayer renderiza mídia usando um MediaCodec adquirido da plataforma subjacente. Quando um decodificador é inicializado, ele é 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]