Nasłuchiwanie zdarzeń odtwarzania
Zdarzenia, takie jak zmiany stanu i błędy odtwarzania, są zgłaszane do zarejestrowanych
Player.Listener
instancji. Aby zarejestrować detektor i otrzymywać takie
wydarzenia:
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);
Metoda Player.Listener
ma puste metody domyślne, więc musisz tylko zaimplementować
z metod, które Cię interesują. Pełny opis języka Javadoc znajdziesz
metod i czas ich wywoływania. Najważniejsze z nich są
omówiono szczegółowo poniżej.
Detektory mogą zdecydować, czy stosować wywołania zwrotne poszczególnych zdarzeń, czy
ogólne wywołanie zwrotne onEvents
, które jest wywoływane po wystąpieniu co najmniej jednego zdarzenia
razem. Aby dowiedzieć się, które z nich znajdziesz w artykule Individual callbacks vs onEvents
,
jest preferowane w różnych przypadkach użycia.
Zmiany stanu odtwarzania
Zmiany stanu odtwarzacza można odbierać po wdrożeniu
onPlaybackStateChanged(@State int state)
w zarejestrowanym
Player.Listener
Odtwarzacz może mieć jeden z 4 stanów odtwarzania:
Player.STATE_IDLE
: stan początkowy, w którym odtwarzacz jest zatrzymuje odtwarzanie, a odtwarzanie się nie powiodło. Odtwarzacz będzie miał tylko ograniczone zasoby w tym stanie.Player.STATE_BUFFERING
: gracz nie może od razu rozpocząć odtwarzania ze swojego bieżącej pozycji. Dzieje się tak głównie dlatego, że trzeba wczytać więcej danych.Player.STATE_READY
: gracz może od razu rozpocząć odtwarzanie od bieżącego pozycji.Player.STATE_ENDED
: odtwarzacz zakończył odtwarzanie wszystkich multimediów.
Oprócz tych stanów gracz ma również flagę playWhenReady
, która wskazuje,
od intencji użytkownika. Zmiany w tej flagi można otrzymywać po wdrożeniu
onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason)
Odtwarzacz jest odtwarzany (czyli jego pozycja przesuwa się w górę, a multimedia są przedstawiane użytkownikowi), gdy są spełnione wszystkie 3 następujące warunki:
- Odtwarzacz jest w stanie
Player.STATE_READY
- Wydarzenie
playWhenReady
zacznie siętrue
- Odtwarzanie nie zostało wstrzymane z powodu zwróconego przez
Player.getPlaybackSuppressionReason
Zamiast sprawdzać te właściwości pojedynczo, Player.isPlaying
. Zmiany tego stanu można otrzymywać po wdrożeniu
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. } } });
Błędy odtwarzania
Błędy, które powodują niepowodzenie odtwarzania, mogą być zgłaszane przez
onPlayerError(PlaybackException error)
w zarejestrowanym
Player.Listener
W przypadku niepowodzenia wywoływana jest metoda
bezpośrednio przed zmianą stanu odtwarzania na Player.STATE_IDLE
.
Aby spróbować ponownie odtworzyć nieudane lub zatrzymane odtwarzanie, wywołaj ExoPlayer.prepare
.
Pamiętaj, że niektóre implementacje Player
przekazują wystąpienia podklas
PlaybackException
w celu podania dodatkowych informacji o błędzie. Dla:
na przykład ExoPlayer
przekazuje ExoPlaybackException
, w którym jest type
,
rendererIndex
i innych pól dotyczących odtwarzacza ExoPlayer.
W przykładzie poniżej pokazujemy, jak wykryć, że odtwarzanie nie powiodło się z powodu błędu Problem z siecią 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. } } } });
Przejścia playlisty
Za każdym razem, gdy odtwarzacz zmienia element multimedialny na playliście.
Połączenie z numerem onMediaItemTransition(MediaItem mediaItem,
@MediaItemTransitionReason int reason)
po zarejestrowaniu
Player.Listener
obiektów. Przyczyna wskazuje, czy było to działanie automatyczne
przejście, przewijanie (np. po wywołaniu funkcji player.next()
), powtórzenie
tego samego elementu lub spowodowane zmianą playlisty (np. jeśli obecnie
odtwarzany element zostanie usunięty).
Metadane
Metadane zwrócone z serwera player.getCurrentMediaMetadata()
mogą się zmienić ze względu na wiele
powodów: przejścia na playlistach, aktualizacji metadanych In-Stream lub aktualizacji
obecnie MediaItem
w trakcie odtwarzania.
Jeśli interesuje Cię zmiana metadanych, na przykład jeśli chcesz zaktualizować interfejs użytkownika pokazujący
bieżący tytuł, możesz posłuchać wykonawcy onMediaMetadataChanged
.
Szukam
Wywołanie metod Player.seekTo
powoduje serię wywołań zwrotnych do zarejestrowanych.
Player.Listener
instancja:
onPositionDiscontinuity
z:reason=DISCONTINUITY_REASON_SEEK
. To jest bezpośredni wynik wywołania funkcjiPlayer.seekTo
. Wywołanie zwrotne maPositionInfo
pola pozycji przed przewijaniem i po nim.onPlaybackStateChanged
z natychmiastową zmianą stanu związaną z wyszukiwaniem. Pamiętaj, że takie zmiany mogą nie zostać wprowadzone.
Pojedyncze wywołania zwrotne a onEvents
Słuchacze mogą zdecydować, czy stosować poszczególne wywołania zwrotne, takie jak
onIsPlayingChanged(boolean isPlaying)
i reklamie ogólnej
onEvents(Player player, Events events)
oddzwonienie. Ogólne wywołanie zwrotne zapewnia
dostęp do obiektu Player
i określa zbiór events
, które wystąpiły
razem. To wywołanie zwrotne jest zawsze wywoływane po wszystkich wywołaniach zwrotnych odpowiadających argumentowi
poszczególne zdarzenia.
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); } }
Poszczególne wydarzenia powinny być preferowane w tych przypadkach:
- Słuchacz jest zainteresowany przyczynami zmian. Na przykład parametr
przyczyny podane dla funkcji
onPlayWhenReadyChanged
lubonMediaItemTransition
. - Detektor działa tylko na nowych wartościach podanych za pomocą parametrów wywołania zwrotnego lub uruchamia inny element, który nie jest zależny od parametrów wywołania zwrotnego.
- Implementacja funkcji detektora preferuje jednoznaczne, czytelne wskazanie wywołał zdarzenie w nazwie metody.
- Odbiornik zgłasza się do systemu analitycznego, który musi wiedzieć o wszystkim, poszczególnych zdarzeń i zmian stanu.
Ogólna kategoria onEvents(Player player, Events events)
powinna być preferowana w
w następujących przypadkach:
- Detektor chce aktywować tę samą logikę w przypadku wielu zdarzeń. Dla:
na przykład do zaktualizowania UI zarówno w
onPlaybackStateChanged
, jak i w przeglądarceonPlayWhenReadyChanged
- Detektor potrzebuje dostępu do obiektu
Player
, aby aktywować kolejne zdarzenia, np. przewijanie po przejściu elementu multimedialnego. - Detektor zamierza używać wielu zgłaszanych wartości stanu
za pomocą osobnych wywołań zwrotnych lub w połączeniu z metodą getter
Player
. Na przykład użycie parametruPlayer.getCurrentWindowIndex()
z parametremTimeline
podano wonTimelineChanged
jest bezpieczne tylko zonEvents
oddzwonienie. - Detektor chce sprawdzić, czy zdarzenia wystąpiły logicznie razem. Dla:
przykład, od
onPlaybackStateChanged
doSTATE_BUFFERING
ze względu na element multimedialny przejścia.
W niektórych przypadkach detektory mogą być zmuszone do łączenia poszczególnych wywołań zwrotnych z funkcją
ogólne wywołanie zwrotne onEvents
, na przykład w celu rejestrowania powodów zmiany elementu multimedialnego
za pomocą onMediaItemTransition
, ale działają tylko wtedy, gdy można użyć wszystkich zmian stanu
razem w usłudze onEvents
.
Jak korzystać z aplikacji AnalyticsListener
Jeśli używasz funkcji ExoPlayer
, w odtwarzaczu można zarejestrować element AnalyticsListener
, dzwoniąc pod numer addAnalyticsListener
. Implementacje „AnalyticsListener
” mogą
nasłuchiwanie szczegółowych zdarzeń, które mogą być przydatne do analiz i logowania.
w celach informacyjnych. Więcej informacji znajdziesz na stronie statystyk.
Jak korzystać z aplikacji EventLogger
EventLogger
to AnalyticsListener
dostarczony bezpośrednio przez bibliotekę dla
w celach związanych z logowaniem danych. Dodaj EventLogger
do ExoPlayer
, aby włączyć przydatne funkcje
dodatkowe logowanie w jednym wierszu:
Kotlin
player.addAnalyticsListener(EventLogger())
Java
player.addAnalyticsListener(new EventLogger());
Więcej informacji znajdziesz na stronie rejestrowania debugowania.
Uruchamianie zdarzeń w określonych pozycjach odtwarzania
Niektóre przypadki użycia wymagają uruchamiania zdarzeń w określonych pozycjach odtwarzania. To jest
obsługiwane przez PlayerMessage
. PlayerMessage
można utworzyć za pomocą:
ExoPlayer.createMessage
Pozycja odtwarzania, w której film ma zostać uruchomiony
można ustawić za pomocą funkcji PlayerMessage.setPosition
. Wiadomości są wykonywane na
domyślnie, ale można to dostosować,
PlayerMessage.setLooper
PlayerMessage.setDeleteAfterDelivery
można użyć
aby kontrolować, czy komunikat ma być wykonywany za każdym razem, gdy określony
pozycja odtwarzania (może się to zdarzać wiele razy z powodu przewijania
i powtórzeń) lub tylko za pierwszym razem. Gdy PlayerMessage
będzie
skonfigurowany, można zaplanować go za pomocą funkcji 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();