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

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

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

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

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

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

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

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

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

หากคุณมีสิทธิ์เข้าถึง Player คุณควรเรียกใช้เมธอดของ 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 ดูเอกสารประกอบ ExoPlayer เกี่ยวกับเหตุการณ์ของเพลเยอร์เพื่อดูรายละเอียดเกี่ยวกับวิธีสร้างและใช้ Listener

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

Kotlin

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

Java

Handler handler = new Handler(Looper.getMainLooper());
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 : SimpleBasePlayer(looper) {
  override fun getState(): State {
    return State.Builder()
      .setAvailableCommands(...) // 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

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

  @Override
  protected State getState() {
    return new State.Builder()
      .setAvailableCommands(...) // 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ที่กำหนดเองทั้งหมด ดูรายละเอียดเพิ่มเติมได้ในคำแนะนำในหน้าการปรับแต่ง