Cómo escuchar eventos de reproducción
Los eventos, como cambios de estado y errores de reproducción, se informan a los
Player.Listener
de instancias. Para registrar un objeto de escucha de modo que reciba dicho
eventos:
Kotlin
// Add a listener to receive events from the player. player.addListener(listener)
Java
// Add a listener to receive events from the player. player.addListener(listener);
Player.Listener
tiene métodos predeterminados vacíos, por lo que solo debes implementar
y los métodos que te interesan. Consulta Javadoc para obtener una descripción completa de
los métodos y cuándo se los llama. Algunos de los métodos más importantes son
se describen con más detalle a continuación.
Los objetos de escucha tienen la opción de implementar devoluciones de llamada de eventos individuales o una
Es la devolución de llamada onEvents
genérica que se llama después de que ocurren uno o más eventos.
entre sí. Consulta Individual callbacks vs onEvents
para obtener una explicación.
se prefiere para distintos casos de uso.
Cambios en el estado de reproducción
Los cambios en el estado del reproductor se pueden recibir implementando
onPlaybackStateChanged(@State int state)
en un
Player.Listener
El reproductor puede estar en uno de los siguientes cuatro estados de reproducción:
Player.STATE_IDLE
: Es el estado inicial, el estado en el que el reproductor se encuentra y cuando falló la reproducción. El reproductor solo contendrá recursos limitados en este estado.Player.STATE_BUFFERING
: El reproductor no puede reproducir inmediatamente desde su la posición actual. Esto sucede principalmente porque se deben cargar más datos.Player.STATE_READY
: El reproductor puede reproducir de inmediato el contenido actual. posición.Player.STATE_ENDED
: El reproductor terminó de reproducir todo el contenido multimedia.
Además de estos estados, el jugador tiene una marca playWhenReady
para indicar
la intención de jugar del usuario. Los cambios en esta marca se pueden recibir implementando
onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason)
Se está reproduciendo un reproductor (es decir, su posición avanza y se reproduce contenido multimedia) presentarse al usuario) cuando se cumplen las tres condiciones siguientes:
- El reproductor está en el estado
Player.STATE_READY
playWhenReady
estrue
.- La reproducción no se suprimió por algún motivo devuelto por
Player.getPlaybackSuppressionReason
En lugar de tener que verificar estas propiedades de forma individual, Player.isPlaying
un modelo de AA. Los cambios en este estado se pueden recibir implementando
onIsPlayingChanged(boolean isPlaying)
:
Kotlin
player.addListener( object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.playWhenReady, // player.playbackState, player.playbackSuppressionReason and // player.playerError for details. } } } )
Java
player.addListener( new Player.Listener() { @Override public void onIsPlayingChanged(boolean isPlaying) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.getPlayWhenReady, // player.getPlaybackState, player.getPlaybackSuppressionReason and // player.getPlaybackError for details. } } });
Errores de reproducción
Los errores que causan fallas en la reproducción se pueden recibir implementando
onPlayerError(PlaybackException error)
en un
Player.Listener
Cuando se produce un error, se llamará a este método
inmediatamente antes de que el estado de reproducción pase a Player.STATE_IDLE
.
Si deseas reintentar las reproducciones con errores o detenidas, llama a ExoPlayer.prepare
.
Ten en cuenta que algunas implementaciones de Player
pasan instancias de subclases de
PlaybackException
para proporcionar información adicional sobre la falla. Para
Por ejemplo, ExoPlayer
pasa ExoPlaybackException
, que tiene type
,
rendererIndex
y otros campos específicos de ExoPlayer.
En el siguiente ejemplo se muestra cómo detectar un error en la reproducción debido a una Problema de red HTTP:
Kotlin
player.addListener( object : Player.Listener { override fun onPlayerError(error: PlaybackException) { val cause = error.cause if (cause is HttpDataSourceException) { // An HTTP error occurred. val httpError = cause // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError is InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } } )
Java
player.addListener( new Player.Listener() { @Override public void onPlayerError(PlaybackException error) { @Nullable Throwable cause = error.getCause(); if (cause instanceof HttpDataSourceException) { // An HTTP error occurred. HttpDataSourceException httpError = (HttpDataSourceException) cause; // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError instanceof HttpDataSource.InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } });
Transiciones de la playlist
Cada vez que el reproductor cambia a un nuevo elemento multimedia de la playlist
Se llama a onMediaItemTransition(MediaItem mediaItem,
@MediaItemTransitionReason int reason)
en registros
Player.Listener
. El motivo indica si se trata de una implementación
una transición, un salto (por ejemplo, después de llamar a player.next()
), una repetición de
mismo elemento o debido a un cambio en la playlist (por ejemplo, si el
el elemento que se está reproduciendo).
Metadatos
Los metadatos que devuelve player.getCurrentMediaMetadata()
pueden cambiar debido a muchos
razones: transiciones de playlists, actualizaciones de metadatos in-stream o actualización de
actual MediaItem
en medio de la reproducción.
Si te interesan los cambios en los metadatos, por ejemplo, para actualizar una IU que muestra
el título actual, puedes escuchar onMediaMetadataChanged
.
Buscando
Llamar a los métodos Player.seekTo
da como resultado una serie de devoluciones de llamada a registros
Instancias de Player.Listener
:
onPositionDiscontinuity
conreason=DISCONTINUITY_REASON_SEEK
. Este es el resultado directo de la llamada aPlayer.seekTo
La devolución de llamada tienePositionInfo
. para la posición antes y después del salto.onPlaybackStateChanged
con cualquier cambio de estado inmediato relacionado con la búsqueda. Ten en cuenta que es posible que no haya ese cambio.
Devoluciones de llamada individuales en comparación con onEvents
Los objetos de escucha pueden elegir entre implementar devoluciones de llamada individuales, como
onIsPlayingChanged(boolean isPlaying)
y el genérico
Devolución de llamada onEvents(Player player, Events events)
. La devolución de llamada genérica brinda
acceso al objeto Player
y especifica el conjunto de events
que se produjo
entre sí. Esta devolución de llamada siempre se llama después de las devoluciones de llamada que corresponden a
los eventos individuales.
Kotlin
override fun onEvents(player: Player, events: Player.Events) { if ( events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED) ) { uiModule.updateUi(player) } }
Java
@Override public void onEvents(Player player, Events events) { if (events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)) { uiModule.updateUi(player); } }
Se deben preferir eventos individuales en los siguientes casos:
- El objeto de escucha está interesado en los motivos de los cambios. Por ejemplo, el
motivos proporcionados para
onPlayWhenReadyChanged
oonMediaItemTransition
. - El objeto de escucha solo actúa sobre los valores nuevos proporcionados a través de los parámetros de devolución de llamada o activa algo más que no depende de los parámetros de devolución de llamada.
- La implementación del objeto de escucha prefiere una indicación clara y legible de lo que activó el evento en el nombre del método.
- El oyente informa a un sistema de análisis que necesita saber acerca de todos eventos individuales y cambios de estado.
Se debe preferir el onEvents(Player player, Events events)
genérico en las
los siguientes casos:
- El objeto de escucha quiere activar la misma lógica para varios eventos. Para
Por ejemplo, actualizar una IU para
onPlaybackStateChanged
yonPlayWhenReadyChanged
- El objeto de escucha necesita acceder al objeto
Player
para activar más eventos. como la búsqueda después de la transición de un elemento multimedia. - El objeto de escucha intenta usar múltiples valores de estado que se informan
a través de devoluciones de llamada separadas o en combinación con el método get
Player
. Por ejemplo, si usasPlayer.getCurrentWindowIndex()
con el LosTimeline
proporcionados enonTimelineChanged
solo están seguros en elonEvents
. - El objeto de escucha está interesado en si los eventos ocurrieron juntos de forma lógica. Para
ejemplo,
onPlaybackStateChanged
aSTATE_BUFFERING
debido a un elemento multimedia transición.
En algunos casos, es posible que los objetos de escucha necesiten combinar las devoluciones de llamada individuales con el
Es la devolución de llamada genérica de onEvents
, por ejemplo, para grabar motivos de cambio de elementos multimedia.
con onMediaItemTransition
, pero solo actuar una vez que se puedan usar todos los cambios de estado
juntos en onEvents
.
AnalyticsListener
en uso
Cuando se usa ExoPlayer
, se puede registrar un AnalyticsListener
con el reproductor
llamando a addAnalyticsListener
. Las implementaciones de AnalyticsListener
pueden
para escuchar eventos detallados que podrían ser útiles para las estadísticas y los registros
comerciales. Consulta la página de estadísticas para obtener más detalles.
EventLogger
en uso
EventLogger
es un objeto AnalyticsListener
que proporciona directamente la biblioteca para
de registro. Agrega EventLogger
a una ExoPlayer
para habilitar funciones útiles
registros adicionales con una sola línea:
Kotlin
player.addAnalyticsListener(EventLogger())
Java
player.addAnalyticsListener(new EventLogger());
Consulta la página del registro de depuración para obtener más detalles.
Cómo activar eventos en posiciones de reproducción especificadas
Algunos casos de uso requieren que se activen eventos en posiciones de reproducción especificadas. Este es
compatible con PlayerMessage
. Se puede crear un PlayerMessage
con
ExoPlayer.createMessage
La posición de reproducción en la que debe ejecutarse
se pueden configurar con PlayerMessage.setPosition
. Los mensajes se ejecutan en la
subproceso de reproducción de forma predeterminada, pero se puede personalizar
PlayerMessage.setLooper
Se puede usar PlayerMessage.setDeleteAfterDelivery
para controlar si el mensaje se ejecutará cada vez que se cumpla
se encuentra la posición de reproducción (esto puede ocurrir varias veces debido a la
y los modos de repetición), o solo la primera vez. Una vez que PlayerMessage
esté
se puede programar con PlayerMessage.send
.
Kotlin
player .createMessage { messageType: Int, payload: Any? -> } .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send()
Java
player .createMessage( (messageType, payload) -> { // Do something at the specified playback position. }) .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120_000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send();