API danh sách phát được xác định bằng giao diện Player, do tất cả các hoạt động triển khai ExoPlayer triển khai. Danh sách phát cho phép phát tuần tự nhiều mục nội dung nghe nhìn. Ví dụ sau đây minh hoạ cách bắt đầu phát một danh sách phát chứa 2 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();
Các cảnh chuyển tiếp giữa các mục trong danh sách phát diễn ra liền mạch. Không có yêu cầu nào về việc các video phải có cùng định dạng (ví dụ: danh sách phát có thể chứa cả video H264 và VP9). Chúng thậm chí có thể thuộc nhiều loại (tức là danh sách phát có thể chứa video, hình ảnh và luồng chỉ có âm thanh). Bạn có thể dùng cùng một MediaItem nhiều lần trong một danh sách phát.
Sửa đổi danh sách phát
Bạn có thể sửa đổi danh sách phát một cách linh hoạt bằng cách thêm, di chuyển, xoá hoặc thay thế các mục nội dung nghe nhìn. Bạn có thể thực hiện việc này cả trước và trong khi phát bằng cách gọi các phương thức API danh sách phát tương ứng:
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));
Chúng tôi cũng hỗ trợ việc thay thế và xoá toàn bộ danh sách phát:
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();
Trình phát sẽ tự động xử lý các nội dung sửa đổi trong quá trình phát theo cách chính xác:
- Nếu
MediaItemđang phát bị di chuyển, thì quá trình phát sẽ không bị gián đoạn vàMediaItemmới thay thế sẽ được phát sau khiMediaItemcũ hoàn tất. - Nếu
MediaItemđang phát bị xoá, trình phát sẽ tự động phát người kế nhiệm còn lại đầu tiên hoặc chuyển sang trạng thái kết thúc nếu không có người kế nhiệm nào như vậy. - Nếu
MediaItemhiện đang phát bị thay thế, thì quá trình phát sẽ không bị gián đoạn nếu không có thuộc tính nào trongMediaItemliên quan đến quá trình phát bị thay đổi. Ví dụ: bạn có thể cập nhật các trườngMediaItem.MediaMetadatatrong hầu hết các trường hợp mà không ảnh hưởng đến quá trình phát.
Truy vấn danh sách phát
Bạn có thể truy vấn danh sách phát bằng cách sử dụng Player.getMediaItemCount và Player.getMediaItemAt. Bạn có thể truy vấn mục nội dung nghe nhìn hiện đang phát bằng cách gọi Player.getCurrentMediaItem. Ngoài ra, còn có những phương thức thuận tiện khác như Player.hasNextMediaItem hoặc Player.getNextMediaItemIndex để đơn giản hoá việc điều hướng trong danh sách phát.
Chế độ lặp lại
Trình phát này hỗ trợ 3 chế độ lặp lại mà bạn có thể đặt bất cứ lúc nào bằng cách nhấn vào biểu tượng Player.setRepeatMode:
Player.REPEAT_MODE_OFF: Danh sách phát không lặp lại và trình phát sẽ chuyển sangPlayer.STATE_ENDEDsau khi phát xong mục cuối cùng trong danh sách phát.Player.REPEAT_MODE_ONE: Mục hiện tại được lặp lại trong một vòng lặp vô tận. Các phương thức nhưPlayer.seekToNextMediaItemsẽ bỏ qua điều này và tìm kiếm mục tiếp theo trong danh sách, sau đó mục này sẽ được lặp lại trong một vòng lặp vô tận.Player.REPEAT_MODE_ALL: Toàn bộ danh sách phát sẽ được phát lặp lại liên tục.
Chế độ trộn bài
Bạn có thể bật hoặc tắt chế độ trộn bài bất cứ lúc nào bằng cách nhấn vào biểu tượng Player.setShuffleModeEnabled. Khi ở chế độ trộn bài, trình phát sẽ phát danh sách phát theo một thứ tự ngẫu nhiên đã được tính toán trước. Tất cả các mục sẽ được phát một lần và bạn cũng có thể kết hợp chế độ trộn bài với Player.REPEAT_MODE_ALL để lặp lại cùng một thứ tự ngẫu nhiên trong một vòng lặp vô tận. Khi chế độ trộn bài bị tắt, nội dung phát sẽ tiếp tục từ mục hiện tại ở vị trí ban đầu trong danh sách phát.
Xin lưu ý rằng các chỉ mục do các phương thức như Player.getCurrentMediaItemIndex trả về luôn đề cập đến thứ tự ban đầu, chưa được xáo trộn. Tương tự, Player.seekToNextMediaItem sẽ không phát mục tại player.getCurrentMediaItemIndex() + 1 mà sẽ phát mục tiếp theo theo thứ tự trộn. Việc chèn các mục mới vào danh sách phát hoặc xoá các mục sẽ giữ nguyên thứ tự phát ngẫu nhiên hiện tại trong phạm vi có thể.
Thiết lập thứ tự phát ngẫu nhiên tuỳ chỉnh
Theo mặc định, trình phát hỗ trợ tính năng trộn bài bằng cách sử dụng DefaultShuffleOrder.
Bạn có thể tuỳ chỉnh chế độ này bằng cách triển khai thứ tự trộn tuỳ chỉnh hoặc bằng cách đặt thứ tự tuỳ chỉnh trong hàm khởi tạo 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);
Xác định các mục trong danh sách phát
Để xác định các mục trong danh sách phát, bạn có thể đặt MediaItem.mediaId khi tạo mục:
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();
Nếu một ứng dụng không xác định rõ mã nhận dạng nội dung nghe nhìn cho một mục nội dung nghe nhìn, thì hệ thống sẽ sử dụng chuỗi biểu thị URI.
Liên kết dữ liệu ứng dụng với các mục trong danh sách phát
Ngoài mã nhận dạng, bạn cũng có thể định cấu hình từng mục nội dung đa phương tiện bằng một thẻ tuỳ chỉnh. Thẻ này có thể là bất kỳ đối tượng nào do ứng dụng cung cấp. Một cách sử dụng thẻ tuỳ chỉnh là đính kèm siêu dữ liệu vào từng mục nội dung nghe nhìn:
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();
Phát hiện thời điểm quá trình phát chuyển sang một mục nội dung nghe nhìn khác
Khi quá trình phát chuyển sang một mục nội dung nghe nhìn khác hoặc bắt đầu lặp lại cùng một mục nội dung nghe nhìn, Listener.onMediaItemTransition(MediaItem,
@MediaItemTransitionReason) sẽ được gọi. Lệnh gọi lại này nhận được mục nội dung nghe nhìn mới, cùng với một @MediaItemTransitionReason cho biết lý do xảy ra quá trình chuyển đổi. Một trường hợp sử dụng phổ biến cho onMediaItemTransition là cập nhật giao diện người dùng của ứng dụng cho mục nội dung nghe nhìn mới:
Kotlin
override fun onMediaItemTransition( mediaItem: MediaItem?, @MediaItemTransitionReason reason: Int, ) { updateUiForPlayingMediaItem(mediaItem) }
Java
@Override public void onMediaItemTransition( @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) { updateUiForPlayingMediaItem(mediaItem); }
Nếu siêu dữ liệu cần thiết để cập nhật giao diện người dùng được đính kèm vào từng mục nội dung nghe nhìn bằng thẻ tuỳ chỉnh, thì quá trình triển khai có thể trông như sau:
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); }
Phát hiện thời điểm danh sách phát thay đổi
Khi một mục nội dung nghe nhìn được thêm, xoá hoặc di chuyển, Listener.onTimelineChanged(Timeline, @TimelineChangeReason) sẽ được gọi ngay lập tức bằng TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED. Lệnh gọi lại này được gọi ngay cả khi trình phát chưa được chuẩn bị.
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); } }
Khi có thông tin (chẳng hạn như thời lượng của một mục nội dung đa phương tiện trong danh sách phát), Timeline sẽ được cập nhật và onTimelineChanged sẽ được gọi bằng TIMELINE_CHANGE_REASON_SOURCE_UPDATE. Sau đây là những lý do khác có thể khiến dòng thời gian được cập nhật:
- Tệp kê khai sẽ có sẵn sau khi bạn chuẩn bị một mục nội dung nghe nhìn thích ứng.
- Tệp kê khai được cập nhật định kỳ trong quá trình phát một sự kiện phát trực tiếp.