Spielerereignisse

Wiedergabeereignisse überwachen

Ereignisse wie Statusänderungen und Wiedergabefehler werden an registrierte Player.Listener Instanzen. Um einen Listener zu registrieren, Events:

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 folgenden Implementierungen vornehmen müssen: die Sie interessieren. Eine vollständige Beschreibung finden Sie im Javadoc. und wann sie aufgerufen werden. Zu den wichtigsten Methoden gehören die nachfolgend ausführlicher beschrieben sind.

Listener haben die Wahl zwischen der Implementierung einzelner Ereignis-Callbacks oder eines Allgemeiner onEvents-Callback, der nach dem Eintreten eines oder mehrerer Ereignisse aufgerufen wird miteinander verbinden. Eine Erklärung dazu finden Sie unter Individual callbacks vs onEvents. die für verschiedene Anwendungsfälle bevorzugt werden sollten.

Änderungen des Wiedergabestatus

Änderungen am Player-Status können empfangen werden, indem onPlaybackStateChanged(@State int state) in einer registrierten Player.Listener. Der Player kann sich in einem von vier Wiedergabestatus befinden:

  • Player.STATE_IDLE: Dies ist der Ausgangszustand, d. h. der Status, wenn der Player und wenn die Wiedergabe fehlgeschlagen ist. Der Spieler kann nur begrenzte Ressourcen haben in diesem Status.
  • Player.STATE_BUFFERING: Der Player kann auf seinem aktuelle Position. Dies liegt vor allem daran, dass mehr Daten geladen werden müssen.
  • Player.STATE_READY: Der Player kann sofort vom aktuellen .
  • Player.STATE_ENDED: Der Player hat die Wiedergabe aller Medien beendet.

Zusätzlich zu diesen Status gibt der Spieler mit dem Flag playWhenReady an, die Absicht der Nutzer. Änderungen in diesem Flag können empfangen werden, indem Sie Folgendes implementieren: onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason)

Ein Player spielt eine neue Rolle, d. h. die Position rückt vor und die Medien werden angezeigt werden), wenn alle drei der folgenden Bedingungen erfüllt sind:

  • Der Player hat den Status Player.STATE_READY
  • playWhenReady ist true
  • Die Wiedergabe wurde aus einem der folgenden Gründe nicht unterdrückt: Player.getPlaybackSuppressionReason

Anstatt diese Eigenschaften einzeln zu prüfen, Player.isPlaying aufgerufen werden kann. Änderungen an diesem Status können empfangen werden, indem Sie Folgendes implementieren: 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.
        }
      }
    });

Wiedergabefehler

Fehler, die zu einem Fehler bei der Wiedergabe führen, können durch die Implementierung onPlayerError(PlaybackException error) in einer registrierten Player.Listener. Wenn ein Fehler auftritt, wird diese Methode aufgerufen unmittelbar bevor der Wiedergabestatus zu Player.STATE_IDLE wechselt. Fehlgeschlagene oder angehaltene Wiedergaben können durch Aufrufen von ExoPlayer.prepare noch einmal versucht werden.

Beachten Sie, dass einige Player-Implementierungen Instanzen von abgeleiteten Klassen von PlaybackException, um zusätzliche Informationen zum Fehler anzugeben. Für Beispiel: ExoPlayer übergibt ExoPlaybackException mit type, rendererIndex und anderen ExoPlayer-spezifischen Feldern enthalten sind.

Das folgende Beispiel zeigt, wie Sie erkennen, wenn eine Wiedergabe aufgrund eines HTTP-Netzwerkproblem:

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 onMediaItemTransition(MediaItem mediaItem, @MediaItemTransitionReason int reason) wird bei der Registrierung aufgerufen Player.Listener-Objekte. Der Grund gibt an, ob es sich um eine automatische Transition, eine Suche (z. B. nach dem Aufruf von player.next()), eine Wiederholung von oder durch eine Playlist-Änderung verursacht wird, z. B. wenn wiedergegebenes Element entfernt wird).

Metadaten

Von player.getCurrentMediaMetadata() zurückgegebene Metadaten können sich aus vielen Gründen ändern. Gründe: Playlist-Übergänge, Aktualisierungen von In-Stream-Metadaten oder aktuell MediaItem während der Wiedergabe.

Wenn Sie an Metadatenänderungen interessiert sind, z. B. um eine UI zu aktualisieren, auf der dem aktuellen Titel, kannst du onMediaMetadataChanged anhören.

Springen zu Videopositionen aktiviert

