Jetpack Media3 menentukan antarmuka Player
yang menguraikan fungsi dasar
untuk pemutaran file video dan audio. ExoPlayer
adalah implementasi default
antarmuka ini di Media3. Sebaiknya gunakan ExoPlayer karena menyediakan
kumpulan fitur komprehensif yang mencakup sebagian besar kasus penggunaan pemutaran dan
dapat disesuaikan untuk menangani kasus penggunaan tambahan yang mungkin Anda miliki. ExoPlayer juga
mengabstraksi fragmentasi perangkat dan OS sehingga kode Anda berfungsi secara konsisten
di seluruh ekosistem Android. ExoPlayer mencakup:
- Dukungan untuk playlist
- Dukungan untuk berbagai format streaming adaptif dan progresif
- Dukungan untuk penyisipan iklan sisi klien dan sisi server
- Dukungan untuk pemutaran yang dilindungi DRM
Halaman ini memandu Anda melalui beberapa langkah utama dalam mem-build aplikasi pemutaran, dan untuk mengetahui detail selengkapnya, Anda dapat membuka panduan lengkap kami tentang Media3 ExoPlayer.
Memulai
Untuk memulai, tambahkan dependensi pada ExoPlayer, UI, dan modul Umum Jetpack Media3:
implementation "androidx.media3:media3-exoplayer:1.4.1" implementation "androidx.media3:media3-ui:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
Bergantung pada kasus penggunaan, Anda mungkin juga memerlukan modul tambahan dari Media3,
seperti exoplayer-dash
untuk memutar streaming dalam format DASH.
Pastikan untuk mengganti 1.4.1
dengan versi library
yang Anda inginkan. Anda dapat melihat catatan rilis
untuk melihat versi terbaru.
Membuat pemutar media
Dengan Media3, Anda dapat menggunakan implementasi antarmuka Player
yang disertakan, ExoPlayer
, atau Anda dapat membuat implementasi kustom Anda sendiri.
Membuat ExoPlayer
Cara paling sederhana untuk membuat instance ExoPlayer
adalah sebagai berikut:
Kotlin
val player = ExoPlayer.Builder(context).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build();
Anda dapat membuat pemutar media di metode siklus proses onCreate()
dari
Activity
, Fragment
, atau Service
tempat pemutar media berada.
Builder
mencakup
berbagai opsi penyesuaian yang mungkin Anda minati, seperti:
setAudioAttributes()
untuk mengonfigurasi penanganan fokus audiosetHandleAudioBecomingNoisy()
untuk mengonfigurasi perilaku pemutaran saat perangkat output audio terputussetTrackSelector()
untuk mengonfigurasi pemilihan trek
Media3 menyediakan komponen UI PlayerView
yang dapat Anda sertakan dalam file
tata letak aplikasi. Komponen ini mengenkapsulasi PlayerControlView
untuk kontrol
pemutaran, SubtitleView
untuk menampilkan subtitel, dan Surface
untuk merender
video.
Menyiapkan pemutar
Tambahkan item media ke playlist untuk
diputar dengan metode seperti
setMediaItem()
dan addMediaItem()
.
Kemudian, panggil prepare()
untuk
mulai memuat media dan mendapatkan resource yang diperlukan.
Anda tidak boleh melakukan langkah-langkah ini sebelum aplikasi berada di latar depan. Jika
pemain Anda berada di Activity
atau Fragment
, ini berarti menyiapkan pemain dalam
metode siklus proses onStart()
di API level 24 dan yang lebih tinggi atau metode siklus proses
onResume()
di API level 23 dan yang lebih rendah. Untuk pemain yang berada di Service
,
Anda dapat menyiapkannya di onCreate()
.
Mengontrol pemutar
Setelah pemutar disiapkan, Anda dapat mengontrol pemutaran dengan memanggil metode di pemutar seperti:
play()
danpause()
untuk memulai dan menjeda pemutaranseekTo()
untuk mencari posisi dalam item media saat iniseekToNextMediaItem()
danseekToPreviousMediaItem()
untuk menjelajahi playlist
Komponen UI seperti PlayerView
atau PlayerControlView
akan diperbarui
sesuai saat terikat dengan pemain.
Merilis pemutar
Pemutaran dapat memerlukan resource yang jumlahnya terbatas, seperti decoder
video, sehingga Anda harus memanggil release()
di pemutar untuk mengosongkan resource saat pemutar tidak lagi diperlukan.
Jika pemain Anda menggunakan Activity
atau Fragment
, rilis pemain dalam
metode siklus proses onStop()
pada API level 24 dan yang lebih tinggi atau metode onPause()
pada API level 23 dan yang lebih lama. Untuk pemain yang berada di Service
, Anda dapat
merilisnya di onDestroy()
.
Mengelola pemutaran dengan sesi media
Di Android, sesi media menyediakan cara standar untuk berinteraksi dengan pemutar media di seluruh batas proses. Dengan menghubungkan sesi media ke pemutar, Anda dapat mengiklankan pemutaran media secara eksternal dan menerima perintah pemutaran dari sumber eksternal, misalnya untuk berintegrasi dengan kontrol media sistem di perangkat seluler dan layar besar.
Untuk menggunakan sesi media, tambahkan dependensi pada modul Sesi Media3:
implementation "androidx.media3:media3-session:1.4.1"
Membuat sesi media
Anda dapat membuat MediaSession
setelah melakukan inisialisasi pemutar sebagai berikut:
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();
Media3 otomatis menyinkronkan status Player
dengan status
MediaSession
. Ini berfungsi dengan implementasi Player
apa pun, termasuk
ExoPlayer
, CastPlayer
, atau
penerapan kustom.
Memberikan kontrol kepada klien lain
Aplikasi klien dapat menerapkan pengontrol media
untuk mengontrol pemutaran sesi media Anda. Untuk menerima permintaan ini, tetapkan objek callback saat mem-build MediaSession
.
Saat pengontrol akan terhubung ke sesi media Anda, metode
onConnect()
akan dipanggil. Anda dapat menggunakan ControllerInfo
yang disediakan untuk memutuskan apakah akan menerima
atau menolak
permintaan. Lihat contohnya di aplikasi demo Sesi Media3.
Setelah terhubung, pengontrol dapat mengirim perintah pemutaran ke sesi. Sesi
kemudian mendelegasikan perintah tersebut ke pemain. Perintah pemutaran dan playlist
yang ditentukan di antarmuka Player
akan otomatis ditangani oleh
sesi.
Metode callback lainnya memungkinkan Anda menangani, misalnya, permintaan untuk
perintah pemutaran kustom
dan mengubah playlist. Callback ini juga menyertakan objek ControllerInfo
sehingga Anda
dapat menentukan kontrol akses berdasarkan permintaan.
Memutar media di latar belakang
Untuk terus memutar media saat aplikasi Anda tidak berada di latar depan, misalnya
untuk memutar musik, buku audio, atau podcast meskipun pengguna tidak membuka
aplikasi Anda, Player
dan MediaSession
harus dienkapsulasi dalam
layanan latar depan. Media3 menyediakan
antarmuka MediaSessionService
untuk tujuan ini.
Mengimplementasikan MediaSessionService
Buat class yang memperluas MediaSessionService
dan buat instance
MediaSession
Anda dalam metode siklus proses onCreate()
.
Kotlin
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your Player and MediaSession in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
Java
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player).build(); } @Override public void onDestroy() { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; super.onDestroy(); } }
Dalam manifes, class Service
Anda dengan filter intent
MediaSessionService
dan minta izin FOREGROUND_SERVICE
untuk menjalankan layanan
latar depan:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Terakhir, di class yang Anda buat, ganti metode onGetSession()
untuk mengontrol
akses klien ke sesi media Anda. Tampilkan MediaSession
untuk menerima
permintaan koneksi, atau tampilkan null
untuk menolak permintaan.
Kotlin
// This example always accepts the connection request override fun onGetSession( controllerInfo: MediaSession.ControllerInfo ): MediaSession? = mediaSession
Java
@Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
Menghubungkan ke UI Anda
Setelah sesi media berada di Service
yang terpisah dari Activity
atau
Fragment
tempat UI pemutar berada, Anda dapat menggunakan MediaController
untuk menautkan
kedua elemen tersebut. Dalam metode onStart()
dari Activity
atau Fragment
dengan
UI, buat SessionToken
untuk MediaSession
, lalu gunakan SessionToken
untuk mem-build MediaController
. Pembuatan MediaController
terjadi secara asinkron.
Kotlin
override fun onStart() { val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java)) val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync() controllerFuture.addListener( { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()) }, MoreExecutors.directExecutor() ) }
Java
@Override public void onStart() { SessionToken sessionToken = new SessionToken(this, new ComponentName(this, PlaybackService.class)); ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(this, sessionToken).buildAsync(); controllerFuture.addListener(() -> { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()); }, MoreExecutors.directExecutor()) }
MediaController
menerapkan antarmuka Player
sehingga Anda dapat menggunakan metode
yang sama seperti play()
dan pause()
untuk mengontrol pemutaran. Serupa dengan komponen
lainnya, jangan lupa merilis MediaController
jika tidak
diperlukan lagi, seperti metode siklus proses onStop()
dari Activity
, dengan memanggil
MediaController.releaseFuture()
.
Memublikasikan notifikasi
Layanan latar depan diwajibkan untuk memublikasikan notifikasi saat aktif. MediaSessionService
akan otomatis membuat
notifikasi MediaStyle
untuk
Anda dalam bentuk MediaNotification
.
Untuk memberikan notifikasi kustom, buat
MediaNotification.Provider
dengan DefaultMediaNotificationProvider.Builder
atau dengan membuat implementasi kustom antarmuka penyedia. Tambahkan
penyedia Anda ke MediaSession
dengan
setMediaNotificationProvider
.
Mengiklankan koleksi konten Anda
MediaLibraryService
di-build di MediaSessionService
dengan memungkinkan aplikasi
klien menjelajahi konten media yang disediakan oleh aplikasi Anda. Aplikasi klien mengimplementasikan
MediaBrowser
untuk berinteraksi
dengan MediaLibraryService
Anda.
Menerapkan MediaLibraryService
mirip dengan menerapkan
MediaSessionService
, kecuali bahwa di onGetSession()
Anda harus menampilkan
MediaLibrarySession
, bukan MediaSession
. Dibandingkan dengan
MediaSession.Callback
, MediaLibrarySession.Callback
menyertakan metode
tambahan yang memungkinkan klien browser menavigasi konten yang ditawarkan oleh
layanan library Anda.
Serupa dengan MediaSessionService
, deklarasikan MediaLibraryService
dalam
manifes dan minta izin FOREGROUND_SERVICE
untuk menjalankan layanan
latar depan:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Contoh di atas menyertakan filter intent untuk MediaLibraryService
dan, untuk kompatibilitas mundur, MediaBrowserService
lama. Pemfilteran
intent tambahan memungkinkan aplikasi klien yang menggunakan MediaBrowserCompat
API
untuk mengenali Service
Anda.
MediaLibrarySession
memungkinkan Anda menayangkan library konten dalam struktur
hierarki, dengan satu MediaItem
root. Setiap MediaItem
dalam hierarki dapat memiliki
berapa pun jumlah node MediaItem
turunan. Anda dapat menayangkan root yang berbeda, atau
hierarki yang berbeda, berdasarkan permintaan aplikasi klien. Misalnya, hierarki yang Anda
kembalikan ke klien yang mencari daftar item media yang direkomendasikan mungkin hanya
berisi MediaItem
root dan satu level node MediaItem
turunan,
sedangkan hierarki yang Anda kembalikan ke aplikasi klien yang berbeda dapat mewakili library
konten yang lebih lengkap.
Membuat MediaLibrarySession
MediaLibrarySession
memperluas MediaSession
API untuk menambahkan API penjelajahan konten. Dibandingkan dengan
callback MediaSession
,
callback MediaLibrarySession
menambahkan metode seperti:
onGetLibraryRoot()
untuk saat klien memintaMediaItem
root hierarki kontenonGetChildren()
untuk saat klien meminta turunanMediaItem
dalam hierarki kontenonGetSearchResult()
untuk saat klien meminta hasil penelusuran dari hierarki konten untuk kueri tertentu
Metode callback yang relevan akan menyertakan objek LibraryParams
dengan sinyal tambahan tentang jenis hierarki konten yang diminati
aplikasi klien.