การเชื่อมต่อกับแอปสื่อทำได้ 2 วิธีดังนี้
MediaControllerMediaBrowser
MediaController
ตัวควบคุมสื่อจะโต้ตอบกับเซสชันสื่อเพื่อค้นหาและควบคุมการเล่นของแอปสื่อ
ใน Media3 นั้น MediaController
API จะใช้Playerอินเทอร์เฟซ ตัวอย่างแอปไคลเอ็นต์ที่ใช้ตัวควบคุมสื่อมีดังนี้
- การควบคุมสื่อของระบบ Android
- แอปที่ใช้ร่วมกับ Android Wear OS
- Android Auto และ Automotive OS
- ผู้ช่วยแบบเสียง เช่น Google Assistant
- แอปทดสอบตัวควบคุมสื่อ
ตัวควบคุมสื่อยังมีประโยชน์ภายในแอปสื่อด้วย เช่น หากเพลเยอร์และเซสชันสื่ออยู่ใน Service แยกจาก Activity หรือ Fragment ที่มี UI
สร้าง MediaController
หากต้องการสร้าง MediaController ให้เริ่มด้วยการสร้าง SessionToken สำหรับ MediaSession ที่เกี่ยวข้อง onStart() วิธีการของActivityหรือ
Fragmentอาจเป็นจุดเริ่มต้นที่ดี
Kotlin
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
การใช้ SessionToken นี้เพื่อสร้าง MediaController จะเชื่อมต่อ
คอนโทรลเลอร์กับเซสชันที่กำหนด การดำเนินการนี้จะเกิดขึ้นแบบไม่พร้อมกัน ดังนั้นคุณควร
รอฟังผลลัพธ์และใช้เมื่อพร้อมใช้งาน
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync() controllerFuture.addListener( { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor(), )
Java
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken).buildAsync(); controllerFuture.addListener( () -> { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor());
ใช้ MediaController
MediaController ใช้อินเทอร์เฟซ Player คุณจึงสามารถใช้คำสั่งที่กำหนดไว้ในอินเทอร์เฟซเพื่อควบคุมการเล่นของ MediaSession ที่เชื่อมต่อ
ซึ่งหมายความว่าการเรียกใช้ play() ใน MediaController จะส่งคำสั่งไปยัง MediaSession ที่เชื่อมต่ออยู่ ซึ่งจากนั้นจะส่งต่อคำสั่งไปยัง Player ที่อยู่เบื้องหลัง
คุณเพิ่ม Player.Listener ลงในตัวควบคุมเพื่อฟังการเปลี่ยนแปลงในสถานะ Player ได้ ดูรายละเอียดเพิ่มเติมเกี่ยวกับการใช้
Player.Listenerได้ในคู่มือเหตุการณ์ของผู้เล่น
อินเทอร์เฟซ MediaController.Listener จะกําหนดการเรียกกลับเพิ่มเติมสําหรับเหตุการณ์และคําสั่งที่กําหนดเองจาก MediaSession ที่เชื่อมต่อ ตัวอย่างเช่น
onCustomCommand() เมื่อเซสชันส่งคำสั่งที่กำหนดเอง
onAvailableSessionCommandsChanged() เมื่อเซสชันเปลี่ยนคำสั่งเซสชันที่ใช้ได้
หรือ onDisconnected() เมื่อตัวควบคุมถูกตัดการเชื่อมต่อ
จากเซสชัน
คุณตั้งค่า MediaController.Listener ได้เมื่อสร้างตัวควบคุมด้วย
Builder
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken) .setListener( object : MediaController.Listener { override fun onCustomCommand( controller: MediaController, command: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { // Handle custom command. return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } override fun onDisconnected(controller: MediaController) { // Handle disconnection. } } ) .buildAsync()
Java
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken) .setListener( new MediaController.Listener() { @Override public ListenableFuture<SessionResult> onCustomCommand( MediaController controller, SessionCommand command, Bundle args) { // Handle custom command. return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); } @Override public void onDisconnected(MediaController controller) { // Handle disconnection. } }) .buildAsync();
เช่นเดียวกับคอมโพเนนต์อื่นๆ อย่าลืมปล่อย MediaController เมื่อไม่จำเป็นต้องใช้แล้ว
เช่น ในเมธอด onStop() ของ Activity หรือ Fragment
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
การปล่อยตัวควบคุมจะยังคงส่งคำสั่งที่รอดำเนินการทั้งหมดไปยังเซสชัน และจะยกเลิกการเชื่อมโยงจากบริการเซสชันเมื่อระบบจัดการคำสั่งเหล่านี้แล้วหรือหลังจากระยะหมดเวลา แล้วแต่ว่ากรณีใดจะเกิดขึ้นก่อน
MediaBrowser
MediaBrowser สร้างขึ้นจากความสามารถที่MediaController มอบให้เพื่อเปิดใช้การเรียกดูคลังสื่อที่MediaLibraryService ของแอปสื่อนำเสนอด้วย
สร้าง MediaBrowser
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync() browserFuture.addListener( { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor(), )
Java
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken).buildAsync(); browserFuture.addListener( () -> { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor());
ใช้ MediaBrowser
หากต้องการเริ่มเรียกดูคลังเนื้อหาของแอปสื่อ ให้เรียกข้อมูลโหนดรูทก่อน
ด้วย getLibraryRoot():
Kotlin
// Get the library root to start browsing the library tree. val rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null) rootFuture.addListener( { // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor(), )
Java
// Get the library root to start browsing the library tree. ListenableFuture<LibraryResult<MediaItem>> rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null); rootFuture.addListener( () -> { // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor());
จากนั้นคุณจะไปยังส่วนต่างๆ ของคลังสื่อได้โดยการดึงข้อมูลรายการย่อยของ
MediaItem ในคลังด้วย getChildren() เช่น หากต้องการดึงข้อมูล
ลูกของโหนดรูท MediaItem ให้ทำดังนี้
Kotlin
// Get the library root to start browsing the library tree. val childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Int.MAX_VALUE, null) childrenFuture.addListener( { // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor(), )
Java
ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Integer.MAX_VALUE, null); childrenFuture.addListener( () -> { // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor());
แสดงตัวควบคุมการเล่นสำหรับแอปสื่ออื่น
เมื่อแสดงตัวควบคุม UI พร้อมปุ่มสำหรับแอปสื่ออื่น คุณต้องทำตามค่ากำหนดของปุ่มสื่อที่ประกาศไว้ของแอปนั้น
หากต้องการแก้ไขค่ากำหนดของแอปตามข้อจำกัดและข้อกำหนดของ UI ให้ใช้ CommandButton.DisplayConstraints คุณสามารถกำหนดขีดจำกัดและข้อจำกัดของสิ่งที่ UI ทำได้ และเมธอด resolve
จะแสดงรายการปุ่มที่แน่นอนเพื่อแสดงพร้อมไอคอน ตำแหน่ง และ
การดำเนินการที่ต้องการ หากผู้ใช้คลิกปุ่มใดปุ่มหนึ่งเหล่านี้ คุณสามารถใช้
CommandButton.executeAction เพื่อทริกเกอร์การดำเนินการที่เกี่ยวข้องในแอปสื่อ
Kotlin
// Get media button preferences from media app val mediaButtonPreferences = controller.getMediaButtonPreferences() // Declare constraints of UI (example: limit overflow button to one) val displayConstraints = DisplayConstraints.Builder().setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1).build() // Resolve media app preferences with constraints val resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller) // Display buttons in UI for (button in resolvedButtons) { generateUiButton( uiPosition = button.slots[0], icon = getIconRes(button.icon), onClick = { button.executeAction(controller) }, ) }
Java
// Get media button preferences from media app List<CommandButton> mediaButtonPreferences = controller.getMediaButtonPreferences(); // Declare constraints of UI (example: limit overflow button to one) DisplayConstraints displayConstraints = new DisplayConstraints.Builder() .setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1) .build(); // Resolve media app preferences with constraints List<CommandButton> resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller); // Display buttons in UI for (CommandButton button : resolvedButtons) { generateUiButton( /* uiPosition= */ button.slots.get(0), /* icon= */ getIconRes(button.icon), /* onClick= */ () -> button.executeAction(controller)); }