เพลย์ลิสต์

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.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 เมื่ออยู่ในโหมดสุ่มเพลง ผู้เล่นจะเล่น ไว้ในลำดับแบบสุ่ม ที่คำนวณไว้ล่วงหน้า รายการทั้งหมดจะเล่นครั้งเดียว โหมดสุ่มเพลงสามารถรวมกับ 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) Callback นี้ได้รับสื่อใหม่ พร้อมด้วย @MediaItemTransitionReason ที่ระบุเหตุผลในการเปลี่ยน เกิดขึ้น กรณีการใช้งานทั่วไปสำหรับ 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 มีการอัปเดตเป็นระยะระหว่างการเล่นสตรีมแบบสด