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

โปรแกรมเล่นเป็นองค์ประกอบของแอปที่อำนวยความสะดวกในการเล่นรายการสื่อ อินเทอร์เฟซ 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 เพื่อเรียกดูเนื้อหาสื่อที่มีอยู่
ForwardingPlayer การใช้งาน Player ที่ส่งต่อการเรียกเมธอดไปยัง Player อีกรายการ ใช้คลาสนี้เพื่อระงับหรือแก้ไข โดยลบล้างเมธอดที่เกี่ยวข้อง
SimpleBasePlayer การใช้งาน Player ที่ลดจำนวนเมธอด ขั้นต่ำที่สุด มีประโยชน์เมื่อใช้โปรแกรมเล่นแบบกำหนดเองที่ ต้องการเชื่อมต่อกับ MediaSession
CastPlayer การใช้งาน Player ที่สื่อสารกับการแคสต์ แอปตัวรับสัญญาณ ลักษณะการทำงานจะขึ้นอยู่กับเซสชันการแคสต์ที่เกี่ยวข้อง

แม้ว่า 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 ดูเอกสารประกอบของ 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 การเปลี่ยนแปลงสถานะ หากคุณต้องการทริกเกอร์การอัปเดตสถานะด้วยตนเอง โทรหา invalidateState()

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