Playlist

Playlist API ditentukan oleh antarmuka Player, yang diimplementasikan oleh semua implementasi ExoPlayer. Playlist memungkinkan pemutaran berurutan beberapa item media. Contoh berikut menunjukkan cara memulai pemutaran playlist berisi dua 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();

Transisi antar-item dalam playlist berjalan lancar. Tidak ada persyaratan keduanya memiliki format yang sama (misalnya, tidak masalah jika daftar putar berisi keduanya video H264 dan VP9). Mereka bahkan mungkin dari berbagai jenis (yaitu, tidak apa-apa untuk playlist untuk berisi streaming video, gambar, dan audio saja). Anda dapat menggunakan MediaItem yang sama beberapa kali dalam playlist.

Mengubah playlist

Anda dapat mengubah playlist secara dinamis dengan menambahkan, memindahkan, menghapus, atau mengganti item media. Hal ini dapat dilakukan sebelum dan selama pemutaran dengan memanggil metode metode API playlist yang sesuai:

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

Mengganti dan menghapus seluruh playlist juga didukung:

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

Pemutar otomatis menangani modifikasi selama pemutaran dengan cara:

  • Jika MediaItem yang sedang diputar dipindahkan, pemutaran tidak akan terganggu dan penggantinya yang baru akan dimainkan setelah selesai.
  • Jika MediaItem yang sedang diputar dihapus, pemutar akan otomatis putar penerus pertama yang tersisa, atau transisi ke status berakhir jika tidak pengganti seperti itu sudah ada.
  • Jika MediaItem yang sedang diputar diganti, pemutaran tidak terganggu jika tidak ada properti dalam MediaItem yang relevan untuk pemutaran ubah. Misalnya, Anda dapat mengupdate MediaItem.MediaMetadata yang sering digunakan tanpa memengaruhi pemutaran.

Membuat kueri playlist

Playlist dapat dikueri menggunakan Player.getMediaItemCount dan Player.getMediaItemAt. Item media yang sedang diputar dapat dikueri dengan memanggil Player.getCurrentMediaItem. Ada juga kemudahan lain metode seperti Player.hasNextMediaItem atau Player.getNextMediaItemIndex untuk menyederhanakan navigasi dalam {i>playlist<i}.

Mode pengulangan

Pemutar mendukung 3 mode pengulangan yang dapat diatur kapan saja dengan Player.setRepeatMode:

  • Player.REPEAT_MODE_OFF: Playlist tidak diulang dan pemutar akan transisi ke Player.STATE_ENDED setelah item terakhir dalam playlist memiliki yang pernah dimainkan.
  • Player.REPEAT_MODE_ONE: Item saat ini diulangi dalam loop tanpa henti. Metode seperti Player.seekToNextMediaItem akan mengabaikan ini dan mencari ke item berikutnya dalam daftar, yang kemudian akan diulangi tanpa henti.
  • Player.REPEAT_MODE_ALL: Seluruh playlist diulangi tanpa henti.

Mode acak

Mode acak dapat diaktifkan atau dinonaktifkan kapan saja dengan Player.setShuffleModeEnabled. Saat dalam mode acak, pemutar akan memutar playlist dalam urutan acak yang telah dihitung sebelumnya. Semua item akan dimainkan sekali dan mode acak juga dapat digabungkan dengan Player.REPEAT_MODE_ALL untuk mengulangi urutan acak yang sama dalam {i>loop <i}tak berujung. Saat mode acak dinonaktifkan, pemutaran akan dilanjutkan dari item saat ini di posisi aslinya dalam playlist.

Perhatikan bahwa indeks yang ditampilkan oleh metode seperti Player.getCurrentMediaItemIndex selalu merujuk ke aslinya, tanpa diacak pesanan. Demikian pula, Player.seekToNextMediaItem tidak akan memutar item di player.getCurrentMediaItemIndex() + 1, tetapi item berikutnya menurut dalam urutan acak. Menyisipkan item baru dalam playlist atau menghapus item akan membuat urutan yang diacak yang ada tidak berubah sejauh mungkin.

Menetapkan urutan acak kustom

Secara default, pemutar mendukung pengacakan menggunakan DefaultShuffleOrder. Hal ini dapat disesuaikan dengan menyediakan penerapan urutan acak khusus, atau dengan menetapkan urutan kustom di konstruktor 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);

Mengidentifikasi item playlist

Untuk mengidentifikasi item playlist, MediaItem.mediaId dapat disetel saat membuat 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();

Jika aplikasi tidak secara eksplisit menentukan ID media untuk item media, string akan digunakan.

Mengaitkan data aplikasi dengan item playlist

Selain ID, setiap item media juga dapat dikonfigurasi dengan tag kustom, yang dapat berupa objek apa pun yang disediakan oleh aplikasi. Salah satu kegunaan tag kustom adalah untuk melampirkan metadata ke setiap item media:

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

Mendeteksi saat pemutaran bertransisi ke item media lain

Saat pemutaran bertransisi ke item media lain, atau mulai mengulangi pemutaran yang sama item media, Listener.onMediaItemTransition(MediaItem, @MediaItemTransitionReason) dipanggil. Callback ini menerima media baru item, bersama dengan @MediaItemTransitionReason yang menunjukkan alasan transisi terjadi. Kasus penggunaan umum untuk onMediaItemTransition adalah memperbarui UI aplikasi untuk item media baru:

Kotlin

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

Java

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

Jika metadata yang diperlukan untuk mengupdate UI, akan dilampirkan ke setiap item media menggunakan tag kustom, penerapannya mungkin akan terlihat seperti berikut:

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

Mendeteksi kapan playlist berubah

Saat item media ditambahkan, dihapus, atau dipindahkan, Listener.onTimelineChanged(Timeline, @TimelineChangeReason) dipanggil. langsung dengan TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED. Callback ini adalah dipanggil bahkan ketika pemain belum siap.

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

Saat informasi, seperti durasi item media dalam playlist, tersedia, Timeline akan diperbarui dan onTimelineChanged akan dipanggil dengan TIMELINE_CHANGE_REASON_SOURCE_UPDATE. Alasan lain yang dapat menyebabkan pembaruan {i>timeline<i} meliputi:

  • Manifes tersedia setelah menyiapkan item media adaptif.
  • Manifes diupdate secara berkala selama pemutaran live stream.