Danh sách phát

API danh sách phát được xác định bằng giao diện Player, được triển khai bằng tất cả cách triển khai ExoPlayer. Danh sách phát cho phép phát tuần tự nhiều nội dung mục nội dung nghe nhìn. Ví dụ sau đây trình bày cách bắt đầu phát một danh sách phát chứa hai 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();

Quá trình chuyển đổi 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 chúng có cùng định dạng (ví dụ: sẽ không có vấn đề gì khi danh sách phát chứa cả hai định dạng video H264 và VP9). Chúng thậm chí có thể thuộc nhiều loại khác nhau (điều đó cũng không sao đối với danh sách phát chứa video, hình ảnh và luồng chỉ âm thanh). Bạn có thể sử 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ể linh động sửa đổi danh sách phát bằng cách thêm, di chuyển, xoá hoặc thay thế mục nội dung nghe nhìn. Việc này có thể được thực hiện cả trước và trong khi phát bằng cách gọi hàm 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 tự động xử lý các sửa đổi trong khi phát theo đúng :

  • Nếu MediaItem đang phát bị di chuyển, quá trình phát sẽ không bị gián đoạn và trò chơi kế tiếp mới sẽ được phát sau khi hoàn tất.
  • Nếu MediaItem đang phát bị xoá, trình phát sẽ tự động phát phiên bản kế tiếp đầu tiên hoặc chuyển sang trạng thái đã kết thúc nếu không kế thừa đó tồn tại.
  • Nếu MediaItem đang phát bị thay 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 trong MediaItem liên quan đến phát đã thay đổi. Ví dụ: bạn có thể cập nhật MediaItem.MediaMetadata trong hầu hết các trường hợp mà không ảnh hưởng đến việc phát.

Truy vấn danh sách phát

Có thể truy vấn danh sách phát này bằng Player.getMediaItemCountPlayer.getMediaItemAt Có thể truy vấn mục nội dung nghe nhìn đang phát bằng cách gọi Player.getCurrentMediaItem. Ngoài ra, còn có các tiện nghi khác các phương thức như Player.hasNextMediaItem hoặc Player.getNextMediaItemIndex để đơn giản hoá thao tác trong danh sách phát.

Chế độ lặp lại

Người chơi hỗ trợ 3 chế độ lặp lại mà có thể thiết lập bất cứ lúc nào bằ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 đổi sang Player.STATE_ENDED sau khi mục cuối cùng trong danh sách phát đã đã được phát.
  • Player.REPEAT_MODE_ONE: Mục hiện tại lặp lại trong một vòng lặp vô tận. Các phương thức như Player.seekToNextMediaItem sẽ bỏ qua điều này và tìm cách mục tiếp theo trong danh sách. Sau đó, các mục này sẽ được lặp lại trong một vòng lặp vô hạn.
  • Player.REPEAT_MODE_ALL: Toàn bộ danh sách phát lặp lại trong một vòng lặp vô tận.

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 Player.setShuffleModeEnabled. Khi ở chế độ trộn bài, người chơi sẽ phát danh sách phát theo thứ tự tính toán trước và ngẫu nhiên. Tất cả các vật phẩm sẽ được chơi 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 thứ tự ngẫu nhiên giống nhau trong một vòng lặp vô tận. Khi chế độ trộn bài bị tắt, quá trình phát sẽ tiếp tục từ mục hiện tại ở vị trí ban đầu trong danh sách phát.

Lưu ý rằng chỉ mục được trả về bằng các phương thức như Player.getCurrentMediaItemIndex luôn đề cập đến video gốc, không bị xáo trộn đơn đặt hàng. Tương tự, Player.seekToNextMediaItem sẽ không phát mục tại player.getCurrentMediaItemIndex() + 1, nhưng mục tiếp theo theo xáo trộn thứ tự. 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ẽ vẫn giữ lại thứ tự xáo trộn hiện có không thay đổi nhiều nhất có thể.

Đặt thứ tự trộn bài tuỳ chỉnh

Theo mặc định, trình phát hỗ trợ phát ngẫu nhiên bằng cách sử dụng DefaultShuffleOrder. Bạn có thể tuỳ chỉnh cách triển khai thứ tự xáo trộn tuỳ chỉnh hoặc bằng cách thiết lập 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 ứng dụng không xác định rõ ràng mã nhận dạng nội dung đa phương tiện cho một mục nội dung đa phương tiện, chuỗi biểu diễn 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, mỗi mục nội dung đa phương tiện cũng có thể được định cấu hình bằng thẻ tuỳ chỉnh. có thể là đối tượng bất kỳ do ứng dụng cung cấp. Một công dụng của thẻ tuỳ chỉnh là đính kèm siêu dữ liệu cho từng mục nội dung đa phương tiệ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 chuyển đổi phát lại sang mục nội dung nghe nhìn khác

Khi chuyển đổi phát lại sang một mục nội dung nghe nhìn khác hoặc bắt đầu lặp lại tương tự mục nội dung đa phương tiện, Listener.onMediaItemTransition(MediaItem, @MediaItemTransitionReason) sẽ được gọi. Lệnh gọi lại này nhận nội dung nghe nhìn mới cùng với @MediaItemTransitionReason cho biết lý do chuyển đổi đã xảy ra. 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 đa phương tiệ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 đa phương tiện bằng cách sử dụng thì quá trình triển khai có thể trông giố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 đa phương tiệ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 là được gọi ngay cả khi người chơi chưa chuẩn bị sẵn sàng.

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ác thông tin 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 trở thành có sẵn, Timeline sẽ được cập nhật và onTimelineChanged sẽ được gọi cùng với TIMELINE_CHANGE_REASON_SOURCE_UPDATE. Các lý do khác có thể gây ra nội dung cập nhật về dòng thời gian bao gồm:

  • Tệp kê khai sẽ xuất hiện sau khi chuẩn bị mục nội dung nghe nhìn thích ứng.
  • Tệp kê khai được cập nhật định kỳ trong khi phát luồng trực tiếp.