อินเทอร์เฟซของโปรแกรมเล่น

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

  • การควบคุมการเล่น เช่น เล่น หยุดชั่วคราว และค้นหา
  • การค้นหาพร็อพเพอร์ตี้ของสื่อที่กำลังเล่นอยู่ เช่น ตำแหน่งการเล่น
  • การจัดการเพลย์ลิสต์/คิวของรายการสื่อ
  • การกำหนดค่าพร็อพเพอร์ตี้การเล่น เช่น การสับเปลี่ยน การเล่นซ้ำ ความเร็ว และ ระดับเสียง
  • การแสดงวิดีโอบนหน้าจอ

นอกจากนี้ Media3 ยังมีการติดตั้งใช้งานอินเทอร์เฟซ Player ที่เรียกว่า ExoPlayer ด้วย

อินเทอร์เฟซทั่วไประหว่างคอมโพเนนต์

คอมโพเนนต์หลายรายการใน Media3 ใช้การติดตั้งใช้งานอินเทอร์เฟซ Player เช่น

คอมโพเนนต์ คำอธิบายและหมายเหตุเกี่ยวกับลักษณะการทำงาน
ExoPlayer API มีเดียเพลเยอร์และการติดตั้งใช้งานเริ่มต้นของอินเทอร์เฟซ Player
MediaController โต้ตอบกับ MediaSession เพื่อส่งคำสั่งการเล่น หาก Player และ MediaSession อยู่ใน Service แยกจาก Activity หรือ Fragment ที่ UI ของเพลเยอร์อยู่ คุณสามารถกำหนด MediaController เป็นเพลเยอร์สำหรับคอมโพเนนต์ UI เช่น PlayerView หรือ Player Composable ระบบจะส่งการเรียกใช้เมธอดการเล่นและเพลย์ลิสต์ไปยัง Player ผ่าน MediaSession
MediaBrowser นอกเหนือจากฟังก์ชันการทำงานที่ MediaController มีให้แล้ว ยังโต้ตอบกับ MediaLibrarySession เพื่อเรียกดูเนื้อหาสื่อที่พร้อมใช้งานด้วย
SimpleBasePlayer การติดตั้งใช้งาน Player ที่ลดจำนวนเมธอด ที่ต้องติดตั้งใช้งานลงเหลือน้อยที่สุด มีประโยชน์เมื่อใช้เพลเยอร์ที่กำหนดเองซึ่งคุณ ต้องการเชื่อมต่อกับ MediaSession
ForwardingSimpleBasePlayer คลาสย่อย SimpleBasePlayer ที่ออกแบบมาเพื่อส่งต่อการดำเนินการเล่น ไปยัง Player อื่น ขณะเดียวกันก็อนุญาตให้ปรับแต่งลักษณะการทำงานที่สอดคล้องกันแบบเดียวกับ SimpleBasePlayer ใช้ คลาสนี้เพื่อระงับหรือแก้ไขการดำเนินการเล่นที่เฉพาะเจาะจง
RemoteCastPlayer การติดตั้งใช้งาน Player สำหรับควบคุมการเล่นในแอปตัวรับสัญญาณ Cast ระยะไกล
CastPlayer การติดตั้งใช้งาน Player สำหรับควบคุมการเล่น Cast ทั้งในเครื่องและระยะไกล

แม้ว่า MediaSession จะไม่ได้ใช้การติดตั้งใช้งานอินเทอร์เฟซ Player แต่ก็ต้องมี Player เมื่อสร้าง โดยมีวัตถุประสงค์เพื่อให้เข้าถึง Player จากกระบวนการหรือเธรดอื่นๆ ได้

สถาปัตยกรรมการเล่นของ Media3

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

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

แผนภาพแสดงวิธีที่คอมโพเนนต์การเล่นของ Media3 เข้ากับสถาปัตยกรรมของแอปสื่อ
รูปที่ 1: อินเทอร์เฟซ Player มีบทบาทสำคัญ ในสถาปัตยกรรมของ Media3

สถานะผู้เล่น

สถานะของมีเดียเพลเยอร์ที่ใช้การติดตั้งใช้งานอินเทอร์เฟซ Player ประกอบด้วยข้อมูล 4 หมวดหมู่หลักๆ ดังนี้

  1. สถานะการเล่น
  2. เพลย์ลิสต์ของรายการสื่อ
    • ลำดับอินสแตนซ์ MediaItem สำหรับการเล่น
    • ดึงข้อมูลด้วย getCurrentTimeline()
    • อินสแตนซ์ Player สามารถระบุเมธอดการดำเนินการเพลย์ลิสต์ เช่น การเพิ่ม หรือ การนำออก MediaItem และเมธอดที่สะดวก เช่น getCurrentMediaItem()
  3. พร็อพเพอร์ตี้เล่น/หยุดชั่วคราว เช่น
    • playWhenReady: ตัวบ่งชี้ว่าผู้ใช้ต้องการให้เล่นสื่อเมื่อเป็นไปได้หรือหยุดชั่วคราว
    • เหตุผลในการระงับการเล่น: ตัวบ่งชี้เหตุผลที่ระงับการเล่น (หากมี) แม้ว่า playWhenReady จะเป็น true
    • isPlaying: ตัวบ่งชี้ว่าเพลเยอร์กำลังเล่นอยู่หรือไม่ ซึ่งจะเป็น true ก็ต่อเมื่อสถานะการเล่นเป็น STATE_READY, playWhenReady เป็น true และไม่ได้ระงับการเล่น
  4. ตำแหน่งการเล่น ซึ่งรวมถึง

