Playlists

La API de la playlist se define mediante la interfaz Player, que se implementa mediante en todas las implementaciones de ExoPlayer. Las playlists permiten la reproducción secuencial de múltiples elementos multimedia. En el siguiente ejemplo, se muestra cómo iniciar la reproducción de una playlist que contiene dos videos:

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

Las transiciones entre elementos de una playlist son fluidas. No hay ningún requisito de que sean del mismo formato (por ejemplo, está bien que una playlist contenga ambos los videos H264 y VP9). Incluso pueden ser de diferentes tipos (es decir, está bien que un playlist que contenga videos, imágenes y reproducciones de solo audio). Puedes usar la mismo MediaItem varias veces dentro de una playlist.

Cómo modificar la playlist

Puedes modificar una playlist de forma dinámica si agregas, mueves, quitas o reemplazas la lista. elementos multimedia. Esto se puede hacer antes y durante la reproducción llamando al métodos de API de playlists correspondientes:

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

También puedes reemplazar y borrar la playlist completa:

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

El reproductor maneja automáticamente las modificaciones durante la reproducción en el forma:

  • Si se mueve el MediaItem que se está reproduciendo actualmente, la reproducción no se interrumpe y se jugará al nuevo sucesor al finalizar.
  • Si se quita el MediaItem que se está reproduciendo actualmente, el reproductor reproducir el primer sucesor restante, o pasar al estado finalizado si no hay existe tal sucesor.
  • Si se reemplaza el MediaItem que se está reproduciendo actualmente, no se interrumpirá la reproducción. si ninguna de las propiedades en el MediaItem relevante para la reproducción cambió. Por ejemplo, es posible actualizar MediaItem.MediaMetadata. en la mayoría de los casos sin afectar la reproducción.

Consultando la playlist

La playlist se puede consultar mediante Player.getMediaItemCount y Player.getMediaItemAt Se puede consultar el elemento multimedia que se está reproduciendo actualmente llamando a Player.getCurrentMediaItem. También hay otros servicios, métodos como Player.hasNextMediaItem o Player.getNextMediaItemIndex para simplifica la navegación por la playlist.

Modos de repetición

El reproductor admite 3 modos de repetición que se pueden configurar en cualquier momento con Player.setRepeatMode:

  • Player.REPEAT_MODE_OFF: La playlist no se repite, y el reproductor hará lo siguiente: haz la transición a Player.STATE_ENDED una vez que el último elemento de la playlist se haya se reprodujeron.
  • Player.REPEAT_MODE_ONE: El elemento actual se repite en un bucle infinito. Los métodos como Player.seekToNextMediaItem ignorarán esto y buscarán como el siguiente elemento de la lista, que luego se repetirá en un bucle infinito.
  • Player.REPEAT_MODE_ALL: Toda la playlist se repite en un bucle infinito.

Modo aleatorio

Puedes habilitar o inhabilitar el modo Shuffle en cualquier momento con Player.setShuffleModeEnabled En el modo de reproducción aleatoria, el reproductor reproduce en un orden aleatorio precalculado. Todos los elementos se reproducirán una vez y el modo aleatorio también se puede combinar con Player.REPEAT_MODE_ALL para repetir el mismo orden aleatorio en un bucle infinito. Cuando el modo aleatorio está desactivado, la reproducción continúa desde el elemento actual en su posición original en el playlist.

Ten en cuenta que los índices devueltos por métodos como Player.getCurrentMediaItemIndex siempre hace referencia al original, no aleatorio. en el orden personalizado. Del mismo modo, Player.seekToNextMediaItem no reproducirá el elemento en player.getCurrentMediaItemIndex() + 1, pero el siguiente elemento según el orden aleatorio. Si insertas elementos nuevos en la playlist o eliminas elementos, se conservarán el orden aleatorio existente sin cambios lo más posible.

Configura un orden aleatorio personalizado

De forma predeterminada, el reproductor admite la reproducción aleatoria a través de DefaultShuffleOrder. Puedes personalizar esto proporcionando una implementación personalizada de orden aleatorio o Configura un orden personalizado en el constructor 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);

Cómo identificar los elementos de una playlist

Para identificar los elementos de la playlist, se puede configurar MediaItem.mediaId al crear el 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();

Si una app no define explícitamente un ID de contenido multimedia para un elemento multimedia, la cadena se usa una representación del URI.

Asociación de los datos de app con elementos de la playlist

Además de un ID, cada elemento multimedia también se puede configurar con una etiqueta personalizada. que puede ser cualquier objeto proporcionado por la app. Las etiquetas personalizadas se usan para adjuntar metadatos a cada elemento multimedia:

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

Detección de la transición de reproducción a otro elemento multimedia

Cuando la reproducción pasa a otro elemento multimedia o comienza a repetir lo mismo se llama al elemento multimedia Listener.onMediaItemTransition(MediaItem, @MediaItemTransitionReason). Esta devolución de llamada recibe el nuevo contenido multimedia. elemento, junto con un @MediaItemTransitionReason que indica por qué se realizó la transición para determinar si se produjo un error. Un caso de uso común para onMediaItemTransition es actualizar el IU de la app para el nuevo elemento multimedia:

Kotlin

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

Java

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

Si los metadatos necesarios para actualizar la IU se adjuntan a cada elemento multimedia con etiquetas personalizadas, la implementación podría ser de la siguiente manera:

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

Cómo detectar cuándo cambia la playlist

Cuando se agrega, quita o mueve un elemento multimedia, Se llama a Listener.onTimelineChanged(Timeline, @TimelineChangeReason) de inmediato con TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED. Esta devolución de llamada es llamado incluso cuando el jugador aún no está preparado.

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

Cuando información como la duración de un elemento multimedia de la playlist se convierte en disponible, se actualizará Timeline y se llamará a onTimelineChanged con TIMELINE_CHANGE_REASON_SOURCE_UPDATE. Otros motivos que pueden causar una actualización del cronograma incluyen lo siguiente:

  • Un manifiesto que está disponible después de preparar un elemento multimedia adaptable.
  • Un manifiesto que se actualiza periódicamente durante la reproducción de una transmisión en vivo