L'API playlist è definita dall'interfaccia Player
, che viene implementata da tutte le implementazioni ExoPlayer
. Le playlist consentono la riproduzione
sequenziale di più 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 sono fluide. Non è necessario che abbiano lo stesso formato (ad esempio, le playlist possono contenere sia video H264 sia video VP9). Possono anche essere di tipi diversi (in altre parole, una playlist deve contenere sia stream video sia stream solo audio). Puoi usare lo stesso MediaItem
più volte all'interno di una playlist.
Modifica della playlist
Puoi modificare una playlist in modo dinamico aggiungendo, spostando, rimuovendo o sostituendo gli elementi multimediali. Questa operazione può essere eseguita sia prima che durante la riproduzione chiamando i 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));
Sono supportate 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 corretto:
- Se viene spostato l'oggetto
MediaItem
attualmente in riproduzione, la riproduzione non viene interrotta e il nuovo successore verrà riprodotto al termine. - Se l'elemento
MediaItem
attualmente in riproduzione viene rimosso, il giocatore giocherà automaticamente il primo successore rimanente o passerà allo stato "Terminato" se non esiste. - Se il valore
MediaItem
attualmente in riproduzione viene sostituito, la riproduzione non viene interrotta se nessuna delle proprietà inMediaItem
pertinente alla riproduzione è cambiata. Ad esempio, nella maggior parte dei casi è possibile aggiornare i campiMediaItem.MediaMetadata
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 Player.getCurrentMediaItem
. Esistono anche altri metodi
come Player.hasNextMediaItem
o Player.getNextMediaItemIndex
per
semplificare la navigazione nella playlist.
Modalità di ripetizione
Il player supporta tre 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 passerà aPlayer.STATE_ENDED
una volta riprodotto l'ultimo elemento della playlist.Player.REPEAT_MODE_ONE
: l'elemento corrente viene ripetuto in un ciclo infinito. Metodi comePlayer.seekToNextMediaItem
lo ignorano e cercano l'elemento successivo nell'elenco, che verrà poi ripetuto in un ciclo infinito.Player.REPEAT_MODE_ALL
: l'intera playlist viene ripetuta in un loop infinito.
Modalità casuale
La modalità casuale può essere attivata o disattivata in qualsiasi momento con Player.setShuffleModeEnabled
. In modalità di riproduzione casuale, il player riprodurrà
la playlist in ordine casuale precalcolato. Tutti gli elementi verranno riprodotti una volta e
la modalità di riproduzione casuale può essere anche combinata con Player.REPEAT_MODE_ALL
per ripetere
lo stesso ordine casuale in un loop infinito. Quando la modalità di riproduzione casuale non è attiva,
la riproduzione continua dall'elemento corrente nella posizione originale nella
playlist.
Tieni presente che gli indici restituiti da metodi come Player.getCurrentMediaItemIndex
fanno sempre riferimento all'ordine originale non casuale. Allo stesso modo, Player.seekToNextMediaItem
non riprodurrà l'elemento al minuto player.getCurrentMediaItemIndex() + 1
, ma l'elemento successivo in base all'ordine casuale. L'inserimento di nuovi elementi nella playlist o la loro rimozione manterrà invariato l'ordine casuale esistente.
Impostazione di un ordine casuale personalizzato
Per impostazione predefinita, il player supporta la riproduzione casuale tramite DefaultShuffleOrder
.
Questa opzione può essere personalizzata fornendo un'implementazione personalizzata di ordine casuale o 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
dell'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 multimediale per un elemento multimediale, viene utilizzata la rappresentazione stringa dell'URI.
Associazione dei dati dell'app a 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. I tag personalizzati possono essere utilizzati per collegare i metadati a ciascun 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 delle transizioni della riproduzione a un altro elemento multimediale
Quando la riproduzione passa a un altro elemento multimediale o inizia a ripetere lo stesso elemento multimediale, viene richiamato Listener.onMediaItemTransition(MediaItem,
@MediaItemTransitionReason)
. Questo callback riceve il nuovo elemento multimediale, insieme a un @MediaItemTransitionReason
che indica il motivo della transizione. Un caso d'uso comune per onMediaItemTransition
è aggiornare l'interfaccia utente 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 essere simile a:
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
Quando un elemento multimediale viene aggiunto, rimosso o spostato, Listener.onTimelineChanged(Timeline, @TimelineChangeReason)
viene chiamato immediatamente con TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED
. Questo callback viene richiamato anche quando il player non è ancora pronto.
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
disponibili, Timeline
viene aggiornato e onTimelineChanged
viene chiamato
con TIMELINE_CHANGE_REASON_SOURCE_UPDATE
. Altri motivi che possono causare un aggiornamento della cronologia sono:
- 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.