Registro de depuração

Por padrão, o ExoPlayer registra apenas erros. Para registrar eventos do player, use a classe EventLogger. O registro adicional que ele fornece pode ser útil para entender o que o player está fazendo, bem como para depurar problemas de reprodução. O EventLogger implementa o AnalyticsListener. Por isso, 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 dizer à guia "logcat" para registrar apenas esse app selecionando Mostrar apenas o aplicativo selecionado. É 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 da 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 depois que o player é preparado. O usuário pausa a reprodução após 9,4 segundos e a retoma um segundo depois, em 10,4 segundos. A reprodução termina dez segundos depois, em 20,4 segundos. Os elementos comuns entre colchetes são:

  • [eventTime=float]: o tempo decorrido desde a criação do jogador.
  • [mediaPos=float]: a posição atual da reprodução.
  • [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 de 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 abaixo mostra o registro de rastreamento de 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 está selecionada porque excede as capacidades do dispositivo, conforme indicado por supported=NO_EXCEEDS_CAPABILITIES. O player vai se adaptar entre as faixas de vídeo selecionadas durante a reprodução. Quando o player adapta 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]

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

Seleção de decodificador

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