Registro de depuración

De forma predeterminada, ExoPlayer solo registra errores. Para registrar eventos del reproductor, se puede usar la clase EventLogger. El registro adicional que proporciona puede ser útil para comprender lo que hace el reproductor y depurar los problemas de reproducción. EventLogger implementa AnalyticsListener, por lo que es fácil registrar una instancia con un ExoPlayer:

Kotlin

player.addAnalyticsListener(EventLogger())

Java

player.addAnalyticsListener(new EventLogger());

La forma más fácil de observar el registro es usar la pestaña logcat de Android Studio. Puedes seleccionar tu app como proceso depurable por el nombre del paquete (androidx.media3.demo.main si usas la app de demostración) y indicarle a la pestaña logcat que solo realice registros para esa app seleccionando mostrar solo la aplicación seleccionada. Es posible filtrar aún más el registro con la expresión EventLogger|ExoPlayerImpl para obtener solo el registro de EventLogger y el jugador en sí.

Una alternativa al uso de la pestaña logcat de Android Studio es usar la consola. Por ejemplo:

adb logcat EventLogger:* ExoPlayerImpl:* *:s

Información del reproductor

La clase ExoPlayerImpl entrega dos líneas importantes sobre la versión del reproductor, el dispositivo y el SO en los que se ejecuta la app, y los módulos de ExoPlayer que se cargaron:

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 reproducción

Los cambios de estado del reproductor se registran en líneas 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]

En este ejemplo, la reproducción comienza 0.93 segundos después de que el reproductor se prepara. El usuario pausa la reproducción después de 9.4 segundos y reanuda la reproducción un segundo después a los 10.4 segundos. La reproducción finaliza diez segundos después, a los 20.4 segundos. Los elementos comunes dentro de los corchetes son los siguientes:

  • [eventTime=float]: Indica el tiempo real transcurrido desde la creación del jugador.
  • [mediaPos=float]: Es la posición de reproducción actual.
  • [window=int]: Es el índice de la ventana actual.
  • [period=int]: Es el período actual en esa ventana.

Los elementos finales de cada línea indican el valor del estado que se informa.

Pistas de contenido multimedia

La información de los segmentos se registra cuando cambian los segmentos disponibles o seleccionados. Esto sucede al menos una vez al inicio de la reproducción. En el siguiente ejemplo, se muestra el registro de seguimiento de una transmisión adaptable:

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: ]

En este ejemplo, el reproductor seleccionó cuatro de las cinco pistas de video disponibles. No se selecciona la quinta pista de video porque supera las capacidades del dispositivo, como lo indica supported=NO_EXCEEDS_CAPABILITIES. El reproductor se adaptará entre las pistas de video seleccionadas durante la reproducción. Cuando el reproductor se adapta de un segmento a otro, se registra en una línea como la que se muestra a continuación:

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 línea de registro indica que el reproductor cambió al video con una resolución de 640 x 360 en la pista de tres segundos de contenido multimedia.

Selección del decodificador

En la mayoría de los casos, ExoPlayer procesa contenido multimedia mediante un MediaCodec adquirido de la plataforma subyacente. Cuando se inicializa un decodificador, se registra en líneas 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]