นอกจากนี้ อินเทอร์เฟซ Player ยังอนุญาตให้เข้าถึง แทร็กที่พร้อมใช้งาน, ข้อมูลเมตาของสื่อ, ความเร็วในการเล่น, ระดับเสียง และพร็อพเพอร์ตี้เสริมอื่นๆ ของการเล่น

ฟังการเปลี่ยนแปลง

ใช้ Player.Listener เพื่อฟังการเปลี่ยนแปลงใน Player ดูรายละเอียดเกี่ยวกับวิธีสร้างและใช้ Listener ได้ในเอกสารประกอบ ExoPlayer เกี่ยวกับ เหตุการณ์เพลเยอร์

โปรดทราบว่าอินเทอร์เฟซ Listener ไม่มีการเรียกกลับเพื่อติดตามความคืบหน้าการเล่นปกติ หากต้องการตรวจสอบความคืบหน้าการเล่นอย่างต่อเนื่อง เช่น เพื่อตั้งค่า UI แถบความคืบหน้า คุณควรค้นหาตำแหน่งปัจจุบันตามช่วงเวลาที่เหมาะสม

Kotlin

fun checkPlaybackPosition(delayMs: Long): Boolean =
  handler.postDelayed(
    {
      val currentPosition = player.currentPosition
      // Update UI based on currentPosition
      checkPlaybackPosition(delayMs)
    },
    delayMs,
  )

Java

boolean checkPlaybackPosition(long delayMs) {
  return handler.postDelayed(
      () -> {
        long currentPosition = player.getCurrentPosition();
        // Update UI based on currentPosition
        checkPlaybackPosition(delayMs);
      },
      delayMs);
}

ควบคุมการเล่น

อินเทอร์เฟซ Player มีวิธีมากมายในการจัดการสถานะและควบคุมการเล่น ดังนี้

การติดตั้งใช้งาน Player ที่กำหนดเอง

หากต้องการสร้างเพลเยอร์ที่กำหนดเอง คุณสามารถขยาย SimpleBasePlayer ที่รวมอยู่ใน Media3 ได้ คลาสนี้มีการติดตั้งใช้งานพื้นฐานของอินเทอร์เฟซ Player เพื่อลดจำนวนเมธอดที่คุณต้องติดตั้งใช้งานลงเหลือน้อยที่สุด

เริ่มต้นด้วยการลบล้างเมธอด getState() เมธอดนี้ควรป้อนข้อมูลสถานะเพลเยอร์ปัจจุบันเมื่อมีการเรียกใช้ ซึ่งรวมถึง

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

Kotlin

class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) {
  override fun getState(): State {
    return State.Builder()
      .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle
      // Configure additional playback properties
      .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
      .setCurrentMediaItemIndex(0)
      .setContentPositionMs(0)
      .build()
  }
}

Java

private static final class CustomPlayer extends SimpleBasePlayer {
  public CustomPlayer(Looper looper) {
    super(looper);
  }

  @Override
  protected State getState() {
    return new State.Builder()
        .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle
        // Configure additional playback properties
        .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
        .setCurrentMediaItemIndex(0)
        .setContentPositionMs(0)
        .build();
  }
}

SimpleBasePlayer จะบังคับให้สร้าง State ด้วยชุดค่าสถานะที่ถูกต้อง นอกจากนี้ยังจัดการ Listener และแจ้งให้ Listener ทราบถึงการเปลี่ยนแปลงสถานะด้วย หากต้องการเริ่มการอัปเดตสถานะด้วยตนเอง ให้เรียกใช้ invalidateState()

นอกเหนือจากเมธอด getState() แล้ว คุณจะต้องติดตั้งใช้งานเมธอดที่ใช้สำหรับคำสั่งที่เพลเยอร์ประกาศว่าพร้อมใช้งานเท่านั้น ค้นหาเมธอด Handler ที่ลบล้างได้ซึ่งสอดคล้องกับฟังก์ชันการทำงานที่คุณต้องการติดตั้งใช้งาน ตัวอย่างเช่น ลบล้างเมธอด handleSeek() เพื่อรองรับการดำเนินการต่างๆ เช่น COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM และ COMMAND_SEEK_TO_NEXT_MEDIA_ITEM

แก้ไขการติดตั้งใช้งาน Player

แทนที่จะสร้าง Player ที่กำหนดเองทั้งหมด คุณสามารถใช้ ForwardingSimpleBasePlayer เพื่อแก้ไขสถานะและลักษณะการทำงานของ Player ที่มีอยู่ได้ ดูรายละเอียดเพิ่มเติมได้ในคู่มือในหน้าการปรับแต่งสำหรับ