L'API Playlist viene definita dall'interfaccia Player
, implementata da tutte le implementazioni ExoPlayer
. Le playlist consentono la riproduzione sequenziale di più contenuti 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 è necessario che siano dello stesso formato (ad esempio, è consentito che una playlist contenga sia video H264 che VP9). Possono anche essere di tipi diversi (ovvero, non è un problema se una playlist contiene video, immagini e stream solo audio). Puoi utilizzare lo stesso MediaItem
più volte all'interno di una playlist.
Modificare la playlist
Puoi modificare in modo dinamico una playlist aggiungendo, spostando, rimuovendo o sostituendo gli elementi multimediali. Questa operazione può essere eseguita prima e 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 l'eliminazione 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 il
MediaItem
attualmente in riproduzione viene spostato, la riproduzione non viene interrotta e il suo nuovo successore verrà riprodotto al termine. - Se l'elemento
MediaItem
in riproduzione viene rimosso, il player riprodurrà automaticamente il primo successore rimanente o passerà allo stato "Terminata" se non esiste un successore di questo tipo. - Se il
MediaItem
attualmente in riproduzione viene sostituito, la riproduzione non viene interrotta se nessuna delle proprietà delMediaItem
pertinenti per la riproduzione è stata modificata. 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 di navigazione comodi, 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
dopo la riproduzione dell'ultimo elemento della playlist.Player.REPEAT_MODE_ONE
: l'elemento corrente viene ripetuto in un loop infinito. Metodi comePlayer.seekToNextMediaItem
lo ignoreranno e cercheranno 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.
Riproduzione casuale
La modalità Shuffle può essere attivata o disattivata in qualsiasi momento con
Player.setShuffleModeEnabled
. In modalità di riproduzione casuale, il player riprodurrà la playlist in un ordine precalcolato e casuale. Tutti gli elementi verranno riprodotti una volta e la modalità di riproduzione casuale può essere combinata anche con Player.REPEAT_MODE_ALL
per ripetere lo stesso ordine casuale in un loop infinito. Quando la modalità di riproduzione casuale è disattivata, la riproduzione riprende dall'elemento corrente nella sua posizione originale nella playlist.
Tieni presente che gli indici restituiti da metodi come
Player.getCurrentMediaItemIndex
fanno sempre riferimento all'ordine originale, non mischiato. Allo stesso modo, Player.seekToNextMediaItem
non riprodurrà l'elemento al minuto player.getCurrentMediaItemIndex() + 1
, ma l'elemento successivo in base all'ordine di riproduzione casuale. L'inserimento di nuovi elementi nella playlist o la rimozione di elementi manterrà immutato l'ordine in riproduzione casuale esistente, per quanto possibile.
Impostazione di un ordine casuale personalizzato
Per impostazione predefinita, il player supporta la riproduzione casuale mediante DefaultShuffleOrder
.
Questo può essere personalizzato fornendo un'implementazione dell'ordine casuale personalizzato 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 lo sviluppo 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 media per un elemento multimediale, viene utilizzata la rappresentazione di 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 utilizzo dei tag personalizzati è l'associazione di metadati a 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 momento in cui la riproduzione passa a un altro elemento multimediale
Quando la riproduzione passa a un altro elemento multimediale o inizia a ripetere lo stesso elemento multimediale, viene chiamato 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 associati a ogni elemento multimediale utilizzando tag personalizzati, un'implementazione potrebbe essere simile alla seguente:
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 delle modifiche alla 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 chiamato anche quando il player 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 diventano disponibili informazioni come la durata di un elemento multimediale nella playlist, Timeline
viene aggiornato e onTimelineChanged
viene chiamato con TIMELINE_CHANGE_REASON_SOURCE_UPDATE
. Altri motivi che possono causare un
aggiornamento della sequenza temporale includono:
- Un manifest diventa disponibile dopo la preparazione di un elemento multimediale adattivo.
- Un file manifest aggiornato periodicamente durante la riproduzione di un live streaming.