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
serangkaian 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 progresif dan adaptif
- Dukungan untuk penyisipan iklan sisi klien dan sisi server
- Dukungan untuk pemutaran yang dilindungi DRM
Halaman ini akan memandu Anda melalui beberapa langkah penting dalam membangun aplikasi pemutaran, dan untuk mengetahui detail selengkapnya, Anda dapat membuka panduan lengkap kami tentang Media3 ExoPlayer.
Memulai
Untuk memulai, tambahkan dependensi pada modul ExoPlayer, UI, dan Common dari Jetpack Media3:
Kotlin
implementation("androidx.media3:media3-exoplayer:1.11.1")
implementation("androidx.media3:media3-ui:1.11.1")
implementation("androidx.media3:media3-common:1.11.1")
Groovy
implementation "androidx.media3:media3-exoplayer:1.11.1"
implementation "androidx.media3:media3-ui:1.11.1"
implementation "androidx.media3:media3-common:1.11.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.11.1 dengan versi library pilihan Anda. Anda dapat melihat catatan rilis untuk mengetahui versi terbaru.
Membuat pemutar media
Dengan Media3, Anda dapat menggunakan implementasi antarmuka Player, ExoPlayer, atau membuat implementasi kustom Anda sendiri.
Membuat ExoPlayer
Cara termudah 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 dalam metode siklus proses onCreate() dari
Activity, Fragment, atau Service tempatnya 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 pemutar Anda berada dalam Activity atau Fragment, ini berarti menyiapkan pemutar dalam metode siklus proses onStart() pada level API 24 dan yang lebih tinggi atau metode siklus proses onResume() pada level API 23 dan yang lebih rendah. Untuk pemutar yang berada di Service,
Anda dapat menyiapkannya di onCreate(). Lihat codelab Exoplayer untuk mengetahui
contoh cara menerapkan metode siklus proses.
Mengontrol pemutar
Setelah pemutar disiapkan, Anda dapat mengontrol pemutaran dengan memanggil metode pada 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 diupdate
sesuai dengan itu saat terikat ke pemutar.
Lepaskan pemain
Pemutaran dapat memerlukan resource yang persediaannya terbatas, seperti dekoder video, jadi penting untuk memanggil release() di pemutar Anda untuk mengosongkan resource saat pemutar tidak lagi diperlukan.
Jika pemutar Anda berada dalam Activity atau Fragment, rilis pemutar dalam
metode siklus proses onStop() pada level API 24 dan yang lebih tinggi atau metode onPause()
pada level API 23 dan yang lebih rendah. Untuk pemain yang berada di Service, Anda dapat merilisnya
di onDestroy(). Lihat codelab Exoplayer untuk mengetahui contoh cara
mengimplementasikan metode siklus proses.
Mengelola pemutaran dengan sesi media
Di Android, sesi media menyediakan cara standar untuk berinteraksi dengan pemutar media di seluruh batas proses. Menghubungkan sesi media ke pemutar memungkinkan Anda memberitahukan pemutaran media secara eksternal dan menerima perintah pemutaran dari sumber eksternal, misalnya untuk berintegrasi dengan kontrol media sistem di perangkat seluler dan perangkat layar besar.
Untuk menggunakan sesi media, tambahkan dependensi pada modul Sesi Media3:
Kotlin
implementation("androidx.media3:media3-session:1.11.1")
Groovy
implementation "androidx.media3:media3-session:1.11.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. Hal ini berfungsi dengan implementasi Player apa pun, termasuk
ExoPlayer, CastPlayer, atau implementasi kustom.
Memberikan kontrol kepada klien lain
Aplikasi klien dapat mengimplementasikan pengontrol media untuk mengontrol pemutaran sesi media Anda. Untuk menerima permintaan ini, tetapkan objek callback saat membuat
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 pemutar. Perintah pemutaran dan playlist
yang ditentukan dalam 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.
Menerapkan 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, deklarasikan 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 Anda berada di Service yang terpisah dari Activity atau
Fragment tempat UI pemutar berada, Anda dapat menggunakan MediaController untuk menautkannya. Dalam metode onStart() dari Activity atau Fragment dengan
UI Anda, buat SessionToken untuk MediaSession, lalu gunakan
SessionToken untuk membuat 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 mengimplementasikan antarmuka Player, sehingga Anda dapat menggunakan metode yang sama seperti play() dan pause() untuk mengontrol pemutaran. Serupa dengan komponen
lainnya, jangan lupa untuk merilis MediaController saat tidak lagi
diperlukan dalam metode siklus proses onStop() dari Activity, dengan memanggil
MediaController.releaseFuture().
Memublikasikan notifikasi
Layanan latar depan harus 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 ke
MediaSession Anda dengan setMediaNotificationProvider.
Mengiklankan koleksi konten Anda
MediaLibraryService dibuat berdasarkan MediaSessionService dengan mengizinkan aplikasi
klien menjelajahi konten media yang disediakan oleh aplikasi Anda. Aplikasi klien mengimplementasikan
MediaBrowser untuk berinteraksi dengan MediaLibraryService Anda.
Mengimplementasikan MediaLibraryService mirip dengan mengimplementasikan
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 Anda 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. Filter intent tambahan memungkinkan aplikasi klien yang menggunakan MediaBrowserCompat API mengenali Service Anda.
MediaLibrarySession memungkinkan Anda menyajikan library konten dalam struktur hierarki,
dengan satu root MediaItem. Setiap MediaItem dalam hierarki dapat memiliki berapa pun
node MediaItem turunan. Anda dapat menyajikan root yang berbeda, atau hierarki yang berbeda, berdasarkan permintaan aplikasi klien. Misalnya, hierarki yang Anda tampilkan ke
klien yang mencari daftar item media yang direkomendasikan mungkin hanya berisi root
MediaItem dan satu tingkat node MediaItem turunan, sedangkan hierarki
yang Anda tampilkan ke aplikasi klien lain mungkin 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()saat klien meminta rootMediaItemdari hierarki kontenonGetChildren()saat klien meminta turunanMediaItemdi hierarki kontenonGetSearchResult()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.