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

เพลเยอร์คือคอมโพเนนต์ของแอปที่ช่วยให้เล่นรายการสื่อได้ อินเทอร์เฟซ 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 ที่ทำงานเป็นบริการที่ทำงานอยู่เบื้องหน้า หากทำเช่นนั้น คุณจะแยกเพลเยอร์ออกจากกิจกรรมในแอปที่มี 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 ไม่มี Callback เพื่อติดตามความคืบหน้าของการเล่นตามปกติ หากต้องการตรวจสอบความคืบหน้าในการเล่นอย่างต่อเนื่อง เช่น เพื่อตั้งค่า 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() คุณต้องใช้เมธอดที่ใช้สำหรับคำสั่งที่เพลเยอร์ประกาศว่าพร้อมใช้งานเท่านั้น ค้นหาเมธอดของเครื่องจัดการที่ลบล้างได้ซึ่งสอดคล้องกับฟังก์ชันการทำงานที่คุณต้องการใช้ เช่น ลบล้างเมธอด handleSeek() เพื่อรองรับการดำเนินการต่างๆ เช่น COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM และ COMMAND_SEEK_TO_NEXT_MEDIA_ITEM

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

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