Registro de depuración

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

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 demo) y decirle a la pestaña Logcat que registre solo esa app seleccionando show only selected application. Es posible filtrar aún más el registro con la expresión EventLogger|ExoPlayerImpl para obtener solo el registro de EventLogger y el reproductor 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 jugador

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 se prepara el reproductor. El usuario pausa la reproducción después de 9.4 segundos y la reanuda 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 entre corchetes son los siguientes:

  • [eventTime=float]: Es la hora real 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 de 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 la pista se registra cuando cambian los segmentos disponibles o seleccionados. Esto ocurre al menos una vez al comienzo de la reproducción. En el siguiente ejemplo, se muestra el registro de segmentos para un flujo 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 seleccionó 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 jugador 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 segmento de video de resolución 640 x 360 tres segundos después de comenzar a reproducir el contenido multimedia.

Selección del decodificador

En la mayoría de los casos, ExoPlayer renderiza contenido multimedia con un MediaCodec adquirido de la plataforma subyacente. Cuando se inicializa un decodificador, se registra en líneas como las siguientes:

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]