เพลย์ลิสต์

API เพลย์ลิสต์กำหนดโดยPlayerอินเทอร์เฟซ ซึ่งExoPlayerการติดตั้งใช้งานทั้งหมดจะใช้ เพลย์ลิสต์ช่วยให้เล่นรายการสื่อหลายรายการ ตามลำดับได้ ตัวอย่างต่อไปนี้แสดงวิธีเริ่มเล่น เพลย์ลิสต์ ที่มีวิดีโอ 2 รายการ

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

การเปลี่ยนระหว่างรายการในเพลย์ลิสต์จะราบรื่น โดยไม่จำเป็นต้องมีรูปแบบเดียวกัน (เช่น เพลย์ลิสต์จะมีวิดีโอทั้ง H264 และ VP9 ก็ได้) และอาจเป็นเพลย์ลิสต์ประเภทต่างๆ ได้ด้วย (กล่าวคือ เพลย์ลิสต์จะมีเพียงวิดีโอ รูปภาพ และสตรีมเสียงก็ได้) คุณใช้MediaItemเดียวกันหลายครั้งในเพลย์ลิสต์ได้

การแก้ไขเพลย์ลิสต์

คุณสามารถแก้ไขเพลย์ลิสต์แบบไดนามิกได้โดยการเพิ่ม ย้าย นำออก หรือแทนที่ รายการสื่อ คุณทำได้ทั้งก่อนและระหว่างการเล่นโดยการเรียกใช้เมธอด API ของเพลย์ลิสต์ที่เกี่ยวข้อง ดังนี้

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

นอกจากนี้ยังรองรับการแทนที่และการล้างทั้งเพลย์ลิสต์ด้วย โดยทำดังนี้

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

โดยเพลเยอร์จะจัดการการแก้ไขโดยอัตโนมัติในระหว่างการเล่นอย่างถูกต้อง ดังนี้

  • หากมีการย้าย MediaItem ที่กำลังเล่นอยู่ การเล่นจะไม่หยุดชะงักและ ระบบจะเล่น MediaItem ตัวถัดไปเมื่อเล่นจบ
  • หากมีการนำMediaItemที่กำลังเล่นอยู่ออก เครื่องเล่นจะเล่นMediaItemตัวแรกที่เหลืออยู่โดยอัตโนมัติ หรือเปลี่ยนไปเป็นสถานะสิ้นสุดหากไม่มีMediaItemตัวใดเหลืออยู่
  • หากมีการแทนที่ MediaItem ที่เล่นอยู่ การเล่นจะไม่หยุดชะงัก หากไม่มีการเปลี่ยนแปลงพร็อพเพอร์ตี้ใดๆ ใน MediaItem ที่เกี่ยวข้องกับการเล่น เช่น คุณสามารถอัปเดตMediaItem.MediaMetadata ฟิลด์ได้ในกรณีส่วนใหญ่โดยไม่ส่งผลต่อการเล่น

การค้นหาเพลย์ลิสต์

คุณค้นหาเพลย์ลิสต์ได้โดยใช้ Player.getMediaItemCount และ Player.getMediaItemAt คุณสามารถค้นหาสื่อที่กำลังเล่นอยู่ได้ โดยการเรียกใช้ Player.getCurrentMediaItem นอกจากนี้ ยังมีวิธีอื่นๆ ที่สะดวกสบาย เช่น Player.hasNextMediaItem หรือ Player.getNextMediaItemIndex เพื่อให้การไปยังส่วนต่างๆ ในเพลย์ลิสต์ง่ายขึ้น

โหมดเล่นซ้ำ

โดยเพลเยอร์รองรับโหมดเล่นซ้ำ 3 โหมดที่ตั้งค่าได้ทุกเมื่อด้วย Player.setRepeatMode

  • Player.REPEAT_MODE_OFF: ระบบจะไม่เล่นเพลย์ลิสต์ซ้ำและโปรแกรมเล่นจะ เปลี่ยนไปเป็นPlayer.STATE_ENDEDเมื่อเล่นรายการสุดท้ายในเพลย์ลิสต์ เสร็จแล้ว
  • Player.REPEAT_MODE_ONE: รายการปัจจุบันจะเล่นซ้ำแบบวนซ้ำไม่สิ้นสุด วิธีต่างๆ เช่น Player.seekToNextMediaItem จะไม่สนใจข้อความนี้และจะค้นหารายการถัดไปในรายการ ซึ่งจะทำซ้ำในลูปที่ไม่มีที่สิ้นสุด
  • Player.REPEAT_MODE_ALL: เล่นทั้งเพลย์ลิสต์ซ้ำแบบวนซ้ำไม่สิ้นสุด

โหมดสุ่มเพลง

