Wiedergabeereignisse überwachen
Ereignisse wie Statusänderungen und Wiedergabefehler werden an registrierte Player.Listener
-Instanzen gemeldet. So registrieren Sie einen Listener für den Empfang solcher Ereignisse:
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
enthält leere Standardmethoden, sodass Sie nur die gewünschten Methoden implementieren müssen. Eine vollständige Beschreibung der Methoden und des Zeitpunkts ihres Aufrufs finden Sie in Javadoc. Einige der wichtigsten Methoden werden unten ausführlicher beschrieben.
Listener können entweder einzelne Ereignis-Callbacks implementieren oder einen generischen onEvents
-Callback implementieren, der aufgerufen wird, nachdem ein oder mehrere Ereignisse zusammen aufgetreten sind. Unter Individual callbacks vs onEvents
finden Sie eine Erläuterung, welche für verschiedene Anwendungsfälle bevorzugt werden sollte.
Änderungen des Wiedergabestatus
Änderungen am Player-Status können durch Implementierung von onPlaybackStateChanged(@State int state)
in einem registrierten Player.Listener
empfangen werden. Der Player kann einen von vier Wiedergabestatus haben:
Player.STATE_IDLE
: Dies ist der Anfangszustand sowie der Status, an dem der Player angehalten wird und bei dem die Wiedergabe fehlgeschlagen ist. In diesem Status verfügt der Player nur über begrenzte Ressourcen.Player.STATE_BUFFERING
: Der Spieler kann nicht sofort von der aktuellen Position aus wiedergeben. Dies liegt vor allem daran, dass mehr Daten geladen werden müssen.Player.STATE_READY
: Der Spieler kann von seiner aktuellen Position aus sofort abspielen.Player.STATE_ENDED
: Der Player hat die Wiedergabe aller Medien beendet.
Zusätzlich zu diesen Status hat der Spieler ein playWhenReady
-Flag, das die Nutzerabsicht angibt, zu spielen. Änderungen in diesem Flag können durch Implementierung von onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason)
empfangen werden.
Ein Player wird wiedergegeben (d. h. seine Position geht weiter und dem Nutzer werden Medien präsentiert), wenn alle drei folgenden Bedingungen erfüllt sind:
- Der Player befindet sich im Status
Player.STATE_READY
playWhenReady
isttrue
- Die Wiedergabe wird aus einem von
Player.getPlaybackSuppressionReason
zurückgegebenen Grund nicht unterdrückt
Anstatt diese Attribute einzeln zu prüfen, kann Player.isPlaying
aufgerufen werden. Änderungen an diesem Status können durch Implementierung von onIsPlayingChanged(boolean isPlaying)
empfangen werden:
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. } } });
Wiedergabefehler
Fehler, die dazu führen, dass die Wiedergabe fehlschlägt, können empfangen werden, indem onPlayerError(PlaybackException error)
in einem registrierten Player.Listener
implementiert wird. Wenn ein Fehler auftritt, wird diese Methode aufgerufen, kurz bevor der Wiedergabestatus in Player.STATE_IDLE
übergeht.
Fehlgeschlagene oder angehaltene Wiedergaben können durch Aufrufen von ExoPlayer.prepare
wiederholt werden.
Beachten Sie, dass einige Player
-Implementierungen Instanzen von abgeleiteten Klassen von PlaybackException
übergeben, um zusätzliche Informationen über den Fehler bereitzustellen. Beispiel: ExoPlayer
übergibt ExoPlaybackException
, das type
, rendererIndex
und andere ExoPlayer-spezifische Felder enthält.
Das folgende Beispiel zeigt, wie du erkennen kannst, wenn eine Wiedergabe aufgrund eines HTTP-Netzwerkproblems fehlgeschlagen ist:
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. } } } });
Playlist-Übergänge
Immer wenn der Player zu einem neuen Medienelement in der Playlist wechselt, wird onMediaItemTransition(MediaItem mediaItem,
@MediaItemTransitionReason int reason)
für registrierte Player.Listener
-Objekte aufgerufen. Der Grund gibt an, ob es sich um einen automatischen Übergang, eine Suche (z. B. nach dem Aufruf von player.next()
), eine Wiederholung desselben Elements oder eine Playlist-Änderung handelte (z. B. wenn das aktuell wiedergegebene Element entfernt wird).
Metadaten
Von player.getCurrentMediaMetadata()
zurückgegebene Metadaten können sich aus verschiedenen Gründen ändern: Playlistübergänge, Aktualisierungen von In-Stream-Metadaten oder Aktualisierung des aktuellen MediaItem
während der Wiedergabe.
Wenn Sie an Metadatenänderungen interessiert sind und beispielsweise eine UI aktualisieren möchten, in der der aktuelle Titel angezeigt wird, können Sie auf onMediaMetadataChanged
warten.
Springen zu Videopositionen aktiviert
Der Aufruf von Player.seekTo
-Methoden führt zu einer Reihe von Callbacks an registrierte Player.Listener
-Instanzen:
onPositionDiscontinuity
mitreason=DISCONTINUITY_REASON_SEEK
. Dies ist das direkte Ergebnis des Aufrufs vonPlayer.seekTo
. Der Callback hatPositionInfo
-Felder für die Position vor und nach der Suche.onPlaybackStateChanged
durch jede unmittelbare Statusänderung im Zusammenhang mit der Suche. Möglicherweise gibt es keine solche Änderung.
Einzelne Rückrufe im Vergleich zu onEvents
Listener können wählen, ob sie einzelne Callbacks wie onIsPlayingChanged(boolean isPlaying)
oder den generischen onEvents(Player player, Events events)
-Callback implementieren. Der generische Callback bietet Zugriff auf das Player
-Objekt und gibt die Gruppe von events
an, die zusammen aufgetreten ist. Dieser Callback wird immer nach den Callbacks aufgerufen, die den einzelnen Ereignissen entsprechen.
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); } }
Einzelne Ereignisse sollten in den folgenden Fällen bevorzugt werden:
- Der Listener interessiert sich für die Gründe für Änderungen. z. B. die für
onPlayWhenReadyChanged
oderonMediaItemTransition
angegebenen Gründe. - Der Listener verarbeitet nur die neuen Werte, die durch Callback-Parameter bereitgestellt werden, oder löst etwas anderes aus, das nicht von den Callback-Parametern abhängig ist.
- Die Listener-Implementierung bevorzugt im Methodennamen eine deutlich lesbare Angabe darüber, was das Ereignis ausgelöst hat.
- Der Listener meldet ein Analysesystem, das über alle einzelnen Ereignisse und Statusänderungen informiert werden muss.
Die generische onEvents(Player player, Events events)
sollte in den folgenden Fällen bevorzugt werden:
- Der Listener möchte dieselbe Logik für mehrere Ereignisse auslösen. Beispiel: Eine UI für
onPlaybackStateChanged
undonPlayWhenReadyChanged
aktualisieren. - Der Listener benötigt Zugriff auf das Objekt
Player
, um weitere Ereignisse auszulösen, z. B. die Suche nach einem Medienelementübergang. - Der Listener beabsichtigt, mehrere Statuswerte zu verwenden, die über separate Callbacks gemeinsam oder in Kombination mit
Player
-Getter-Methoden gemeldet werden. Beispielsweise ist die Verwendung vonPlayer.getCurrentWindowIndex()
mit demTimeline
inonTimelineChanged
nur innerhalb desonEvents
-Callbacks sicher. - Der Listener möchte wissen, ob Ereignisse logisch zusammen aufgetreten sind. Beispiel:
onPlaybackStateChanged
zuSTATE_BUFFERING
aufgrund einer Umstellung eines Medienelements.
In einigen Fällen müssen Listener möglicherweise die einzelnen Callbacks mit dem generischen onEvents
-Callback kombinieren, z. B. um Gründe für Änderungen von Medienelementen mit onMediaItemTransition
aufzuzeichnen. Sie werden aber erst dann aktiv, wenn alle Statusänderungen gemeinsam in onEvents
verwendet werden können.
AnalyticsListener
werden verwendet
Bei Verwendung von ExoPlayer
kann durch Aufrufen von addAnalyticsListener
ein AnalyticsListener
mit dem Spieler registriert werden. AnalyticsListener
-Implementierungen können auf detaillierte Ereignisse warten, die für Analyse- und Logging-Zwecke nützlich sein können. Weitere Informationen finden Sie auf der Analytics-Seite.
EventLogger
werden verwendet
EventLogger
ist ein AnalyticsListener
, der für Logging-Zwecke direkt von der Bibliothek bereitgestellt wird. Fügen Sie EventLogger
zu einem ExoPlayer
hinzu, um nützliches zusätzliches Logging mit einer einzigen Zeile zu ermöglichen:
Kotlin
player.addAnalyticsListener(EventLogger())
Java
player.addAnalyticsListener(new EventLogger());
Weitere Informationen finden Sie auf der Seite zum Debug-Logging.
Ereignisse an bestimmten Wiedergabepositionen werden ausgelöst
In einigen Anwendungsfällen müssen Ereignisse an bestimmten Wiedergabepositionen ausgelöst werden. Dies wird mit PlayerMessage
unterstützt. Ein PlayerMessage
kann mit ExoPlayer.createMessage
erstellt werden. Die Wiedergabeposition, an der es ausgeführt werden soll, kann mit PlayerMessage.setPosition
festgelegt werden. Nachrichten werden standardmäßig im Wiedergabethread ausgeführt. Dies kann jedoch mit PlayerMessage.setLooper
angepasst werden. Mit PlayerMessage.setDeleteAfterDelivery
kann gesteuert werden, ob die Nachricht jedes Mal ausgeführt wird, wenn die angegebene Wiedergabeposition erreicht wird (dies kann beim Such- und Wiederholungsmodus mehrere Male passieren) oder nur beim ersten Mal. Sobald die PlayerMessage
konfiguriert ist, kann sie mit PlayerMessage.send
geplant werden.
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();