Der Aufruf von Player.seekTo-Methoden führt zu einer Reihe von Callbacks an registrierte Player.Listener Instanzen:

  1. onPositionDiscontinuity mit reason=DISCONTINUITY_REASON_SEEK. Dies ist das direkte Ergebnis des Aufrufs von Player.seekTo. Der Callback hat PositionInfo für die Position vor und nach der Suche.
  2. onPlaybackStateChanged mit jeder sofortigen Statusänderung in Bezug auf die Suche. Hinweis: Unter Umständen gab es keine solche Änderung.

Einzelne Callbacks im Vergleich zu onEvents

Listener können wählen, ob sie einzelne Callbacks implementieren möchten: onIsPlayingChanged(boolean isPlaying) und die allgemeinen onEvents(Player player, Events events)-Rückruf. Die allgemeine Callback-Funktion bietet Zugriff auf das Player-Objekt und gibt die Anzahl der aufgetretenen events an. miteinander verbinden. Dieser Callback wird immer nach den Callbacks aufgerufen, die sich auf die die einzelnen Ereignisse.

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. Beispiel: Der Parameter Gründe für onPlayWhenReadyChanged oder onMediaItemTransition angegeben.
  • Der Listener reagiert nur auf die neuen Werte, die über Callback-Parameter bereitgestellt werden. oder etwas anderes auslöst, das nicht von den Callback-Parametern abhängt.
  • Die Listener-Implementierung bevorzugt eine klar lesbare Angabe, das Ereignis im Methodennamen ausgelöst hat.
  • Der Hörer meldet sich an ein Analysesystem, das alle Informationen einzelne Ereignisse und Statusänderungen.

Die generische onEvents(Player player, Events events) sollte im folgenden Fällen:

  • Der Listener möchte für mehrere Ereignisse dieselbe Logik auslösen. Für Beispiel: Das Aktualisieren einer UI für onPlaybackStateChanged und onPlayWhenReadyChanged.
  • Der Listener benötigt Zugriff auf das Objekt Player, um weitere Ereignisse auszulösen. zum Beispiel die Suche nach dem Übergang eines Medienelements.
  • Der Listener möchte mehrere Statuswerte verwenden, die gemeldet werden. durch separate Callbacks gemeinsam oder in Kombination mit dem Player-Getter . Wenn Sie z. B. Player.getCurrentWindowIndex() mit dem Parameter Die in onTimelineChanged angegebene Timeline ist nur innerhalb des folgenden Bereichs sicher: onEvents-Rückruf.
  • Der Listener möchte wissen, ob Ereignisse logisch zusammen aufgetreten sind. Für Beispiel: onPlaybackStateChanged auf STATE_BUFFERING aufgrund eines Medienelements zu übertragen.

In einigen Fällen müssen Listener die einzelnen Callbacks möglicherweise mit dem Parameter Allgemeiner onEvents-Callback, z. B. zum Erfassen von Gründen für Änderungen an Medienelementen mit onMediaItemTransition handeln, aber nur agieren, wenn alle Statusänderungen verwendet werden können zusammen in onEvents.

AnalyticsListener verwenden

Bei Verwendung von ExoPlayer kann ein AnalyticsListener mit dem Spieler registriert werden indem du addAnalyticsListener aufrufst. AnalyticsListener-Implementierungen können um detaillierte Ereignisse zu überwachen, die für Analysen und Logging nützlich sein können zu verstehen. Weitere Informationen finden Sie auf der Seite „Analytics“.

EventLogger verwenden

EventLogger ist eine AnalyticsListener, die direkt von der Bibliothek für Protokollierungszwecke. EventLogger zu ExoPlayer hinzufügen, um nützliche Funktionen zu aktivieren zusätzliche Protokollierung in einer einzigen Zeile:

Kotlin

player.addAnalyticsListener(EventLogger())

Java

player.addAnalyticsListener(new EventLogger());

Weitere Informationen finden Sie auf der Seite für die Protokollierung der Fehlerbehebung.

Ereignisse an bestimmten Wiedergabepositionen auslösen

Einige Anwendungsfälle erfordern das Auslösen von Ereignissen an bestimmten Wiedergabepositionen. Dies ist unterstützt mit PlayerMessage. Ein PlayerMessage kann erstellt werden mithilfe von ExoPlayer.createMessage. Wiedergabeposition, an der das Video ausgeführt werden soll kann mit PlayerMessage.setPosition festgelegt werden. Nachrichten werden auf dem standardmäßig wiedergegeben werden. Dies kann jedoch angepasst werden, PlayerMessage.setLooper PlayerMessage.setDeleteAfterDelivery kann verwendet werden um zu steuern, ob die Nachricht jedes Mal ausgeführt wird, wenn die angegebene Wiedergabeposition erreicht wurde. Dies kann bei der Suche nach und Wiederholungsmodi) oder nur beim ersten Mal. Sobald PlayerMessage konfiguriert, kann er 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();