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 siano dello stesso formato (ad esempio, una playlist può contenere video
H264 e VP9). Possono anche essere di tipi diversi (ad esempio, una playlist può contenere video, immagini e solo stream audio). Puoi utilizzare lo stesso MediaItem più volte all'interno di una playlist.
Modificare la playlist
Puoi modificare dinamicamente una playlist aggiungendo, spostando, rimuovendo o sostituendo elementi multimediali. Puoi farlo sia prima che durante la riproduzione chiamando i metodi 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 brano
MediaItemin riproduzione viene spostato, la riproduzione non viene interrotta e il nuovo brano successivo verrà riprodotto al termine. - Se l'
MediaItemattualmente in riproduzione viene rimosso, il player riprodurrà automaticamente il primo successore rimanente o passerà allo stato di fine se non esiste un successore. - Se l'
MediaItemattualmente in riproduzione viene sostituito, la riproduzione non viene interrotta se nessuna delle proprietà dell'MediaItempertinente per la riproduzione è cambiata. Ad esempio, nella maggior parte dei casi è possibile aggiornare i campiMediaItem.MediaMetadatasenza influire sulla riproduzione.
Eseguire 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 comodità 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 lettore passerà aPlayer.STATE_ENDEDuna volta riprodotto l'ultimo elemento della playlist.Player.REPEAT_MODE_ONE: l'elemento corrente viene ripetuto in un ciclo infinito. Metodi comePlayer.seekToNextMediaItemignoreranno questo 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.
Modalità Shuffle
La modalità casuale può essere attivata o disattivata in qualsiasi momento con
Player.setShuffleModeEnabled. In modalità di riproduzione casuale, il player riproduce la playlist in un ordine casuale precalcolato. 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 ciclo infinito. Quando la modalità di riproduzione casuale è disattivata,
la riproduzione continua 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. Analogamente, Player.seekToNextMediaItem non riprodurrà l'elemento alle
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à
l'ordine casuale esistente il più possibile invariato.
Impostare un ordine di riproduzione casuale personalizzato
Per impostazione predefinita, il player supporta la riproduzione casuale utilizzando DefaultShuffleOrder.
Puoi personalizzarlo fornendo un'implementazione dell'ordine di riproduzione 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);
Identificare gli elementi della playlist
Per identificare gli elementi della playlist, MediaItem.mediaId può essere impostato 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 media per un elemento multimediale, viene utilizzata la rappresentazione di stringa dell'URI.
Associazione dei dati delle 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 è quello di allegare 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 è l'aggiornamento dell'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 la UI sono allegati a ogni elemento multimediale utilizzando tag personalizzati, un'implementazione potrebbe essere simile a questa:
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. Questa callback viene
chiamata anche quando il giocatore non è ancora stato 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 verrà aggiornato e onTimelineChanged verrà chiamato con TIMELINE_CHANGE_REASON_SOURCE_UPDATE. Altri motivi che possono causare un
aggiornamento della cronologia includono:
- Un manifest che diventa disponibile dopo la preparazione di un elemento multimediale adattabile.
- Un manifest aggiornato periodicamente durante la riproduzione di un live streaming.