Mengontrol dan mengiklankan pemutaran menggunakan MediaSession

Sesi media menyediakan cara universal untuk berinteraksi dengan pemutar audio atau video. Di Media3, pemutar default adalah class ExoPlayer, yang mengimplementasikan antarmuka Player. Menghubungkan sesi media ke pemutar memungkinkan aplikasi mengiklankan pemutaran media secara eksternal dan menerima perintah pemutaran dari sumber eksternal.

Perintah dapat berasal dari tombol fisik seperti tombol putar di headset atau remote control TV. Perintah ini juga dapat berasal dari aplikasi klien yang memiliki pengontrol media, seperti menginstruksikan "jeda" ke Asisten Google. Sesi media mendelegasikan perintah ini ke pemutar aplikasi media.

Kapan harus memilih sesi media

Saat menerapkan MediaSession, Anda mengizinkan pengguna mengontrol pemutaran:

  • Melalui headphone mereka. Sering kali ada tombol atau interaksi sentuh yang dapat dilakukan pengguna di headphone untuk memutar atau menjeda media atau beralih ke trek berikutnya atau sebelumnya.
  • Dengan berbicara kepada Asisten Google. Pola umum adalah mengucapkan "OK Google, jeda" untuk menjeda media apa pun yang sedang diputar di perangkat.
  • Melalui smartwatch Wear OS. Hal ini memungkinkan akses yang lebih mudah ke kontrol pemutaran yang paling umum saat memutar di ponsel.
  • Melalui Kontrol media. Carousel ini menampilkan kontrol untuk setiap sesi media yang sedang berjalan.
  • Di TV. Memungkinkan tindakan dengan tombol pemutaran fisik, kontrol pemutaran platform, dan pengelolaan daya (misalnya, jika TV, soundbar, atau penerima A/V dimatikan atau input dialihkan, pemutaran harus berhenti di aplikasi).
  • Melalui kontrol media Android Auto. Hal ini memungkinkan kontrol pemutaran yang aman saat mengemudi.
  • Dan proses eksternal lainnya yang perlu memengaruhi pemutaran.

Hal ini sangat berguna untuk banyak kasus penggunaan. Khususnya, sebaiknya Anda mempertimbangkan untuk menggunakan MediaSession jika:

  • Anda melakukan streaming konten video panjang, seperti film atau TV live.
  • Anda melakukan streaming konten audio panjang, seperti podcast atau playlist musik.
  • Anda sedang membuat aplikasi TV.

Namun, tidak semua kasus penggunaan cocok dengan MediaSession. Anda mungkin ingin menggunakan Player saja dalam kasus berikut:

  • Anda menampilkan konten berdurasi pendek, yang tidak memerlukan kontrol eksternal atau pemutaran di latar belakang.
  • Tidak ada satu video aktif, seperti pengguna men-scroll daftar dan beberapa video ditampilkan di layar secara bersamaan.
  • Anda memutar video pengantar atau penjelasan satu kali, yang Anda harapkan ditonton secara aktif oleh pengguna tanpa memerlukan kontrol pemutaran eksternal.
  • Konten Anda sensitif terhadap privasi dan Anda tidak ingin proses eksternal mengakses metadata media (misalnya, mode samaran di browser).

Jika kasus penggunaan Anda tidak sesuai dengan salah satu yang tercantum di atas, pertimbangkan apakah Anda bersedia aplikasi Anda melanjutkan pemutaran saat pengguna tidak berinteraksi secara aktif dengan konten. Jika jawabannya ya, Anda mungkin ingin memilih MediaSession. Jika jawabannya tidak, sebaiknya gunakan Player.

Membuat sesi media

Sesi media berdampingan dengan pemutar yang dikelolanya. Anda dapat membuat sesi media dengan objek Context dan Player. Anda harus membuat dan menginisialisasi sesi media saat diperlukan, seperti metode siklus proses onStart() atau onResume() dari Activity atau Fragment, atau metode onCreate() dari Service yang memiliki sesi media dan pemutar terkaitnya.

Untuk membuat sesi media, inisialisasi Player dan berikan ke MediaSession.Builder seperti ini:

Kotlin

val player = ExoPlayer.Builder(context).build()
val mediaSession = MediaSession.Builder(context, player).build()

Java

ExoPlayer player = new ExoPlayer.Builder(context).build();
MediaSession mediaSession = new MediaSession.Builder(context, player).build();

Penanganan status otomatis

Library Media3 otomatis mengupdate sesi media menggunakan status pemutar. Dengan demikian, Anda tidak perlu menangani pemetaan dari pemain ke sesi secara manual.

Hal ini berbeda dengan sesi media platform tempat Anda perlu membuat dan mempertahankan PlaybackState secara terpisah dari pemutar itu sendiri, misalnya untuk menunjukkan error.

ID sesi unik

Secara default, MediaSession.Builder membuat sesi dengan string kosong sebagai ID sesi. Hal ini sudah cukup jika aplikasi hanya ingin membuat satu instance sesi, yang merupakan kasus paling umum.

Jika ingin mengelola beberapa instance sesi secara bersamaan, aplikasi harus memastikan bahwa ID sesi setiap sesi unik. ID sesi dapat ditetapkan saat membangun sesi dengan MediaSession.Builder.setId(String id).

Jika Anda melihat IllegalStateException menyebabkan aplikasi Anda error dengan pesan error IllegalStateException: Session ID must be unique. ID=, kemungkinan sesi telah dibuat secara tidak terduga sebelum instance yang dibuat sebelumnya dengan ID yang sama dilepaskan. Untuk menghindari kebocoran sesi akibat error pemrograman, kasus tersebut akan dideteksi dan diberi tahu dengan memunculkan pengecualian.

Memberikan kontrol kepada klien lain

Sesi media adalah kunci untuk mengontrol pemutaran. Hal ini memungkinkan Anda merutekan perintah dari sumber eksternal ke pemutar yang melakukan tugas memutar media Anda. Sumber ini dapat berupa tombol fisik seperti tombol putar di headset atau remote control TV, atau perintah tidak langsung seperti menginstruksikan "jeda" ke Asisten Google. Demikian pula, Anda dapat memberikan akses ke sistem Android untuk memfasilitasi kontrol notifikasi dan layar kunci, atau ke smartwatch Wear OS agar Anda dapat mengontrol pemutaran dari tampilan jam. Klien eksternal dapat menggunakan pengontrol media untuk mengeluarkan perintah pemutaran ke aplikasi media Anda. Perintah ini diterima oleh sesi media Anda, yang pada akhirnya mendelegasikan perintah ke pemutar media.

Diagram yang menunjukkan interaksi antara MediaSession dan MediaController.
Gambar 1: Pengontrol media memfasilitasi penerusan perintah dari sumber eksternal ke sesi media.

Saat pengontrol akan terhubung ke sesi media Anda, metode onConnect() akan dipanggil. Anda dapat menggunakan ControllerInfo yang diberikan untuk memutuskan apakah akan menerima