Aplikasi yang saat ini menggunakan com.google.android.exoplayer2
library dan androidx.media harus bermigrasi ke androidx.media3. Gunakan
skrip migrasi untuk memigrasikan file build gradle, file sumber Java dan
Kotlin, serta file tata letak XML dari ExoPlayer
2.19.1 ke AndroidX Media3 1.1.1.
Ringkasan
Sebelum bermigrasi, tinjau bagian berikut untuk mempelajari lebih lanjut manfaat API baru, API yang akan dimigrasikan, dan prasyarat yang harus dipenuhi project aplikasi Anda.
Alasan bermigrasi ke Jetpack Media3
- Ini adalah tempat baru ExoPlayer, sedangkan
com.google.android.exoplayer2tidak lagi digunakan. - Akses Player API di seluruh komponen/proses dengan
MediaBrowser/MediaController. - Gunakan kemampuan yang diperluas dari
MediaSessiondanMediaControllerAPI. - Iklankan kemampuan pemutaran dengan kontrol akses yang sangat terperinci.
- Sederhanakan aplikasi Anda dengan menghapus
MediaSessionConnectordanPlayerNotificationManager. - Kompatibel dengan versi lama dengan API klien media-compat (
MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)
API Media yang akan dimigrasikan ke AndroidX Media3
- ExoPlayer dan ekstensi
Hal ini mencakup semua modul project ExoPlayer lama, kecuali modul mediasession yang tidak lagi digunakan. Aplikasi atau modul yang bergantung pada paket dicom.google.android.exoplayer2dapat dimigrasikan dengan skrip migrasi. - MediaSessionConnector (bergantung pada paket
androidx.media.*dariandroidx.media:media:1.4.3+)
HapusMediaSessionConnectordan gunakanandroidx.media3.session.MediaSessionsebagai gantinya. - MediaBrowserServiceCompat (bergantung pada paket
androidx.media.*dariandroidx.media:media:1.4.3+)
Migrasikan subclassandroidx.media.MediaBrowserServiceCompatkeandroidx.media3.session.MediaLibraryServicedan kode yang menggunakanMediaBrowserCompat.MediaItemkeandroidx.media3.common.MediaItem. - MediaBrowserCompat (bergantung pada paket
android.support.v4.media.*dariandroidx.media:media:1.4.3+)
Migrasikan kode klien yang menggunakanMediaBrowserCompatatauMediaControllerCompatuntuk menggunakanandroidx.media3.session.MediaBrowserdenganandroidx.media3.common.MediaItem.
Prasyarat
Pastikan project Anda berada di bawah kontrol sumber
Pastikan Anda dapat dengan mudah mengembalikan perubahan yang diterapkan oleh alat migrasi yang dibuat dengan skrip. Jika project Anda belum berada di bawah kontrol sumber, sekarang adalah waktu yang tepat untuk memulainya. Jika karena alasan tertentu Anda tidak ingin melakukannya, buat salinan cadangan project sebelum memulai migrasi.
Mengupdate aplikasi
Sebaiknya update project Anda untuk menggunakan versi terbaru library ExoPlayer dan hapus panggilan ke metode yang tidak digunakan lagi. Jika Anda ingin menggunakan skrip untuk migrasi, Anda harus mencocokkan versi yang Anda update dengan versi yang ditangani oleh skrip.
Tingkatkan compileSdkVersion aplikasi Anda ke minimal 32.
Upgrade Gradle dan plugin Android Studio Gradle ke versi terbaru yang berfungsi dengan dependensi yang diupdate dari atas. Misalnya:
- Versi Plugin Android Gradle: 7.1.0
- Versi Gradle: 7.4
Ganti semua pernyataan impor karakter pengganti yang menggunakan tanda bintang (*) dan gunakan pernyataan impor yang sepenuhnya memenuhi syarat: Hapus pernyataan impor karakter pengganti dan gunakan Android Studio untuk mengimpor pernyataan yang sepenuhnya memenuhi syarat (F2 - Alt/Enter, F2 - Alt/Enter, ...).
Migrasikan dari
com.google.android.exoplayer2.PlayerViewkecom.google.android.exoplayer2.StyledPlayerView. Hal ini diperlukan karena tidak ada yang setara dengancom.google.android.exoplayer2.PlayerViewdi AndroidX Media3.
Memigrasikan ExoPlayer dengan dukungan skrip
Skrip ini memfasilitasi pemindahan dari com.google.android.exoplayer2 ke struktur paket dan modul baru
di bawah androidx.media3. Skrip ini menerapkan beberapa pemeriksaan validasi pada project Anda dan mencetak peringatan jika validasi gagal.
Jika tidak, skrip ini akan menerapkan pemetaan class dan paket yang diganti namanya dalam
resource project gradle Android yang ditulis dalam Java atau Kotlin.
usage: ./media3-migration.sh [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]
PROJECT_ROOT: path to your project root (location of 'gradlew')
-p: list package mappings and then exit
-c: list class mappings (precedence over package mappings) and then exit
-d: list dependency mappings and then exit
-l: list files that will be considered for rewrite and then exit
-x: exclude the path from the list of file to be changed: 'app/src/test'
-m: migrate packages, classes and dependencies to AndroidX Media3
-f: force the action even when validation fails
-v: print the exoplayer2/media3 version strings of this script
-h, --help: show this help text
Menggunakan skrip migrasi
Download skrip migrasi dari tag project ExoPlayer di GitHub yang sesuai dengan versi yang telah Anda update ke aplikasi:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"Setel agar skrip dapat dieksekusi:
chmod 744 media3-migration.shJalankan skrip dengan
--helpuntuk mempelajari opsi.Jalankan skrip dengan
-luntuk mencantumkan kumpulan file yang dipilih untuk migrasi (gunakan-funtuk memaksa listing tanpa peringatan):./media3-migration.sh -l -f /path/to/gradle/project/rootJalankan skrip dengan
-muntuk memetakan paket, class, dan modul ke Media3. Menjalankan skrip dengan opsi-makan menerapkan perubahan pada file yang dipilih.- Berhenti saat terjadi error validasi tanpa melakukan perubahan
./media3-migration.sh -m /path/to/gradle/project/root- Eksekusi paksa
Jika skrip menemukan pelanggaran prasyarat, migrasi dapat dipaksakan dengan tanda
-f:./media3-migration.sh -m -f /path/to/gradle/project/root
# list files selected for migration when excluding paths
./media3-migration.sh -l -x "app/src/test/" -x "service/" /path/to/project/root
# migrate the selected files
./media3-migration.sh -m -x "app/src/test/" -x "service/" /path/to/project/root
Selesaikan langkah-langkah manual ini setelah menjalankan skrip dengan opsi -m:
- Periksa cara skrip mengubah kode Anda: Gunakan alat diff dan perbaiki
potensi masalah (pertimbangkan untuk mengajukan bug jika Anda merasa skrip memiliki
masalah umum yang diperkenalkan tanpa meneruskan opsi
-f). - Build project: Gunakan
./gradlew clean buildatau di Android Studio, pilih File > Sync Project with Gradle Files, lalu Build > Clean project, dan Build > Rebuild project (pantau build Anda di tab 'Build - Build Output' Android Studio).
Langkah-langkah tindak lanjut yang direkomendasikan:
- Selesaikan keikutsertaan untuk error terkait penggunaan API yang tidak stabil.
- Ganti panggilan API yang tidak digunakan lagi: Gunakan API pengganti yang disarankan. Arahkan kursor ke peringatan di Android Studio, dan lihat JavaDoc simbol yang tidak digunakan lagi untuk mengetahui apa yang harus digunakan sebagai pengganti panggilan tertentu.
- Urutkan pernyataan impor: Buka project di Android Studio, lalu klik kanan node folder paket di penampil project dan pilih Optimize imports pada paket yang berisi file sumber yang diubah.
Mengganti MediaSessionConnector dengan androidx.media3.session.MediaSession
Di dunia MediaSessionCompat lama, MediaSessionConnector bertanggung jawab untuk menyinkronkan status pemutar dengan status sesi dan menerima perintah dari pengontrol yang memerlukan delegasi ke metode pemutar yang sesuai. Dengan AndroidX Media3, hal ini dilakukan oleh MediaSession secara langsung tanpa memerlukan konektor.
Hapus semua referensi dan penggunaan MediaSessionConnector: Jika Anda menggunakan skrip otomatis untuk memigrasikan class dan paket ExoPlayer, skrip tersebut kemungkinan telah membuat kode Anda dalam status yang tidak dapat dikompilasi terkait
MediaSessionConnectoryang tidak dapat diselesaikan. Android Studio akan menampilkan kode yang rusak saat Anda mencoba mem-build atau memulai aplikasi.Dalam file
build.gradletempat Anda mempertahankan dependensi, tambahkan dependensi implementasi ke modul sesi AndroidX Media3 dan hapus dependensi lama:implementation "androidx.media3:media3-session:1.10.0"Ganti
MediaSessionCompatdenganandroidx.media3.session.MediaSession.Di situs kode tempat Anda membuat
MediaSessionCompatlama, gunakanandroidx.media3.session.MediaSession.Builderuntuk membuatMediaSession. Teruskan pemutar untuk membuat builder sesi.Kotlin
val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player).setCallback(MySessionCallback()).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); mediaSession = new MediaSession.Builder(context, player).setCallback(new MySessionCallback()).build();
Implementasikan
MySessionCallbackseperti yang diperlukan oleh aplikasi Anda. Hal ini bersifat opsional. Jika Anda ingin mengizinkan pengontrol menambahkan item media ke pemutar, implementasikanMediaSession.Callback.onAddMediaItems(). Metode ini melayani berbagai metode API saat ini dan lama yang menambahkan item media ke pemutar untuk pemutaran dengan cara yang kompatibel dengan versi lama. Hal ini mencakup metodeMediaController.set/addMediaItems()pengontrol Media3, serta metodeTransportControls.prepareFrom*/playFrom*API lama. Implementasi contohonAddMediaItemsdapat ditemukan diPlaybackServiceaplikasi demo sesi.Rilis sesi media di situs kode tempat Anda menghancurkan sesi sebelum migrasi:
Kotlin
mediaSession?.run { player.release() release() mediaSession = null }
Java
if (mediaSession != null) { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; }
Fungsi MediaSessionConnector di Media3
Tabel berikut menunjukkan Media3 API yang menangani fungsi yang sebelumnya diimplementasikan di MediaSessionConnector.
| MediaSessionConnector | AndroidX Media3 |
|---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setMediaButtonPreferences() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() dipanggil secara internal)
|
QueueNavigator |
ForwardingSimpleBasePlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
Memigrasikan MediaBrowserService ke MediaLibraryService
AndroidX Media3 memperkenalkan MediaLibraryService yang menggantikan MediaBrowserServiceCompat. JavaDoc MediaLibraryService dan super class MediaSessionService memberikan pengantar yang baik tentang API dan model pemrograman asinkron layanan.
MediaLibraryService kompatibel dengan versi lama MediaBrowserService. Aplikasi klien yang menggunakan MediaBrowserCompat atau MediaControllerCompat akan terus berfungsi tanpa perubahan kode saat terhubung ke MediaLibraryService. Untuk klien, tidak ada perbedaan apakah aplikasi Anda menggunakan MediaLibraryService atau MediaBrowserServiceCompat lama.
Agar kompatibilitas mundur berfungsi, Anda harus mendaftarkan kedua antarmuka layanan dengan layanan Anda di
AndroidManifest.xml. Dengan cara ini, klien akan menemukan layanan Anda berdasarkan antarmuka layanan yang diperlukan:<service android:name=".MusicService" android:exported="true"> <intent-filter> <action android:name="androidx.media3.session.MediaLibraryService"/> <action android:name="android.media.browse.MediaBrowserService" /> </intent-filter> </service>Dalam file
build.gradletempat Anda mempertahankan dependensi, tambahkan dependensi implementasi ke modul sesi AndroidX Media3 dan hapus dependensi lama:implementation "androidx.media3:media3-session:1.10.0"Ubah layanan Anda agar mewarisi dari
MediaLibraryService, bukanMediaBrowserServiceSeperti yang telah disebutkan sebelumnya,MediaLibraryServicekompatibel denganMediaBrowserServicelama. Oleh karena itu, API yang lebih luas yang ditawarkan layanan kepada klien masih sama. Jadi, kemungkinan aplikasi dapat mempertahankan sebagian besar logika yang diperlukan untuk mengimplementasikanMediaBrowserServicedan mengadaptasinya untukMediaLibraryServicebaru.Perbedaan utama dibandingkan dengan
MediaBrowserServiceCompatlama adalah sebagai berikut:Implementasikan metode siklus proses layanan: Metode yang perlu diganti pada layanan itu sendiri adalah
onCreate/onDestroy, tempat aplikasi mengalokasikan/merilis sesi library, pemutar, dan resource lainnya. Selain metode siklus proses layanan standar, aplikasi perlu menggantionGetSession(MediaSession.ControllerInfo)untuk menampilkanMediaLibrarySessionyang di-build dionCreate.Implementasikan MediaLibraryService.MediaLibrarySessionCallback: Mem-build sesi memerlukan
MediaLibraryService.MediaLibrarySessionCallbackyang mengimplementasikan metode API domain sebenarnya. Jadi, alih-alih mengganti metode API layanan lama, Anda akan mengganti metodeMediaLibrarySession.Callback.Callback kemudian digunakan untuk mem-build
MediaLibrarySession:Kotlin
mediaLibrarySession = MediaLibrarySession.Builder(context, player, MySessionCallback()).build()
Java
mediaLibrarySession = new MediaLibrarySession.Builder(context, player, new MySessionCallback()).build();
Temukan API lengkap MediaLibrarySessionCallback dalam dokumentasi API.
Implementasikan
MediaSession.Callback.onAddMediaItems(): CallbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)melayani berbagai metode API saat ini dan lama yang menambahkan item media ke pemutar untuk pemutaran dengan cara yang kompatibel dengan versi lama. Hal ini mencakup metodeMediaController.set/addMediaItems()pengontrol Media3, serta metodeTransportControls.prepareFrom*/playFrom*API lama. Implementasi contoh callback dapat ditemukan diPlaybackServiceaplikasi demo sesi.AndroidX Media3 menggunakan
androidx.media3.common.MediaItem, bukan MediaBrowserCompat.MediaItem dan MediaMetadataCompat. Bagian kode Anda yang terikat ke class lama harus diubah sesuai dengan itu atau dipetakan keMediaItemMedia3.Model pemrograman asinkron umum diubah menjadi
Futures, berbeda dengan pendekatanResultyang dapat dilepas dariMediaBrowserServiceCompat. Implementasi layanan Anda dapat menampilkan asinkronListenableFuturebukan melepaskan hasil atau menampilkan Future langsung untuk langsung menampilkan nilai.
Menghapus PlayerNotificationManager
MediaLibraryService mendukung notifikasi media secara otomatis dan PlayerNotificationManager dapat dihapus saat menggunakan MediaLibraryService atau MediaSessionService.
Aplikasi dapat menyesuaikan notifikasi dengan menetapkan MediaNotification.Provider kustom di onCreate() yang menggantikan DefaultMediaNotificationProvider. MediaLibraryService kemudian akan menangani memulai layanan di latar depan sesuai kebutuhan.
Dengan mengganti MediaLibraryService.updateNotification(), aplikasi dapat mengambil kepemilikan penuh untuk memposting notifikasi dan memulai/menghentikan layanan di latar depan sesuai kebutuhan.
Memigrasikan kode klien menggunakan MediaBrowser
Dengan AndroidX Media3, MediaBrowser mengimplementasikan antarmuka MediaController/Player dan dapat digunakan untuk mengontrol pemutaran media selain menjelajahi library media. Jika Anda harus membuat MediaBrowserCompat dan a
MediaControllerCompat di dunia lama, Anda dapat melakukan hal yang sama hanya dengan menggunakan
the MediaBrowser di Media3.
MediaBrowser dapat di-build dan menunggu koneksi ke layanan dibuat:
Kotlin
scope.launch { val sessionToken = SessionToken(context, ComponentName(context, "MusicService")) browser = MediaBrowser.Builder(context, sessionToken) .setListener(BrowserListener()) .buildAsync() .await() }
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, "MusicService")); ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken) .setListener(new BrowserListener()) .buildAsync();
Lihat
Mengontrol pemutaran di sesi media
untuk mempelajari cara membuat MediaController guna mengontrol pemutaran di
latar belakang.
Langkah dan pembersihan lebih lanjut
Error API yang tidak stabil
Setelah bermigrasi ke Media3, Anda mungkin melihat error lint tentang penggunaan API yang tidak stabil.
API ini aman digunakan dan error lint adalah produk sampingan dari jaminan kompatibilitas biner baru kami. Jika Anda tidak memerlukan kompatibilitas biner yang ketat, error ini dapat disembunyikan dengan aman menggunakan anotasi @OptIn.
Latar belakang
ExoPlayer v1 atau v2 tidak memberikan jaminan yang ketat tentang kompatibilitas biner library antara versi berikutnya. Platform ExoPlayer API sangat besar berdasarkan desain, untuk memungkinkan aplikasi menyesuaikan hampir setiap aspek pemutaran. Versi ExoPlayer berikutnya terkadang memperkenalkan penggantian nama simbol atau perubahan yang dapat menyebabkan gangguan lainnya (misalnya, metode baru yang diperlukan pada antarmuka). Dalam sebagian besar kasus, gangguan ini dikurangi dengan memperkenalkan simbol baru bersamaan dengan penghentian penggunaan simbol lama untuk beberapa versi, sehingga developer memiliki waktu untuk memigrasikan penggunaannya, tetapi hal ini tidak selalu memungkinkan.
Perubahan yang dapat menyebabkan gangguan ini mengakibatkan dua masalah bagi pengguna library ExoPlayer v1 dan v2:
- Upgrade dari ke versi ExoPlayer dapat menyebabkan kode berhenti dikompilasi.
- Aplikasi yang bergantung pada ExoPlayer secara langsung dan melalui library perantara harus memastikan bahwa kedua dependensi tersebut memiliki versi yang sama, jika tidak, ketidakcocokan biner dapat menyebabkan error runtime.
Peningkatan di Media3
Media3 menjamin kompatibilitas biner untuk subset platform API. Bagian
yang tidak menjamin kompatibilitas biner ditandai dengan
@UnstableApi. Untuk memperjelas perbedaan ini, penggunaan simbol API yang tidak stabil akan menghasilkan error lint kecuali jika diberi anotasi dengan @OptIn.
Setelah bermigrasi dari ExoPlayer v2 ke Media3, Anda mungkin melihat banyak error lint API yang tidak stabil. Hal ini mungkin membuat Media3 tampak 'kurang stabil' dibandingkan ExoPlayer v2. Bukan itu masalahnya. Bagian 'tidak stabil' dari Media3 API memiliki tingkat stabilitas yang sama dengan seluruh platform ExoPlayer v2 API, dan jaminan platform Media3 API yang stabil tidak tersedia di ExoPlayer v2. Perbedaannya hanyalah bahwa error lint kini memberi tahu Anda tentang tingkat stabilitas yang berbeda.
Menangani error lint API yang tidak stabil
Lihat bagian pemecahan masalah tentang error lint ini untuk mengetahui detail tentang cara
memberi anotasi pada penggunaan Java dan Kotlin dari API yang tidak stabil dengan @OptIn.
API tidak digunakan lagi
Anda mungkin melihat bahwa panggilan ke API yang tidak digunakan lagi dicoret di Android Studio. Sebaiknya ganti panggilan tersebut dengan alternatif yang sesuai. Arahkan kursor ke simbol untuk melihat JavaDoc yang memberi tahu API mana yang harus digunakan sebagai gantinya.
Sampel kode dan aplikasi demo
- Aplikasi demo sesi AndroidX Media3 (seluler dan WearOS)
- Tindakan kustom
- Notifikasi UI sistem, MediaButton/BT
- Kontrol pemutaran Asisten Google
- UAMP: Android Media Player (cabang media3) (seluler, AutomotiveOS)
- Notifikasi UI sistem, MediaButton/BT, Pemutaran ulang
- Kontrol pemutaran Asisten Google/WearOS
- AutomotiveOS: perintah kustom dan login