คุณเปิดหรือปิดใช้โหมดสุ่มเพลงได้ทุกเมื่อด้วย Player.setShuffleModeEnabled เมื่ออยู่ในโหมดสุ่ม โปรแกรมเล่นจะเล่น เพลย์ลิสต์ตามลำดับแบบสุ่มที่คำนวณไว้ล่วงหน้า ระบบจะเล่นรายการทั้งหมด 1 ครั้ง และคุณยังใช้โหมดสับเปลี่ยนร่วมกับPlayer.REPEAT_MODE_ALLเพื่อเล่นซ้ำ ลำดับแบบสุ่มเดียวกันในลูปที่ไม่มีที่สิ้นสุดได้ด้วย เมื่อปิดโหมดสับเปลี่ยน การเล่นจะดำเนินต่อจากรายการปัจจุบันที่ตำแหน่งเดิมใน เพลย์ลิสต์

โปรดทราบว่าดัชนีที่ส่งคืนโดยเมธอดต่างๆ เช่น Player.getCurrentMediaItemIndex จะอ้างอิงถึงลำดับเดิมที่ไม่ได้สับเปลี่ยนเสมอ ในทำนองเดียวกัน Player.seekToNextMediaItem จะไม่เล่นรายการที่ player.getCurrentMediaItemIndex() + 1 แต่จะเล่นรายการถัดไปตาม ลำดับการสับเปลี่ยน การแทรกรายการใหม่ในเพลย์ลิสต์หรือการนำรายการออกจะทำให้ลำดับแบบสุ่มที่มีอยู่ไม่เปลี่ยนแปลงมากที่สุด

การตั้งค่าลำดับการสับเปลี่ยนเพลงที่กำหนดเอง

โดยค่าเริ่มต้น เพลเยอร์จะรองรับการสับเปลี่ยนโดยใช้ DefaultShuffleOrder คุณปรับแต่งได้โดยการติดตั้งใช้งานลำดับการสับเปลี่ยนที่กำหนดเอง หรือโดย การตั้งค่าลำดับที่กำหนดเองในตัวสร้าง 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);

การระบุรายการในเพลย์ลิสต์

หากต้องการระบุรายการเพลย์ลิสต์ คุณMediaItem.mediaIdสามารถตั้งค่าเมื่อสร้าง รายการได้ดังนี้

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

หากแอปไม่ได้กำหนดรหัสสื่อสำหรับรายการสื่ออย่างชัดเจน ระบบจะใช้การแสดงสตริงของ URI

การเชื่อมโยงข้อมูลแอปกับรายการในเพลย์ลิสต์

นอกจากรหัสแล้ว คุณยังกำหนดค่ารายการสื่อแต่ละรายการด้วยแท็กที่กำหนดเองได้ ซึ่งอาจเป็นออบเจ็กต์ใดก็ได้ที่แอปจัดหาให้ การใช้แท็กที่กำหนดเองอย่างหนึ่งคือการแนบข้อมูลเมตา กับรายการสื่อแต่ละรายการ

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

ตรวจหาเมื่อการเล่นเปลี่ยนไปเป็นรายการสื่ออื่น

เมื่อการเล่นเปลี่ยนไปเป็นรายการสื่ออื่น หรือเริ่มเล่นรายการสื่อเดียวกันซ้ำ Listener.onMediaItemTransition(MediaItem, @MediaItemTransitionReason) จะได้รับการเรียกใช้ โดยการเรียกกลับนี้จะได้รับรายการสื่อใหม่ พร้อมกับ @MediaItemTransitionReason ที่ระบุสาเหตุของการเปลี่ยน Use Case ทั่วไปสำหรับ onMediaItemTransition คือการอัปเดต UI ของแอปสำหรับรายการสื่อใหม่ ดังนี้

Kotlin

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

Java

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

หากแนบข้อมูลเมตาที่จำเป็นต่อการอัปเดต UI ไปกับรายการสื่อแต่ละรายการโดยใช้ แท็กที่กำหนดเอง การติดตั้งใช้งานอาจมีลักษณะดังนี้

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

ตรวจหาเมื่อเพลย์ลิสต์มีการเปลี่ยนแปลง

เมื่อมีการเพิ่ม นำออก หรือย้ายรายการสื่อ Listener.onTimelineChanged(Timeline, @TimelineChangeReason) จะเรียกใช้ ทันทีด้วย TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED ระบบจะเรียกใช้แฮนเดิลนี้ แม้ว่ายังไม่ได้เตรียมเพลเยอร์ก็ตาม

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

เมื่อมีข้อมูล เช่น ระยะเวลาของรายการสื่อในเพลย์ลิสต์ ระบบจะอัปเดต Timeline และเรียกใช้ onTimelineChanged ด้วย TIMELINE_CHANGE_REASON_SOURCE_UPDATE สาเหตุอื่นๆ ที่อาจทำให้มีการอัปเดตไทม์ไลน์ ได้แก่

  • ไฟล์ Manifest จะพร้อมใช้งานหลังจากเตรียมรายการสื่อแบบปรับอัตโนมัติ
  • ไฟล์ Manifest จะได้รับการอัปเดตเป็นระยะๆ ในระหว่างการเล่นไลฟ์สด