Playlists

A API da playlist é definida pela interface Player, que é implementada por todas as implementações de ExoPlayer. As listas de reprodução permitem a reprodução sequencial de vários itens de mídia. O exemplo abaixo mostra como iniciar a reprodução de uma playlist. com dois vídeos:

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

As transições entre os itens de uma playlist são perfeitas. Não há requisitos que são do mesmo formato (por exemplo, uma playlist que contenha ambos vídeos H264 e VP9). Elas podem até ser de diferentes tipos (ou seja, é bom que um para conter vídeos, imagens e streams somente de áudio). Você pode usar o o mesmo MediaItem várias vezes em uma playlist.

Modificar a playlist

Você pode modificar dinamicamente uma lista de reprodução adicionando, movendo, removendo ou substituindo itens de mídia. Isso pode ser feito antes e durante a reprodução chamando métodos correspondentes da API de playlist:

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

Também é possível substituir e limpar toda a 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();

O player processa automaticamente as modificações durante a reprodução no formato maneira:

  • Se o MediaItem em reprodução for movido, a reprodução não será interrompida e seu novo sucessor será jogado após a conclusão.
  • Se o MediaItem em reprodução for removido, o player será automaticamente reproduzir o primeiro sucessor restante ou passar para o estado finalizado se não tal sucessor existe.
  • Se o MediaItem em reprodução for substituído, a reprodução não será interrompida se nenhuma das propriedades no MediaItem for relevante para a reprodução mudou. Por exemplo, é possível atualizar MediaItem.MediaMetadata campos na maioria dos casos sem afetar a reprodução.

Consultar a playlist

A playlist pode ser consultada usando Player.getMediaItemCount e Player.getMediaItemAt. O item de mídia em reprodução pode ser consultado chame Player.getCurrentMediaItem. Há também outras conveniências métodos, como Player.hasNextMediaItem ou Player.getNextMediaItemIndex, para simplificar a navegação na lista de reprodução.

Modos de repetição

O player oferece suporte a três modos de repetição que podem ser definidos a qualquer momento com Player.setRepeatMode:

  • Player.REPEAT_MODE_OFF: a playlist não é repetida, e o player fazer a transição para Player.STATE_ENDED quando o último item da playlist for tocado.
  • Player.REPEAT_MODE_ONE: o item atual é repetido em um loop infinito. Métodos como Player.seekToNextMediaItem ignorarão isso e buscarão a próximo item da lista, que será repetido em um loop infinito.
  • Player.REPEAT_MODE_ALL: a playlist inteira é repetida em um loop infinito.

Modo de ordem aleatória

O modo de ordem aleatória pode ser ativado ou desativado a qualquer momento com Player.setShuffleModeEnabled: No modo aleatório, o player toca em uma ordem aleatória pré-computada. Todos os itens serão reproduzidos uma vez e o modo de ordem aleatória também pode ser combinado com Player.REPEAT_MODE_ALL para repetir a mesma ordem aleatória em um loop infinito. Quando o modo de ordem aleatória está desativado, a reprodução continua do item atual na posição original na lista de reprodução.

Os índices retornados por métodos como Player.getCurrentMediaItemIndex sempre se referem ao original, sem ordem aleatória ordem. Da mesma forma, Player.seekToNextMediaItem não vai abrir o item em player.getCurrentMediaItemIndex() + 1, mas o próximo item de acordo com ordem aleatória. Inserir ou remover novos itens na playlist não vai mudar a ordem embaralhada atual permanece inalterada o máximo possível.

Como definir uma ordem de embaralhamento personalizada

Por padrão, o player é compatível com o embaralhamento usando a DefaultShuffleOrder. Isso pode ser personalizado com uma implementação personalizada de ordem de embaralhamento ou definindo uma ordem personalizada no construtor 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);

Identificar itens da playlist

Para identificar itens da playlist, MediaItem.mediaId pode ser definido ao criar o item:

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 um app não definir explicitamente um ID de mídia para um item de mídia, a string do URI é usada.

Como associar dados do aplicativo a itens da playlist

Além de um ID, cada item de mídia também pode ser configurado com uma tag personalizada, que pode ser qualquer objeto fornecido pelo app. Um uso das tags personalizadas é anexar metadados a cada item de mídia:

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

Como detectar quando a reprodução faz a transição para outro item de mídia

Quando a reprodução faz a transição para outro item de mídia ou começa a repetir o mesmo item de mídia, Listener.onMediaItemTransition(MediaItem, @MediaItemTransitionReason) é chamado. Esse callback recebe a nova mídia item, junto com um @MediaItemTransitionReason indicando por que a transição o incidente. Um caso de uso comum de onMediaItemTransition é atualizar o interface do app para o novo item de mídia:

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 os metadados exigidos para atualizar a interface forem anexados a cada item de mídia usando tags personalizadas, uma implementação terá esta aparência:

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

Detectar quando a playlist muda

Quando um item de mídia é adicionado, removido ou movido, Listener.onTimelineChanged(Timeline, @TimelineChangeReason) é chamado imediatamente com TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED. Esse callback é chamado mesmo quando o player ainda não foi 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);
  }
}

Quando informações como a duração de um item de mídia na playlist mudam disponível, o método Timeline será atualizado, e onTimelineChanged será chamado com TIMELINE_CHANGE_REASON_SOURCE_UPDATE. Outros motivos que podem causar atualização do cronograma incluem:

  • Um manifesto é disponibilizado após a preparação de um item de mídia adaptável.
  • Um manifesto é atualizado periodicamente durante a reprodução de uma transmissão ao vivo.