Kerangka kerja multimedia Android menyertakan dukungan untuk memutar berbagai jenis media umum, jadi
Anda bisa dengan mudah mengintegrasikan audio, video, dan gambar ke dalam aplikasi Anda. Anda dapat memutar audio atau
video dari file media yang disimpan dalam resource aplikasi (resource mentah), dari file yang berdiri sendiri
dalam sistem file, atau dari aliran data yang masuk melalui koneksi jaringan, semuanya menggunakan MediaPlayer
API.
Dokumen ini menunjukkan cara menggunakan
MediaPlayer
untuk menulis pemutaran media
aplikasi yang berinteraksi dengan pengguna dan sistem untuk memperoleh kinerja yang baik dan
pengalaman pengguna yang
menyenangkan. Atau, Anda mungkin ingin
untuk menggunakan ExoPlayer, yang merupakan open source yang dapat disesuaikan
library yang mendukung fitur performa tinggi yang tidak tersedia di MediaPlayer
Catatan: Anda hanya dapat memutar data audio ke output standar perangkat seluler. Saat ini, perangkat tersebut mencakup speaker perangkat seluler atau headset Bluetooth. Anda tidak dapat memutar suara dalam audio percakapan selama panggilan berlangsung.
Dasar-dasar
Class berikut digunakan untuk memutar suara dan video dalam framework Android:
MediaPlayer
- Class ini adalah API utama untuk memutar suara dan video.
AudioManager
- Class ini mengelola sumber audio dan output audio di perangkat.
Deklarasi manifes
Sebelum memulai pengembangan pada aplikasi menggunakan MediaPlayer, pastikan manifes Anda memiliki deklarasi yang sesuai untuk mengizinkan penggunaan fitur terkait.
- Izin Internet - Jika Anda menggunakan MediaPlayer untuk melakukan streaming berbasis jaringan
aplikasi Anda harus meminta akses jaringan.
<uses-permission android:name="android.permission.INTERNET" />
- Izin Penguncian Layar Saat Aktif - Jika aplikasi pemutar Anda perlu mempertahankan layar
dari meredupkan atau mengaktifkan prosesor dari mode tidur, atau menggunakan
MediaPlayer.setScreenOnWhilePlaying()
atau MetodeMediaPlayer.setWakeMode()
, Anda harus meminta izin ini.<uses-permission android:name="android.permission.WAKE_LOCK" />
Menggunakan MediaPlayer
Salah satu komponen terpenting
dari kerangka kerja media adalah
MediaPlayer
. Objek class ini dapat mengambil, mendekode, serta memutar audio dan video
dengan penyiapan minimal. Class ini mendukung beberapa sumber media yang berbeda, seperti:
- Resource lokal
- URI internal, seperti yang mungkin Anda peroleh dari Content Resolver
- URL eksternal (streaming)
Untuk mengetahui daftar format media yang didukung Android, lihat daftar Media yang Didukung Formats.
Berikut contohnya
cara memutar audio yang tersedia sebagai sumber daya mentah lokal (disimpan dalam
res/raw/
):
Kotlin
var mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1) mediaPlayer.start() // no need to call prepare(); create() does that for you
Java
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1); mediaPlayer.start(); // no need to call prepare(); create() does that for you
Dalam hal ini, "raw" sumber daya adalah file yang tidak mencoba menguraikan dengan cara tertentu. Namun, isi referensi ini tidak boleh berupa audio mentah. Harus berupa file media yang dienkode dan diformat dengan benar menjadi satu format yang didukung.
Dan berikut ini cara memutar dari URI yang tersedia secara lokal di sistem (yang Anda peroleh melalui Content Resolver, misalnya):
Kotlin
val myUri: Uri = .... // initialize Uri here val mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(applicationContext, myUri) prepare() start() }
Java
Uri myUri = ....; // initialize Uri here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioAttributes( new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ); mediaPlayer.setDataSource(getApplicationContext(), myUri); mediaPlayer.prepare(); mediaPlayer.start();
Melakukan pemutaran dari URL jarak jauh melalui streaming HTTP akan terlihat seperti ini:
Kotlin
val url = "http://........" // your URL here val mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(url) prepare() // might take long! (for buffering, etc) start() }
Java
String url = "http://........"; // your URL here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioAttributes( new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ); mediaPlayer.setDataSource(url); mediaPlayer.prepare(); // might take long! (for buffering, etc) mediaPlayer.start();
Catatan: Jika Anda meneruskan URL untuk melakukan streaming file media online, file tersebut harus dapat: download progresif.
Perhatian: Anda harus menangkap atau meneruskan
IllegalArgumentException
dan IOException
saat menggunakan
setDataSource()
, karena
file yang Anda rujuk mungkin tidak ada.
Persiapan asinkron
Anda dapat menggunakan MediaPlayer
dengan mudah di
prinsip ini. Namun, penting untuk diingat bahwa
ada beberapa hal lagi yang
perlu mengintegrasikannya dengan benar
dengan aplikasi Android biasa. Sebagai
contoh, panggilan ke prepare()
dapat
memakan waktu lama untuk
dilaksanakan, karena
mungkin diperlukan pengambilan
dan dekode data media. Jadi, seperti halnya dengan
yang mungkin memakan waktu lama, Anda tidak boleh memanggilnya dari
UI thread aplikasi. Tindakan tersebut akan menyebabkan UI hang sampai metode kembali,
yang merupakan pengalaman pengguna yang sangat buruk dan dapat menyebabkan {i>error<i} ANR (Aplikasi Tidak Merespons). Meskipun jika
Anda berharap sumber daya Anda dimuat dengan cepat, ingat bahwa apa pun yang membutuhkan lebih dari sepersepuluh
satu detik untuk merespons di UI menyebabkan
jeda yang terlihat dan memberi
kesan bahwa aplikasi Anda lambat kepada pengguna.
Untuk menghindari penangguhan UI thread, buat thread lain ke
menyiapkan MediaPlayer
dan memberi tahu thread utama jika sudah selesai. Namun, meskipun
Anda bisa menulis logika threading
pola ini sangat umum saat menggunakan MediaPlayer
sehingga framework
menyediakan cara mudah untuk menyelesaikan tugas ini dengan menggunakan
Metode prepareAsync()
. Metode ini
mulai menyiapkan media di latar belakang dan segera kembali. Saat media
selesai persiapan, onPrepared()
dari MediaPlayer.OnPreparedListener
, yang dikonfigurasi melalui
setOnPreparedListener()
dipanggil.
Mengelola status
Aspek lain dari MediaPlayer
yang harus Anda ingat adalah
bahwa kode itu berbasis negara bagian. Artinya, MediaPlayer
memiliki status internal
yang harus selalu Anda perhatikan ketika menulis kode, karena operasi tertentu
hanya valid saat pemutar dalam status tertentu. Jika Anda melakukan operasi saat
salah, sistem dapat menampilkan pengecualian atau menyebabkan perilaku lain yang tidak diinginkan.
Dokumentasi dalam
Class MediaPlayer
menampilkan diagram status lengkap,
yang menjelaskan metode mana yang memindahkan MediaPlayer
dari satu status ke status lainnya.
Misalnya, saat Anda membuat MediaPlayer
baru, instance tersebut akan berada dalam mode Idle
status. Pada saat itu, Anda harus menginisialisasinya dengan memanggil
setDataSource()
, menghadirkannya
ke status Diinisialisasi. Setelah itu, Anda harus menyiapkannya menggunakan
prepare()
atau
Metode prepareAsync()
. Kapan
MediaPlayer
selesai disiapkan, proses akan memasuki Prepared
yang berarti Anda dapat memanggil start()
untuk membuatnya memutar media. Pada saat itu, seperti diilustrasikan dalam diagram,
Anda dapat berpindah antara status Started, Dijeda, dan PlaybackCompleted dengan
memanggil metode seperti
start()
,
pause()
, dan
seekTo()
,
di antara yang lainnya. Jika Anda
memanggil stop()
, tetapi, perhatikan bahwa Anda
tidak dapat menelepon start()
lagi sampai Anda
siapkan MediaPlayer
lagi.
Selalu pertahankan diagram status
ingat saat menulis kode yang berinteraksi dengan
MediaPlayer
, karena memanggil metodenya dari status yang salah merupakan
penyebab umum {i>bug<i}.
Merilis MediaPlayer
MediaPlayer
dapat menghabiskan
resource sistem.
Oleh karena itu, Anda harus selalu mengambil
tindakan pencegahan tambahan untuk memastikan Anda tidak
bergantung pada instance MediaPlayer
lebih lama dari yang diperlukan. Jika Anda
selesai, Anda harus selalu memanggil
release()
untuk memastikan
sumber daya sistem yang dialokasikan
untuknya dilepaskan dengan benar. Misalnya, jika Anda
menggunakan MediaPlayer
dan aktivitas Anda menerima panggilan ke onStop()
, Anda harus melepaskan MediaPlayer
,
karena hal itu
tidak masuk akal untuk menyimpannya saat aktivitas Anda sedang tidak berinteraksi
pengguna (kecuali jika Anda memutar media di latar belakang, yang akan dibahas di bagian berikutnya).
Tentu saja, saat aktivitas Anda dilanjutkan atau dimulai ulang,
buat MediaPlayer
baru dan siapkan lagi sebelum melanjutkan pemutaran.
Berikut cara merilis dan menghapus MediaPlayer
:
Kotlin
mediaPlayer?.release() mediaPlayer = null
Java
mediaPlayer.release(); mediaPlayer = null;
Sebagai contoh, pertimbangkan masalah
yang bisa terjadi jika Anda
lupa merilis MediaPlayer
saat aktivitas Anda dihentikan, tetapi buat
yang baru ketika
aktivitas dimulai lagi. Seperti yang mungkin Anda ketahui, ketika pengguna mengubah
orientasi layar (atau mengubah
konfigurasi perangkat dengan cara lain),
sistem menanganinya dengan memulai ulang aktivitas (secara {i>default<i}), sehingga Anda mungkin
menghabiskan semua sumber daya
sistem sebagai pengguna
memutar perangkat bolak-balik antara potret dan lanskap, karena pada setiap
perubahan orientasi, Anda membuat MediaPlayer
baru yang tidak pernah
data. (Untuk informasi selengkapnya tentang pemulaian ulang waktu proses, lihat Menangani Perubahan Waktu Proses.)
Anda mungkin bertanya-tanya apa yang terjadi jika Anda ingin terus bermain
"media latar belakang" bahkan saat pengguna meninggalkan aktivitas Anda, hampir sama
perilaku aplikasi Musik bawaan. Dalam hal ini, yang Anda butuhkan adalah
MediaPlayer
yang dikontrol oleh Layanan, sebagai
dibahas di bagian berikutnya
Menggunakan MediaPlayer dalam layanan
Jika Anda ingin media tetap diputar di latar belakang bahkan saat aplikasi
tidak ada di layar—artinya, Anda ingin video terus diputar saat pengguna
dengan aplikasi lain—maka Anda harus memulai
Layanan dan kontrol
MediaPlayer
dari sana.
Anda harus menyematkan
MediaPlayer di layanan MediaBrowserServiceCompat
dan memiliki
berinteraksi dengan
MediaBrowserCompat
dalam aktivitas lain.
Anda harus berhati-hati dengan penyiapan klien/server ini. Ada ekspektasi tentang bagaimana pemutar yang berjalan di layanan latar belakang berinteraksi dengan sistem file. Jika aplikasi Anda tidak memenuhi harapan tersebut, pengguna mungkin memiliki pengalaman buruk. {i>Read<i} Membangun Aplikasi Audio untuk detail selengkapnya.
Bagian ini menjelaskan petunjuk khusus untuk mengelola MediaPlayer jika diterapkan dalam layanan.
Menjalankan secara asinkron
Pertama-tama, seperti Activity
, semua berfungsi dalam
Service
dilakukan dalam satu thread dengan
secara default—bahkan, jika Anda menjalankan aktivitas dan layanan dari aplikasi yang sama,
menggunakan thread yang sama ("thread utama") secara default. Oleh karena itu, layanan perlu
memproses intent yang masuk dengan cepat
dan jangan pernah melakukan komputasi
yang panjang saat meresponsnya. Jika ada masalah berat
atau memblokir panggilan yang diharapkan, Anda harus melakukan tugas tersebut secara asinkron:
thread lain yang Anda terapkan sendiri, atau menggunakan banyak fasilitas framework
untuk pemrosesan asinkron.
Misalnya, saat menggunakan MediaPlayer
dari thread utama,
Anda harus memanggil prepareAsync()
, bukan
prepare()
, dan implementasikan
MediaPlayer.OnPreparedListener
agar diberi tahu saat persiapan selesai dan Anda dapat mulai bermain.
Contoh:
Kotlin
private const val ACTION_PLAY: String = "com.example.action.PLAY" class MyService: Service(), MediaPlayer.OnPreparedListener { private var mMediaPlayer: MediaPlayer? = null override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { ... val action: String = intent.action when(action) { ACTION_PLAY -> { mMediaPlayer = ... // initialize it here mMediaPlayer?.apply { setOnPreparedListener(this@MyService) prepareAsync() // prepare async to not block main thread } } } ... } /** Called when MediaPlayer is ready */ override fun onPrepared(mediaPlayer: MediaPlayer) { mediaPlayer.start() } }
Java
public class MyService extends Service implements MediaPlayer.OnPreparedListener { private static final String ACTION_PLAY = "com.example.action.PLAY"; MediaPlayer mediaPlayer = null; public int onStartCommand(Intent intent, int flags, int startId) { ... if (intent.getAction().equals(ACTION_PLAY)) { mediaPlayer = ... // initialize it here mediaPlayer.setOnPreparedListener(this); mediaPlayer.prepareAsync(); // prepare async to not block main thread } } /** Called when MediaPlayer is ready */ public void onPrepared(MediaPlayer player) { player.start(); } }
Menangani error asinkron
Pada operasi sinkron, error biasanya akan
diberi sinyal dengan pengecualian atau kode error, tetapi setiap kali Anda menggunakan
Anda harus memastikan bahwa aplikasi Anda diberi tahu
{i>error<i} secara tepat. Dalam kasus MediaPlayer
,
Anda dapat melakukannya dengan menerapkan
MediaPlayer.OnErrorListener
dan
menyetelnya dalam instance MediaPlayer
:
Kotlin
class MyService : Service(), MediaPlayer.OnErrorListener { private var mediaPlayer: MediaPlayer? = null fun initMediaPlayer() { // ...initialize the MediaPlayer here... mediaPlayer?.setOnErrorListener(this) } override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean { // ... react appropriately ... // The MediaPlayer has moved to the Error state, must be reset! } }
Java
public class MyService extends Service implements MediaPlayer.OnErrorListener { MediaPlayer mediaPlayer; public void initMediaPlayer() { // ...initialize the MediaPlayer here... mediaPlayer.setOnErrorListener(this); } @Override public boolean onError(MediaPlayer mp, int what, int extra) { // ... react appropriately ... // The MediaPlayer has moved to the Error state, must be reset! } }
Penting untuk diingat bahwa saat terjadi error, MediaPlayer
berpindah ke status Error (lihat dokumentasi untuk
Class MediaPlayer
untuk diagram status lengkap)
dan Anda harus meresetnya sebelum
dapat menggunakannya lagi.
Menggunakan penguncian layar saat aktif
Saat merancang aplikasi yang memutar media di latar belakang, perangkat mungkin tidur saat layanan Anda berjalan. Karena sistem Android mencoba menghemat baterai saat perangkat tidur, sistem akan mencoba mematikan fitur ponsel yang tidak perlu, termasuk CPU dan perangkat keras WiFi. Tetapi, jika layanan Anda memutar atau {i>streaming<i} musik, Anda ingin mencegah sistem agar tidak mengganggu pemutaran.
Untuk memastikan bahwa layanan Anda terus berjalan berdasarkan kondisi itu, Anda harus menggunakan "penguncian layar saat aktif". Penguncian layar saat aktif adalah cara untuk memberi sinyal untuk sistem di mana aplikasi Anda menggunakan beberapa fitur yang seharusnya tetap tersedia bahkan jika ponsel tidak ada aktivitas.
Perhatikan: Anda harus selalu menggunakan penguncian layar saat aktif dengan hemat dan menahannya hanya selama benar-benar diperlukan, karena cara itu mengurangi masa pakai baterai secara signifikan perangkat seluler.
Untuk memastikan CPU terus berjalan saat MediaPlayer
Anda
diputar, panggil metode setWakeMode()
saat melakukan inisialisasi MediaPlayer
. Setelah Anda melakukannya,
MediaPlayer
akan menahan kunci yang ditentukan saat memutar dan melepaskan kunci
saat dijeda atau dihentikan:
Kotlin
mediaPlayer = MediaPlayer().apply { // ... other initialization here ... setWakeMode(applicationContext, PowerManager.PARTIAL_WAKE_LOCK) }
Java
mediaPlayer = new MediaPlayer(); // ... other initialization here ... mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
Namun, penguncian layar saat aktif yang diperoleh dalam contoh ini hanya menjamin bahwa CPU akan tetap aktif. Jika
Anda melakukan streaming media melalui
jaringan dan Anda menggunakan
Wi-Fi, Anda mungkin ingin mengadakan
WifiLock
sebagai
yang harus Anda dapatkan dan rilis secara manual. Jadi, saat Anda mulai mempersiapkan
MediaPlayer
dengan URL jarak jauh, Anda harus membuat dan mendapatkan kunci Wi-Fi.
Contoh:
Kotlin
val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager val wifiLock: WifiManager.WifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock") wifiLock.acquire()
Java
WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE)) .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock"); wifiLock.acquire();
Saat Anda menjeda atau menghentikan media, atau saat Anda tidak lagi memerlukan jaringan, Anda harus melepaskan kunci:
Kotlin
wifiLock.release()
Java
wifiLock.release();
Melakukan pembersihan
Seperti yang disebutkan sebelumnya, objek MediaPlayer
dapat menggunakan
jumlah sumber daya sistem, jadi Anda harus menyimpannya hanya selama yang Anda butuhkan dan
release()
jika sudah selesai. Penting
memanggil metode pembersihan ini secara eksplisit daripada
mengandalkan pembersihan sampah memori sistem karena
mungkin perlu waktu beberapa saat sebelum pembersih sampah memori mengklaim kembali MediaPlayer
,
karena sensitif terhadap kebutuhan memori dan
tidak kekurangan sumber daya terkait media lainnya.
Jadi, jika Anda menggunakan layanan, Anda harus selalu mengganti
Metode onDestroy()
untuk memastikan Anda merilis
MediaPlayer
:
Kotlin
class MyService : Service() { private var mediaPlayer: MediaPlayer? = null // ... override fun onDestroy() { super.onDestroy() mediaPlayer?.release() } }
Java
public class MyService extends Service { MediaPlayer mediaPlayer; // ... @Override public void onDestroy() { super.onDestroy(); if (mediaPlayer != null) mediaPlayer.release(); } }
Anda harus selalu mencari peluang lain untuk merilis MediaPlayer
juga, selain melepaskannya saat dimatikan. Misalnya, jika Anda berharap tidak
dapat memutar media untuk jangka waktu yang lama (misalnya, setelah kehilangan fokus audio),
Anda harus merilis MediaPlayer
yang sudah ada dan membuatnya lagi
nanti. Pada
di sisi lain, jika Anda hanya ingin menghentikan
pemutaran untuk waktu yang sangat singkat, Anda mungkin
simpan MediaPlayer
untuk menghindari overhead saat pembuatan dan penyiapan
untuk mencoba lagi perintah.
Manajemen Hak Digital (DRM)
Mulai Android 8.0 (level API 26), MediaPlayer
menyertakan API yang
mendukung pemutaran materi yang dilindungi DRM. API ini mirip dengan API tingkat
rendah yang disediakan oleh
MediaDrm
, tetapi beroperasi pada level yang lebih tinggi dan tidak
mengekspos objek ekstraktor, drm, dan kripto yang mendasarinya.
Meskipun MediaPlayer DRM API tidak menyediakan fungsi
MediaDrm
, mendukung kasus penggunaan paling umum. Tujuan
implementasi saat ini dapat menangani jenis konten berikut:
- File media lokal yang dilindungi Widevine
- File media jarak jauh/streaming yang dilindungi Widevine
Cuplikan kode berikut menunjukkan cara menggunakan DRM MediaPlayer yang baru metode dalam implementasi sinkron sederhana.
Untuk mengelola media yang dikontrol DRM, Anda perlu menyertakan metode baru ini bersama alur biasa panggilan MediaPlayer, seperti yang ditunjukkan di bawah ini:
Kotlin
mediaPlayer?.apply { setDataSource() setOnDrmConfigHelper() // optional, for custom configuration prepare() drmInfo?.also { prepareDrm() getKeyRequest() provideKeyResponse() } // MediaPlayer is now ready to use start() // ...play/pause/resume... stop() releaseDrm() }
Java
setDataSource(); setOnDrmConfigHelper(); // optional, for custom configuration prepare(); if (getDrmInfo() != null) { prepareDrm(); getKeyRequest(); provideKeyResponse(); } // MediaPlayer is now ready to use start(); // ...play/pause/resume... stop(); releaseDrm();
Mulai dengan menginisialisasi objek dan setelan MediaPlayer
sumbernya menggunakan setDataSource()
,
seperti biasa. Kemudian, untuk menggunakan DRM, lakukan langkah-langkah berikut:
- Jika Anda ingin aplikasi melakukan konfigurasi khusus, tentukan
OnDrmConfigHelper
, dan melampirkannya ke pemain menggunakansetOnDrmConfigHelper()
. - Panggil
prepare()
. - Panggil
getDrmInfo()
. Jika sumber memiliki DRM konten tersebut, metode akan mengembalikan nilai {i>non-null<i} NilaiMediaPlayer.DrmInfo
.
Jika MediaPlayer.DrmInfo
ada:
- Periksa peta UUID yang tersedia dan pilih salah satunya.
- Persiapkan konfigurasi DRM untuk sumber saat ini dengan memanggil
prepareDrm()
. - Jika Anda membuat dan mendaftarkan
Callback
OnDrmConfigHelper
, proses ini disebut sementaraprepareDrm()
sedang dieksekusi. Hal ini memungkinkan Anda melakukan konfigurasi kustom DRM sebelum membuka sesi DRM. Callback dipanggil secara sinkron di thread yang memanggilprepareDrm()
. Kepada mengakses properti DRM, panggilgetDrmPropertyString()
dansetDrmPropertyString()
. Jangan melakukan operasi yang panjang. - Jika perangkat belum disediakan,
prepareDrm()
juga mengakses server penyediaan untuk menyediakan perangkat. Proses ini dapat memerlukan jumlah waktu yang bervariasi, tergantung pada konektivitas jaringan. - Untuk mendapatkan array byte permintaan kunci buram untuk dikirim ke server lisensi, panggil
getKeyRequest()
. - Untuk memberi tahu mesin DRM tentang respons kunci yang diterima dari server lisensi, panggil
provideKeyResponse()
. Hasilnya bergantung pada jenis permintaan kunci:- Jika respons ditujukan untuk permintaan kunci offline, hasilnya akan berupa ID rangkaian kunci Anda dapat menggunakan
ID kumpulan kunci ini dengan
restoreKeys()
untuk memulihkan kunci ke sesi. - Jika respons ditujukan untuk permintaan streaming atau rilis, hasilnya adalah null.
- Jika respons ditujukan untuk permintaan kunci offline, hasilnya akan berupa ID rangkaian kunci Anda dapat menggunakan
ID kumpulan kunci ini dengan
Menjalankan prepareDrm()
secara asinkron
Secara default, prepareDrm()
berjalan secara sinkron, melakukan pemblokiran hingga persiapan selesai. Namun,
persiapan DRM pertama pada perangkat baru mungkin juga memerlukan penyediaan,
ditangani secara internal oleh
prepareDrm()
, dan
mungkin memakan waktu lebih lama untuk
diselesaikan karena operasi jaringan yang terlibat. Anda dapat
hindari pemblokiran di
prepareDrm()
kali
menentukan dan menetapkan MediaPlayer.OnDrmPreparedListener
.
Saat Anda menetapkan OnDrmPreparedListener
,
prepareDrm()
melakukan penyediaan (jika diperlukan) dan persiapan di latar belakang. Kapan
dan persiapan telah selesai, pemroses dipanggil. Anda seharusnya
tidak membuat asumsi apa pun tentang urutan pemanggilan atau thread di mana
berjalan (kecuali jika pemroses didaftarkan dengan thread pengendali).
Pemroses dapat dipanggil sebelum atau setelah
prepareDrm()
akan dikembalikan.
Menyiapkan DRM secara asinkron
Anda dapat menginisialisasi DRM secara asinkron dengan membuat dan mendaftarkan
MediaPlayer.OnDrmInfoListener
untuk persiapan DRM dan
MediaPlayer.OnDrmPreparedListener
untuk memulai pemutar.
Mereka bekerja
sama dengan
prepareAsync()
, seperti yang ditunjukkan di bawah ini:
Kotlin
setOnPreparedListener() setOnDrmInfoListener() setDataSource() prepareAsync() // ... // If the data source content is protected you receive a call to the onDrmInfo() callback. override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) { mediaPlayer.apply { prepareDrm() getKeyRequest() provideKeyResponse() } } // When prepareAsync() finishes, you receive a call to the onPrepared() callback. // If there is a DRM, onDrmInfo() sets it up before executing this callback, // so you can start the player. override fun onPrepared(mediaPlayer: MediaPlayer) { mediaPlayer.start() }
Java
setOnPreparedListener(); setOnDrmInfoListener(); setDataSource(); prepareAsync(); // ... // If the data source content is protected you receive a call to the onDrmInfo() callback. onDrmInfo() { prepareDrm(); getKeyRequest(); provideKeyResponse(); } // When prepareAsync() finishes, you receive a call to the onPrepared() callback. // If there is a DRM, onDrmInfo() sets it up before executing this callback, // so you can start the player. onPrepared() { start(); }
Menangani media yang dienkripsi
Mulai Android 8.0 (level API 26), MediaPlayer
juga dapat mendekripsi
{i>Common Encryption Scheme <i}(CENC) dan
Media terenkripsi tingkat sampel HLS (METHOD=SAMPLE-AES) untuk jenis streaming dasar
H.264, dan AAC. Sebelumnya, media terenkripsi segmen penuh (METHOD=AES-128) didukung.
Mengambil media dari ContentResolver
Fitur lain yang mungkin berguna dalam
aplikasi pemutar media adalah kemampuan untuk
mengambil musik yang
ada di perangkat pengguna. Anda dapat melakukannya dengan meminta ContentResolver
untuk media eksternal:
Kotlin
val resolver: ContentResolver = contentResolver val uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI val cursor: Cursor? = resolver.query(uri, null, null, null, null) when { cursor == null -> { // query failed, handle error. } !cursor.moveToFirst() -> { // no media on the device } else -> { val titleColumn: Int = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE) val idColumn: Int = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID) do { val thisId = cursor.getLong(idColumn) val thisTitle = cursor.getString(titleColumn) // ...process entry... } while (cursor.moveToNext()) } } cursor?.close()
Java
ContentResolver contentResolver = getContentResolver(); Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; Cursor cursor = contentResolver.query(uri, null, null, null, null); if (cursor == null) { // query failed, handle error. } else if (!cursor.moveToFirst()) { // no media on the device } else { int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE); int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID); do { long thisId = cursor.getLong(idColumn); String thisTitle = cursor.getString(titleColumn); // ...process entry... } while (cursor.moveToNext()); }
Untuk menggunakannya dengan MediaPlayer
, Anda dapat melakukan hal berikut:
Kotlin
val id: Long = /* retrieve it from somewhere */ val contentUri: Uri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id ) mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(applicationContext, contentUri) } // ...prepare and start...
Java
long id = /* retrieve it from somewhere */; Uri contentUri = ContentUris.withAppendedId( android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioAttributes( new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ); mediaPlayer.setDataSource(getApplicationContext(), contentUri); // ...prepare and start...
Pelajari lebih lanjut
Halaman ini membahas topik yang berkaitan dengan perekaman, penyimpanan, dan pemutaran kembali audio dan video.