Menghubungkan ke aplikasi media

Pengontrol media berinteraksi dengan sesi media untuk mengkueri dan mengontrol pemutaran aplikasi media. Di Media3, API MediaController mengimplementasikan antarmuka Player. Contoh aplikasi klien yang menggunakan pengontrol media meliputi:

Pengontrol media juga dapat berguna dalam aplikasi media, misalnya jika pemutar dan sesi media berada di Service yang terpisah dari Activity atau Fragment dengan UI.

Membuat MediaController

Untuk membuat MediaController, mulailah dengan membuat SessionToken untuk MediaSession yang sesuai. Metode onStart() dari Activity atau Fragment dapat menjadi tempat yang tepat untuk hal ini.

Kotlin

val sessionToken =
  SessionToken(context, ComponentName(context, PlaybackService::class.java))

Java

SessionToken sessionToken =
  new SessionToken(context, new ComponentName(context, PlaybackService.class));

Menggunakan SessionToken ini untuk membangun MediaController kemudian menghubungkan pengontrol ke sesi yang diberikan. Tindakan ini dilakukan secara asinkron, jadi Anda harus memantau hasilnya dan menggunakannya saat tersedia.

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());

Gunakan MediaController

MediaController mengimplementasikan antarmuka Player, sehingga Anda dapat menggunakan perintah yang ditentukan dalam antarmuka untuk mengontrol pemutaran MediaSession yang terhubung. Artinya, memanggil play() pada MediaController akan mengirimkan perintah ke MediaSession yang terhubung, yang selanjutnya akan mendelegasikan perintah ke Player yang mendasarinya.

Anda dapat menambahkan Player.Listener ke pengontrol untuk memproses perubahan status Player. Lihat panduan Peristiwa pemain untuk mengetahui detail selengkapnya tentang penggunaan Player.Listener.

Antarmuka MediaController.Listener menentukan callback tambahan untuk peristiwa dan perintah kustom dari MediaSession yang terhubung. Contohnya adalah onCustomCommand() saat sesi mengirim perintah kustom, onAvailableSessionCommandsChanged() saat sesi mengubah perintah sesi yang tersedia, atau onDisconnected() saat pengontrol terputus dari sesi.

MediaController.Listener dapat ditetapkan saat membuat pengontrol dengan Builder:

Kotlin

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

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();

Seperti komponen lainnya, jangan lupa untuk melepaskan MediaController saat tidak lagi diperlukan, seperti dalam metode onStop() dari Activity atau Fragment.

Kotlin

MediaController.releaseFuture(controllerFuture)

Java

MediaController.releaseFuture(controllerFuture);

Melepaskan pengontrol akan tetap mengirimkan semua perintah tertunda yang dikirim ke sesi dan hanya melepaskan ikatan dari layanan sesi setelah perintah ini ditangani atau setelah periode waktu tunggu, mana saja yang terjadi lebih dulu.

Membuat dan menggunakan MediaBrowser

MediaBrowser dibuat berdasarkan kemampuan yang ditawarkan oleh MediaController untuk juga memungkinkan penjelajahan koleksi media yang ditawarkan oleh MediaLibraryService aplikasi media.

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());

Untuk mulai menjelajahi library konten aplikasi media, ambil terlebih dahulu node root dengan 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());

Kemudian, Anda dapat menjelajahi koleksi media dengan mengambil turunan MediaItem dalam koleksi dengan getChildren(). Misalnya, untuk mengambil turunan dari node root 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());

Menampilkan kontrol pemutaran untuk aplikasi media lain

Saat menampilkan kontrol UI dengan tombol untuk aplikasi media lain, penting untuk mengikuti preferensi tombol media yang dinyatakan dari aplikasi tersebut.

Cara terbaik untuk menyelesaikan preferensi aplikasi serta batasan dan persyaratan UI Anda adalah dengan menggunakan CommandButton.DisplayConstraints. Anda dapat menentukan batas dan batasan yang dapat dilakukan UI Anda, dan metode resolve memberikan daftar tombol yang pasti untuk ditampilkan dengan ikon, posisi, dan tindakan yang dimaksud.