Aplikasi yang saat ini menggunakan library com.google.android.exoplayer2
dan androidx.media
mandiri harus dimigrasikan 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 melakukan migrasi, tinjau bagian berikut untuk mempelajari lebih lanjut manfaat API baru, API untuk dimigrasikan, dan prasyarat yang harus dipenuhi project aplikasi Anda.
Alasan bermigrasi ke Jetpack Media3
- Ini adalah rumah baru ExoPlayer, sedangkan
com.google.android.exoplayer2
dihentikan. - Akses Player API di berbagai komponen/proses dengan
MediaBrowser
/MediaController
. - Gunakan kemampuan yang diperluas dari
MediaSession
danMediaController
API. - Menunjukkan kemampuan pemutaran dengan kontrol akses yang mendetail.
- Sederhanakan aplikasi Anda dengan menghapus
MediaSessionConnector
danPlayerNotificationManager
. - Kompatibel dengan versi lama dengan API klien media-compat
(
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
Media API untuk dimigrasikan ke AndroidX Media3
- ExoPlayer dan ekstensinya
Ini mencakup semua modul dari project ExoPlayer lama kecuali modul mediasession yang dihentikan. Aplikasi atau modul bergantung pada paket dicom.google.android.exoplayer2
dapat dimigrasikan dengan skrip migrasi. - MediaSessionConnector (bergantung pada
paket
androidx.media.*
dariandroidx.media:media:1.4.3+
)
HapusMediaSessionConnector
dan gunakanandroidx.media3.session.MediaSession
sebagai gantinya. - MediaBrowserServiceCompat (bergantung pada
paket
androidx.media.*
dariandroidx.media:media:1.4.3+
)
Migrasikan subclassandroidx.media.MediaBrowserServiceCompat
keandroidx.media3.session.MediaLibraryService
dan kode menggunakanMediaBrowserCompat.MediaItem
keandroidx.media3.common.MediaItem
. - MediaBrowserCompat (bergantung pada
paket
android.support.v4.media.*
dariandroidx.media:media:1.4.3+
)
Migrasikan kode klien menggunakanMediaBrowserCompat
atauMediaControllerCompat
untuk menggunakanandroidx.media3.session.MediaBrowser
denganandroidx.media3.common.MediaItem
.
Prasyarat
Memastikan project Anda berada di bawah kontrol sumber
Pastikan Anda dapat dengan mudah mengembalikan perubahan yang diterapkan oleh alat migrasi dengan skrip. Jika Anda belum memiliki project di bawah kontrol sumber, sekarang adalah saat 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 library ExoPlayer versi terbaru dan hapus semua panggilan ke metode yang tidak digunakan lagi. Jika ingin menggunakan skrip untuk migrasi, Anda harus mencocokkan versi yang digunakan untuk mengupdate dengan versi yang ditangani oleh skrip.
Tingkatkan compileSdkVersion aplikasi Anda ke minimal 32.
Upgrade Gradle dan plugin Gradle Android Studio ke versi terbaru yang berfungsi dengan dependensi yang telah diupdate dari atas. Misalnya:
- Versi Plugin Android Gradle: 7.1.0
- Versi Gradle: 7.4
Mengganti semua pernyataan impor karakter pengganti yang menggunakan asterix (*) dan menggunakan 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, ...).
Bermigrasi dari
com.google.android.exoplayer2.PlayerView
kecom.google.android.exoplayer2.StyledPlayerView
. Hal ini diperlukan karena tidak ada padanan dengancom.google.android.exoplayer2.PlayerView
di AndroidX Media3.
Memigrasikan ExoPlayer dengan dukungan skrip
Skrip ini memfasilitasi pemindahan dari com.google.android.exoplayer2
ke struktur
paket dan modul baru di bagian androidx.media3
. Skrip ini menerapkan beberapa pemeriksaan validasi pada project Anda dan mencetak peringatan jika validasi gagal.
Jika tidak, pemetaan akan menerapkan pemetaan class dan paket yang diganti namanya di
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 tempat Anda mengupdate aplikasi:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
Jadikan skrip dapat dieksekusi:
chmod 744 media3-migration.sh
Jalankan skrip dengan
--help
untuk mempelajari opsi.Jalankan skrip dengan
-l
untuk mencantumkan kumpulan file yang dipilih untuk migrasi (gunakan-f
untuk memaksa listingan tanpa peringatan):./media3-migration.sh -l -f /path/to/gradle/project/root
Jalankan skrip dengan
-m
untuk memetakan paket, class, dan modul ke Media3. Menjalankan skrip dengan opsi-m
akan 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 dipaksa 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 manual ini setelah menjalankan skrip dengan opsi -m
:
- Periksa cara skrip mengubah kode Anda: Gunakan alat diff dan perbaiki
potensi masalah (pertimbangkan untuk melaporkan bug jika menurut Anda skrip tersebut memiliki
masalah umum yang muncul tanpa meneruskan opsi
-f
). - Build project: Gunakan
./gradlew clean build
atau di Android Studio, pilih File > Sync Project with Gradle Files, lalu Build > Clean project, kemudian Build > Rebuild project (pantau build Anda di tab 'Build - Build Output' di Android Studio).
Langkah-langkah tindak lanjut yang direkomendasikan:
- Selesaikan keikutsertaan atas error terkait penggunaan API yang tidak stabil.
- Mengganti panggilan API yang tidak digunakan lagi: Gunakan API pengganti yang disarankan. Tahan kursor ke peringatan di Android Studio, dan lihat JavaDoc tentang simbol yang tidak digunakan lagi untuk mengetahui apa yang harus digunakan, bukan panggilan yang diberikan.
- Mengurutkan pernyataan impor: Buka project di Android Studio, lalu klik kanan node folder paket di project viewer dan pilih Optimize imports pada paket yang berisi file sumber yang telah diubah.
Ganti MediaSessionConnector
dengan androidx.media3.session.MediaSession
Dalam 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 meninggalkan kode Anda dalam status yang tidak dapat dikompilasi terkait
MediaSessionConnector
yang tidak dapat di-resolve. Android Studio akan menampilkan kode yang rusak saat Anda mencoba membangun atau memulai aplikasi.Dalam file
build.gradle
tempat Anda mempertahankan dependensi, tambahkan dependensi implementasi ke modul sesi AndroidX Media3 dan hapus dependensi lama:implementation "androidx.media3:media3-session:1.3.1"
Ganti
MediaSessionCompat
denganandroidx.media3.session.MediaSession
.Di situs kode tempat Anda membuat
MediaSessionCompat
lama, gunakanandroidx.media3.session.MediaSession.Builder
untuk mem-buildMediaSession
. Teruskan pemain untuk membuat pembuat sesi.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
Terapkan
MySessionCallback
sesuai kebutuhan aplikasi Anda. Tindakan ini bersifat opsional. Jika Anda ingin mengizinkan pengontrol untuk menambahkan item media ke pemutar, implementasikanMediaSession.Callback.onAddMediaItems()
. Pemutar ini menyalurkan berbagai metode API saat ini dan lama yang menambahkan item media ke pemutar untuk diputar dengan cara yang kompatibel dengan versi sebelumnya. Hal ini mencakup metodeMediaController.set/addMediaItems()
dari pengontrol Media3, serta metodeTransportControls.prepareFrom*/playFrom*
dari API lama. Contoh implementasionAddMediaItems
dapat ditemukan diPlaybackService
aplikasi demo sesi.Rilis sesi media di situs kode tempat Anda menghancurkan sesi sebelum migrasi:
mediaSession?.run { player.release() release() mediaSession = null }
Fungsi MediaSessionConnector
di Media3
Tabel berikut menunjukkan Media3 API yang menangani fungsi
yang sebelumnya diimplementasikan di MediaSessionConnector
.
MediaSessionConnector | Media3 AndroidX |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setCustomLayout() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() dipanggil secara internal)
|
QueueNavigator |
ForwardingPlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
Migrasikan MediaBrowserService
ke MediaLibraryService
AndroidX Media3 memperkenalkan MediaLibraryService
yang menggantikan
MediaBrowserServiceCompat
. JavaDoc MediaLibraryService
dan MediaSessionService
class
supernya memberikan pengantar yang baik ke dalam API dan
model pemrograman asinkron layanan.
MediaLibraryService
memiliki kompatibilitas mundur dengan
MediaBrowserService
. Aplikasi klien yang menggunakan MediaBrowserCompat
atau
MediaControllerCompat
, terus berfungsi tanpa perubahan kode saat terhubung
ke MediaLibraryService
. Untuk klien, hal ini transparan 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 menemukan layanan Anda melalui 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.gradle
tempat Anda mempertahankan dependensi, tambahkan dependensi implementasi ke modul sesi AndroidX Media3 dan hapus dependensi lama:implementation "androidx.media3:media3-session:1.3.1"
Ubah layanan Anda untuk mewarisi dari
MediaLibraryService
, bukanMediaBrowserService
Seperti yang disebutkan sebelumnya,MediaLibraryService
kompatibel denganMediaBrowserService
lama. Oleh karena itu, API yang lebih luas yang ditawarkan layanan kepada klien tetap sama. Jadi, ada kemungkinan bahwa aplikasi dapat menyimpan sebagian besar logika yang diperlukan untuk mengimplementasikanMediaBrowserService
dan menyesuaikannya untukMediaLibraryService
baru.Perbedaan utama dibandingkan dengan
MediaBrowserServiceCompat
lama adalah sebagai berikut:Mengimplementasikan metode siklus proses layanan: Metode yang perlu diganti pada layanan itu sendiri adalah
onCreate/onDestroy
, dengan aplikasi mengalokasikan/merilis sesi library, pemutar, dan resource lainnya. Selain metode siklus proses layanan standar, aplikasi perlu menggantionGetSession(MediaSession.ControllerInfo)
untuk menampilkanMediaLibrarySession
yang di-build dionCreate
.Implementasi MediaLibraryService.MediaLibrarySessionCallback: Pembuatan sesi memerlukan
MediaLibraryService.MediaLibrarySessionCallback
yang mengimplementasikan metode API domain sebenarnya. Jadi, Anda akan mengganti metodeMediaLibrarySession.Callback
, bukan mengganti metode API layanan lama.Callback ini kemudian digunakan untuk membuat
MediaLibrarySession
:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
Temukan API lengkap MediaLibrarySessionCallback dalam dokumentasi API.
Mengimplementasikan
MediaSession.Callback.onAddMediaItems()
: CallbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
menayangkan berbagai metode API saat ini dan yang lama yang menambahkan item media ke pemutar untuk diputar dengan cara yang kompatibel dengan versi lama. Hal ini mencakup metodeMediaController.set/addMediaItems()
dari pengontrol Media3, serta metodeTransportControls.prepareFrom*/playFrom*
dari API lama. Contoh penerapan callback dapat ditemukan diPlaybackService
aplikasi demo sesi.AndroidX Media3 menggunakan
androidx.media3.common.MediaItem
, bukan MediaBrowserCompat.meluncurkan dan MediaMetadataCompat. Bagian kode Anda yang terkait dengan class lama perlu diubah atau dipetakan keMediaItem
Media3.Model pemrograman asinkron umum diubah menjadi
Futures
, berbeda dengan pendekatanResult
yang dapat dilepas dariMediaBrowserServiceCompat
. Implementasi layanan Anda dapat menampilkanListenableFuture
asinkron, bukan 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 menyetel
MediaNotification.Provider
kustom di onCreate()
yang menggantikan
DefaultMediaNotificationProvider
. Kemudian, MediaLibraryService
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 harus membuat MediaBrowserCompat
dan
MediaControllerCompat
di dunia lama, Anda dapat melakukan hal yang sama hanya dengan menggunakan
MediaBrowser
di Media3.
MediaBrowser
dapat di-build dan menunggu koneksi ke
layanan yang dibuat:
scope.launch {
val sessionToken =
SessionToken(context, ComponentName(context, MusicService::class.java)
browser =
MediaBrowser.Builder(context, sessionToken))
.setListener(BrowserListener())
.buildAsync()
.await()
// Get the library root to start browsing the library.
root = browser.getLibraryRoot(/* params= */ null).await();
// Add a MediaController.Listener to listen to player state events.
browser.addListener(playerListener)
playerView.setPlayer(browser)
}
Lihat
Mengontrol pemutaran di sesi media
untuk mempelajari cara membuat MediaController
guna mengontrol pemutaran di
latar belakang.
Langkah lebih lanjut dan pembersihan
Error API tidak stabil
Setelah bermigrasi ke Media3, Anda mungkin melihat error lint terkait penggunaan API yang tidak stabil.
API ini aman digunakan dan error lint adalah hasil sampingan dari
jaminan kompatibilitas biner baru kami. Jika Anda tidak memerlukan kompatibilitas biner
yang ketat, error ini dapat disembunyikan secara aman dengan anotasi
@OptIn
.
Latar belakang
Baik ExoPlayer v1 atau v2 tidak memberikan jaminan ketat tentang kompatibilitas biner library di antara versi berikutnya. Permukaan ExoPlayer API sangat besar secara desain, agar aplikasi dapat menyesuaikan hampir setiap aspek pemutaran. Versi ExoPlayer berikutnya terkadang akan memperkenalkan penggantian nama simbol atau perubahan lainnya yang dapat menyebabkan gangguan (misalnya metode baru yang diperlukan pada antarmuka). Pada sebagian besar kasus, kerusakan ini dimitigasi dengan memperkenalkan simbol baru serta penghentian penggunaan simbol lama untuk beberapa versi, agar developer memiliki waktu untuk memigrasikan penggunaan mereka, 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 adalah versi yang sama, jika tidak, inkompatibilitas 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 dianotasi dengan @OptIn
.
Setelah bermigrasi dari ExoPlayer v2 ke Media3, Anda mungkin melihat banyak error lint API yang tidak stabil. Ini mungkin membuatnya tampak seperti Media3 'kurang stabil' dibandingkan ExoPlayer v2. Bukan itu masalahnya. Bagian yang 'tidak stabil' di Media3 API memiliki tingkat stabilitas yang sama dengan seluruh platform ExoPlayer v2 API, dan jaminan platform API Media3 yang stabil tidak tersedia sama sekali di ExoPlayer v2. Perbedaannya adalah, error lint kini memberi tahu Anda tentang berbagai tingkat stabilitas.
Menangani error lint API yang tidak stabil
Anda memiliki dua pilihan untuk menangani error lint API yang tidak stabil:
- Beralihlah untuk menggunakan API stabil yang memberikan hasil sama.
Terus gunakan API yang tidak stabil dan anotasikan penggunaan dengan
@OptIn
.import androidx.annotation.OptIn import androidx.media3.common.util.UnstableApi @OptIn(UnstableApi::class) fun functionUsingUnstableApi() { // Do something useful. }
Perlu diketahui juga ada anotasi
kotlin.OptIn
yang tidak boleh digunakan. Sangat penting untuk tetap menggunakan anotasiandroidx.annotation.OptIn
untuk tujuan ini.
Seluruh paket dapat diikutsertakan dengan menambahkan package-info.java
:
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
Seluruh project dapat diikutsertakan dengan menyembunyikan error lint tertentu dalam lint.xml. Lihat JavaDoc anotasi UnstableApi untuk detail selengkapnya.
API yang 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 tersebut untuk melihat JavaDoc yang memberi tahu API mana yang akan digunakan.
Contoh kode dan aplikasi demo
- Aplikasi demo sesi Media3 AndroidX (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, Melanjutkan pemutaran
- Kontrol pemutaran Asisten Google/WearOS
- AutomotiveOS: perintah kustom dan login