Interfejs Play API jest definiowany przez interfejs Player
, który jest zaimplementowany przez
we wszystkich implementacjach ExoPlayer
. Playlisty umożliwiają sekwencyjne odtwarzanie wielu
elementów multimedialnych. Ten przykład pokazuje, jak rozpocząć odtwarzanie playlisty
zawierający 2 filmy:
Kotlin
// Build the media items. val firstItem = MediaItem.fromUri(firstVideoUri) val secondItem = MediaItem.fromUri(secondVideoUri) // Add the media items to be played. player.addMediaItem(firstItem) player.addMediaItem(secondItem) // Prepare the player. player.prepare() // Start the playback. player.play()
Java
// Build the media items. MediaItem firstItem = MediaItem.fromUri(firstVideoUri); MediaItem secondItem = MediaItem.fromUri(secondVideoUri); // Add the media items to be played. player.addMediaItem(firstItem); player.addMediaItem(secondItem); // Prepare the player. player.prepare(); // Start the playback. player.play();
Przejście między elementami playlisty jest płynne. Nie ma żadnych wymagań
muszą mieć ten sam format (np. playlista może zawierać zarówno
H264 i VP9). Mogą nawet być różnego rodzaju (tzn. na
playlisty z filmami, obrazami i strumieniami audio). Za pomocą
ten sam MediaItem
wiele razy w ramach jednej playlisty.
Modyfikowanie playlisty
Możesz dynamicznie modyfikować playlistę przez dodawanie, przenoszenie, usuwanie i zastępowanie elementów multimedialnych. Można to zrobić zarówno przed odtworzeniem, jak i w jego trakcie, używając wywołania funkcji odpowiednie metody interfejsu API playlist:
Kotlin
// Adds a media item at position 1 in the playlist. player.addMediaItem(/* index= */ 1, MediaItem.fromUri(thirdUri)) // Moves the third media item from position 2 to the start of the playlist. player.moveMediaItem(/* currentIndex= */ 2, /* newIndex= */ 0) // Removes the first item from the playlist. player.removeMediaItem(/* index= */ 0) // Replace the second item in the playlist. player.replaceMediaItem(/* index= */ 1, MediaItem.fromUri(newUri))
Java
// Adds a media item at position 1 in the playlist. player.addMediaItem(/* index= */ 1, MediaItem.fromUri(thirdUri)); // Moves the third media item from position 2 to the start of the playlist. player.moveMediaItem(/* currentIndex= */ 2, /* newIndex= */ 0); // Removes the first item from the playlist. player.removeMediaItem(/* index= */ 0); // Replace the second item in the playlist. player.replaceMediaItem(/* index= */ 1, MediaItem.fromUri(newUri));
Możesz też zastąpić lub wyczyścić całą playlistę:
Kotlin
// Replaces the playlist with a new one. val newItems: List<MediaItem> = listOf(MediaItem.fromUri(fourthUri), MediaItem.fromUri(fifthUri)) player.setMediaItems(newItems, /* resetPosition= */ true) // Clears the playlist. If prepared, the player transitions to the ended state. player.clearMediaItems()
Java
// Replaces the playlist with a new one. ImmutableList<MediaItem> newItems = ImmutableList.of(MediaItem.fromUri(fourthUri), MediaItem.fromUri(fifthUri)); player.setMediaItems(newItems, /* resetPosition= */ true); // Clears the playlist. If prepared, the player transitions to the ended state. player.clearMediaItems();
Odtwarzacz automatycznie wprowadza modyfikacje podczas odtwarzania w odpowiednim sposób:
- Jeśli obecnie odtwarzany element
MediaItem
zostanie przeniesiony, odtwarzanie nie zostanie przerwane. jego nowa następca zostanie odtworzona po zakończeniu. - Jeśli obecnie odtwarzana treść (
MediaItem
) zostanie usunięta, odtwarzacz automatycznie odtwórz pierwszy pozostały następcę lub przejdź do stanu zakończenia, jeśli nie że istnieje taki następca. - Jeśli zastąpisz obecnie odtwarzany
MediaItem
, odtwarzanie nie zostanie przerwane jeśli żadna z właściwości obiektuMediaItem
odpowiednich do odtworzenia została zmieniona. Można na przykład zaktualizowaćMediaItem.MediaMetadata
pola w większości przypadków bez wpływu na odtwarzanie.
Wysyłanie zapytania dotyczącego playlisty
Zapytania dotyczące playlisty można wysyłać za pomocą poleceń Player.getMediaItemCount
i
Player.getMediaItemAt
Można wysłać zapytanie dotyczące aktualnie odtwarzanego elementu multimedialnego
dzwoniąc pod numer Player.getCurrentMediaItem
. Dostępne są też inne udogodnienia.
takie jak Player.hasNextMediaItem
lub Player.getNextMediaItemIndex
, aby
aby ułatwić nawigację po playliście.
Tryby powtarzania
Odtwarzacz obsługuje 3 tryby powtarzania, które można ustawić w dowolnym momencie,
Player.setRepeatMode
:
Player.REPEAT_MODE_OFF
: playlista się nie powtarza, a odtwarzacz przejście doPlayer.STATE_ENDED
, gdy ostatni element na playliście co gra.Player.REPEAT_MODE_ONE
: bieżący element jest powtarzany w nieskończonej pętli. Metody takie jakPlayer.seekToNextMediaItem
zignorują go i przewiną do kolejny element na liście. Zostanie on powtórzony w nieskończonej pętli.Player.REPEAT_MODE_ALL
: cała playlista jest powtarzana w niekończącej się pętli.
Tryb losowania
Tryb losowego można w każdej chwili włączyć lub wyłączyć za pomocą
Player.setShuffleModeEnabled
W trybie losowym odtwarzacz odtwarza
w wstępnie określonej, losowej kolejności. Wszystkie elementy zostaną odtworzone raz
tryb losowania można też połączyć z funkcją Player.REPEAT_MODE_ALL
, aby powtarzać
w tej samej losowej kolejności
w nieskończonej pętli. Gdy tryb odtwarzania losowego jest wyłączony,
odtwarzanie od bieżącego elementu w oryginalnym miejscu
na playliście.
Zwróć uwagę, że indeksy zwracane przez metody takie jak
Player.getCurrentMediaItemIndex
zawsze odnosi się do oryginału, bez odtwarzań losowo
zamówienie. Podobnie Player.seekToNextMediaItem
nie odtworzy elementu pod adresem
player.getCurrentMediaItemIndex() + 1
, ale kolejny element zgodnie z
kolejność losowa. Wstawienie nowych elementów na playliście lub ich usunięcie spowoduje zachowanie
istniejące losowe kolejność nie uległo zmianie.
Ustawianie niestandardowej kolejności losowej
Domyślnie odtwarzacz obsługuje tasowanie z użyciem funkcji DefaultShuffleOrder
.
Można to dostosować, wprowadzając niestandardową implementację kolejności tasowania.
ustaw niestandardową kolejność w konstruktorze DefaultShuffleOrder
:
Kotlin
// Set a custom shuffle order for the 5 items currently in the playlist: exoPlayer.setShuffleOrder(DefaultShuffleOrder(intArrayOf(3, 1, 0, 4, 2), randomSeed)) // Enable shuffle mode. exoPlayer.shuffleModeEnabled = true
Java
// Set a custom shuffle order for the 5 items currently in the playlist: exoPlayer.setShuffleOrder(new DefaultShuffleOrder(new int[] {3, 1, 0, 4, 2}, randomSeed)); // Enable shuffle mode. exoPlayer.setShuffleModeEnabled(/* shuffleModeEnabled= */ true);
Identyfikowanie elementów playlisty
Aby zidentyfikować elementy playlisty, można ustawić parametr MediaItem.mediaId
podczas tworzenia
element:
Kotlin
// Build a media item with a media ID. val mediaItem = MediaItem.Builder().setUri(uri).setMediaId(mediaId).build()
Java
// Build a media item with a media ID. MediaItem mediaItem = new MediaItem.Builder().setUri(uri).setMediaId(mediaId).build();
Jeśli aplikacja nie ma jawnie zdefiniowanego identyfikatora multimediów dla elementu multimedialnego, ciąg znaków identyfikatora URI.
Powiązanie danych aplikacji z elementami playlisty
Oprócz identyfikatora, każdego elementu multimedialnego możesz też skonfigurować tag niestandardowy, który może być dowolnym obiektem dostarczonym przez aplikację. Jednym z zastosowań tagów niestandardowych jest dołączanie do każdego elementu multimedialnego:
Kotlin
// Build a media item with a custom tag. val mediaItem = MediaItem.Builder().setUri(uri).setTag(metadata).build()
Java
// Build a media item with a custom tag. MediaItem mediaItem = new MediaItem.Builder().setUri(uri).setTag(metadata).build();
Wykrywanie przechodzenia odtwarzania do innego elementu multimedialnego
Gdy odtwarzanie przechodzi do innego elementu multimedialnego lub rozpoczyna powtarzanie tego samego
element multimedialny, wywoływana jest funkcja Listener.onMediaItemTransition(MediaItem,
@MediaItemTransitionReason)
. To wywołanie zwrotne odbiera nowe multimedia
element wraz z @MediaItemTransitionReason
wskazującym przyczynę przeniesienia
. Typowy przypadek użycia onMediaItemTransition
to aktualizowanie
interfejsu aplikacji nowego elementu multimedialnego:
Kotlin
override fun onMediaItemTransition( mediaItem: MediaItem?, @MediaItemTransitionReason reason: Int, ) { updateUiForPlayingMediaItem(mediaItem) }
Java
@Override public void onMediaItemTransition( @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) { updateUiForPlayingMediaItem(mediaItem); }
Jeśli metadane wymagane do aktualizacji interfejsu użytkownika są dołączone do każdego elementu multimedialnego za pomocą atrybutu , implementacja może wyglądać tak:
Kotlin
override fun onMediaItemTransition( mediaItem: MediaItem?, @MediaItemTransitionReason reason: Int, ) { var metadata: CustomMetadata? = null mediaItem?.localConfiguration?.let { localConfiguration -> metadata = localConfiguration.tag as? CustomMetadata } updateUiForPlayingMediaItem(metadata) }
Java
@Override public void onMediaItemTransition( @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) { @Nullable CustomMetadata metadata = null; if (mediaItem != null && mediaItem.localConfiguration != null) { metadata = (CustomMetadata) mediaItem.localConfiguration.tag; } updateUiForPlayingMediaItem(metadata); }
Wykrywanie zmian na playliście
Po dodaniu, usunięciu lub przeniesieniu elementu multimedialnego
Funkcja Listener.onTimelineChanged(Timeline, @TimelineChangeReason)
jest wywoływana
natychmiast w usłudze TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED
. To wywołanie zwrotne
nawet jeśli gracz nie był jeszcze gotowy.
Kotlin
override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) { if (reason == Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED) { // Update the UI according to the modified playlist (add, move or remove). updateUiForPlaylist(timeline) } }
Java
@Override public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) { if (reason == TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED) { // Update the UI according to the modified playlist (add, move or remove). updateUiForPlaylist(timeline); } }
Gdy informacje, takie jak czas trwania elementu multimedialnego na playliście, stają się
dostępny, interfejs Timeline
zostanie zaktualizowany, a aplikacja onTimelineChanged
otrzyma nazwę
dzięki funkcji TIMELINE_CHANGE_REASON_SOURCE_UPDATE
. Inne powody, dla których
aktualizacje harmonogramu obejmują:
- Plik manifestu staje się dostępny po przygotowaniu adaptacyjnego elementu multimedialnego.
- Plik manifestu jest okresowo aktualizowany podczas odtwarzania transmisji na żywo.