Playlist

L'API playlist viene definita dall'interfaccia Player, implementata da tutte le ExoPlayer implementazioni. Le playlist consentono la riproduzione sequenziale elementi multimediali. L'esempio seguente mostra come avviare la riproduzione di una playlist contenente due video:

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();

Le transizioni tra gli elementi di una playlist avvengono in maniera fluida. Non c'è alcun requisito che abbiano lo stesso formato (ad esempio, è possibile che una playlist contenga entrambi video H264 e VP9). Possono anche essere di tipo diverso (vale a dire, va bene per una contenente video, immagini e stream solo audio). Puoi utilizzare lo lo stesso MediaItem più volte in una playlist.

Modifica della playlist

Puoi modificare dinamicamente una playlist aggiungendo, spostando, rimuovendo o sostituendo elementi multimediali. Questa operazione può essere eseguita prima e durante la riproduzione chiamando il metodo metodi dell'API playlist corrispondenti:

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));

È supportata anche la sostituzione e la cancellazione dell'intera 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();

Il player gestisce automaticamente le modifiche durante la riproduzione nel modo modo:

  • Se sposti l'elemento MediaItem attualmente in riproduzione, la riproduzione non viene interrotta e il nuovo successore verrà riprodotto al completamento.
  • Se viene rimosso il brano MediaItem attualmente in riproduzione, il player verrà automaticamente riprodurre il primo successore rimasto o passare allo stato Terminato se non tale successore esiste.
  • Se viene sostituito il MediaItem attualmente in riproduzione, la riproduzione non si interrompe se nessuna delle proprietà in MediaItem è pertinente per la riproduzione è cambiato. Ad esempio, è possibile aggiornare MediaItem.MediaMetadata campi nella maggior parte dei casi senza influire sulla riproduzione.

Esecuzione di query sulla playlist

È possibile eseguire query sulla playlist utilizzando Player.getMediaItemCount e Player.getMediaItemAt. È possibile eseguire query sull'elemento multimediale attualmente in riproduzione chiamando il numero Player.getCurrentMediaItem. Ci sono anche altre comodità come Player.hasNextMediaItem o Player.getNextMediaItemIndex per semplificare la navigazione all'interno della playlist.

Modalità di ripetizione

Il player supporta 3 modalità di ripetizione che possono essere impostate in qualsiasi momento con Player.setRepeatMode:

  • Player.REPEAT_MODE_OFF: la playlist non viene ripetuta e il player lo passa a Player.STATE_ENDED una volta che l'ultimo elemento della playlist è è stato eseguito.
  • Player.REPEAT_MODE_ONE: l'elemento corrente viene ripetuto in un loop infinito. Metodi come Player.seekToNextMediaItem ignorano questo problema e cercheranno al successivo elemento dell'elenco, che sarà poi ripetuto in un loop infinito.
  • Player.REPEAT_MODE_ALL: l'intera playlist viene ripetuta in un loop infinito.

Modalità casuale

La modalità di riproduzione casuale può essere attivata o disattivata in qualsiasi momento con Player.setShuffleModeEnabled. In modalità casuale, il giocatore riprodurrà i playlist in ordine casuale precalcolato. Tutti gli elementi verranno riprodotti una volta e la modalità casuale può anche essere combinata con Player.REPEAT_MODE_ALL per la ripetizione lo stesso ordine randomizzato in un loop infinito. Quando la modalità casuale è disattivata, la riproduzione continua dall'elemento corrente nella sua posizione originale nella playlist.

Nota che gli indici vengono restituiti da metodi come Player.getCurrentMediaItemIndex fa sempre riferimento all'originale, in ordine casuale ordine. In modo simile, Player.seekToNextMediaItem non riprodurrà l'elemento al player.getCurrentMediaItemIndex() + 1, ma l'elemento successivo secondo la in ordine casuale. L'inserimento di nuovi elementi nella playlist o la rimozione di elementi mantengono l'ordine casuale esistente non modificato, per quanto possibile.

Impostazione di un ordine casuale personalizzato

Per impostazione predefinita, il player supporta la riproduzione casuale mediante DefaultShuffleOrder. È possibile personalizzarli fornendo un'implementazione personalizzata degli ordini di shuffling oppure Impostando un ordine personalizzato nel costruttore 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);

Identificazione degli elementi della playlist

Per identificare gli elementi della playlist, puoi impostare MediaItem.mediaId durante la creazione della elemento:

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();

Se un'app non definisce esplicitamente un ID elemento multimediale per un elemento multimediale, la stringa dell'URI.

Associare i dati dell'app agli elementi della playlist

Oltre a un ID, ogni elemento multimediale può essere configurato anche con un tag personalizzato, che può essere qualsiasi oggetto fornito dall'app. Un uso dei tag personalizzati è l'aggiunta metadati per ogni elemento multimediale:

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();

Rilevamento del passaggio della riproduzione a un altro elemento multimediale

Quando la riproduzione passa a un altro elemento multimediale o inizia a ripetere lo stesso elemento elemento multimediale, viene chiamato Listener.onMediaItemTransition(MediaItem, @MediaItemTransitionReason). Questo callback riceve i nuovi contenuti multimediali insieme a un @MediaItemTransitionReason che indica il motivo della transizione si è verificato un errore. Un caso d'uso comune di onMediaItemTransition è l'aggiornamento UI dell'app per il nuovo elemento multimediale:

Kotlin

override fun onMediaItemTransition(
  mediaItem: MediaItem?,
  @MediaItemTransitionReason reason: Int,
) {
  updateUiForPlayingMediaItem(mediaItem)
}

Java

@Override
public void onMediaItemTransition(
    @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) {
  updateUiForPlayingMediaItem(mediaItem);
}

Se i metadati necessari per aggiornare l'interfaccia utente sono allegati a ogni elemento multimediale utilizzando tag personalizzati, l'implementazione potrebbe avere il seguente aspetto:

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);
}

Rilevamento del cambio di playlist in corso...

Quando un elemento multimediale viene aggiunto, rimosso o spostato, Il nome di Listener.onTimelineChanged(Timeline, @TimelineChangeReason) è immediatamente con TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED. Il callback è chiamato anche quando il giocatore non è stato ancora preparato.

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);
  }
}

Quando informazioni come la durata di un elemento multimediale nella playlist diventano disponibile, Timeline verrà aggiornato e onTimelineChanged si chiamerà con TIMELINE_CHANGE_REASON_SOURCE_UPDATE. Altri motivi che possono causare un l'aggiornamento della sequenza temporale include:

  • Un file manifest che diventa disponibile dopo la preparazione di un elemento multimediale adattivo.
  • Un file manifest che viene aggiornato periodicamente durante la riproduzione di un live streaming.