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
yang 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 lancar. Tidak ada persyaratan
bahwa video harus memiliki format yang sama (misalnya, playlist boleh berisi video H264 dan VP9). Bahkan, jenisnya bisa berbeda-beda (yaitu, tidak masalah jika playlist berisi video, gambar, dan hanya streaming audio). 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 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));
Penggantian dan penghapusan 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 yang benar:
- Jika
MediaItemyang sedang diputar dipindahkan, pemutaran tidak akan terganggu dan penggantinya yang baru akan diputar setelah selesai. - Jika
MediaItemyang sedang diputar dihapus, pemutar akan otomatis memutar penerus pertama yang tersisa, atau bertransisi ke status berakhir jika tidak ada penerus seperti itu. - Jika
MediaItemyang sedang diputar diganti, pemutaran tidak akan terganggu jika tidak ada properti dalamMediaItemyang relevan untuk pemutaran yang berubah. Misalnya, kolomMediaItem.MediaMetadatadapat diperbarui dalam sebagian besar kasus tanpa memengaruhi pemutaran.
Mengueri playlist
Playlist dapat dikueri menggunakan Player.getMediaItemCount dan
Player.getMediaItemAt. Item media yang sedang diputar dapat dikueri
dengan memanggil Player.getCurrentMediaItem. Ada juga metode praktis lainnya seperti Player.hasNextMediaItem atau Player.getNextMediaItemIndex untuk menyederhanakan navigasi dalam playlist.
Mode pengulangan
Pemutar mendukung 3 mode pengulangan yang dapat disetel kapan saja dengan
Player.setRepeatMode:
Player.REPEAT_MODE_OFF: Daftar putar tidak diulang dan pemutar akan beralih kePlayer.STATE_ENDEDsetelah item terakhir dalam daftar putar diputar.Player.REPEAT_MODE_ONE: Item saat ini diulang dalam loop tanpa akhir. Metode sepertiPlayer.seekToNextMediaItemakan mengabaikan hal ini dan mencari item berikutnya dalam daftar, yang kemudian akan diulang dalam loop tanpa akhir.Player.REPEAT_MODE_ALL: Seluruh playlist diulang dalam loop tanpa akhir.
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 diputar satu kali dan
mode acak juga dapat digabungkan dengan Player.REPEAT_MODE_ALL untuk mengulang
urutan acak yang sama dalam loop tanpa akhir. Jika 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 pada urutan asli yang tidak diacak. Demikian pula, Player.seekToNextMediaItem tidak akan memutar item di
player.getCurrentMediaItemIndex() + 1, tetapi item berikutnya sesuai dengan
urutan acak. Menyisipkan item baru dalam playlist atau menghapus item akan membuat urutan acak yang ada tetap tidak berubah sebisa mungkin.
Menetapkan urutan pengacakan kustom
Secara default, pemutar mendukung pengacakan menggunakan DefaultShuffleOrder.
Hal ini dapat disesuaikan dengan memberikan implementasi urutan pengacakan kustom, 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 ditetapkan 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, representasi string URI akan digunakan.
Mengaitkan data aplikasi dengan item playlist
Selain ID, setiap item media juga dapat dikonfigurasi dengan tag kustom, yang dapat berupa objek yang disediakan aplikasi. Salah satu penggunaan 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 mengulang item media yang sama, Listener.onMediaItemTransition(MediaItem,
@MediaItemTransitionReason) dipanggil. Callback ini menerima item media baru, beserta @MediaItemTransitionReason yang menunjukkan alasan terjadinya transisi. 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 memperbarui UI dilampirkan ke setiap item media menggunakan tag kustom, maka implementasinya mungkin terlihat seperti:
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 saat playlist berubah
Saat item media ditambahkan, dihapus, atau dipindahkan,
Listener.onTimelineChanged(Timeline, @TimelineChangeReason) dipanggil
segera dengan TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED. Callback ini dipanggil meskipun pemutar 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 linimasa meliputi:
- Manifes tersedia setelah menyiapkan item media adaptif.
- Manifes diperbarui secara berkala selama pemutaran live stream.