Registro de depuração

Por padrão, o ExoPlayer só registra erros. Para registrar eventos do jogador, a classe EventLogger pode ser usada. O registro extra oferecido pode ser útil para entender o que o player está fazendo e depurar problemas de reprodução. A EventLogger implementa o AnalyticsListener. Portanto, o registro de 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 processo depurável pelo nome do pacote ( androidx.media3.demo.main se estiver usando o app de demonstração) e instruir a guia Logcat para registrar apenas para esse app selecionando show only selected application. É possível filtrar ainda mais a geração de registros com a expressão EventLogger|ExoPlayerImpl para conseguir a geração de registros apenas de EventLogger e do próprio jogador.

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 entrega 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 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 10 segundos depois, aos 20,4 segundos. Os elementos comuns dentro dos colchetes são:

  • [eventTime=float]: o tempo decorrido desde a criação do jogador.
  • [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 das faixas 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 a geração de registros de faixas para um stream 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 foi 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 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]

Essa linha de registro indica que o player mudou para a faixa de vídeo com resolução de 640 x 360 três segundos na 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]