w playlistach.

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 obiektu MediaItem 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 do Player.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 jak Player.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 użytkownika 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.