Il framework multimediale Android include il supporto per la riproduzione di vari tipi di contenuti multimediali comuni, quindi
di integrare facilmente audio, video e immagini nelle tue applicazioni. Puoi riprodurre contenuti audio o
Video da file multimediali archiviati nelle risorse dell'applicazione (risorse non elaborate), da file autonomi
nel file system o da uno stream di dati in arrivo su una connessione di rete, il tutto utilizzando le API di MediaPlayer
.
Questo documento illustra come utilizzare
MediaPlayer
per scrivere una riproduzione multimediale
un'applicazione che interagisce con l'utente e il sistema per ottenere buone prestazioni e
una piacevole esperienza utente. In alternativa, potresti
per utilizzare ExoPlayer, un sistema open source personalizzabile
libreria che supporta funzionalità ad alte prestazioni non disponibile in MediaPlayer
Nota:puoi riprodurre i dati audio solo sull'output standard dispositivo. Attualmente, si tratta dell'altoparlante del dispositivo mobile o delle cuffie Bluetooth. Non puoi riprodurre il suono file nell'audio della conversazione durante una chiamata.
Nozioni di base
Le seguenti classi vengono utilizzate per riprodurre audio e video nel framework Android:
MediaPlayer
- Questa classe è l'API principale per la riproduzione di audio e video.
AudioManager
- Questo corso gestisce le sorgenti e l'uscita audio su un dispositivo.
Dichiarazioni del file manifest
Prima di iniziare lo sviluppo dell'applicazione utilizzando MediaPlayer, assicurati che il file manifest abbia le dichiarazioni appropriate per consentire l'uso delle funzionalità correlate.
- Autorizzazione Internet: se utilizzi MediaPlayer per lo streaming in base alla rete.
contenuti, l'applicazione deve richiedere l'accesso alla rete.
<uses-permission android:name="android.permission.INTERNET" />
- Autorizzazione wakelock: se l'applicazione del player deve mantenere lo schermo
l'attenuazione della luminosità o la sospensione del processore, oppure utilizza
MediaPlayer.setScreenOnWhilePlaying()
oMediaPlayer.setWakeMode()
metodi, devi richiedere questa autorizzazione.<uses-permission android:name="android.permission.WAKE_LOCK" />
Utilizzo di MediaPlayer
Uno dei componenti più importanti del framework multimediale è il
MediaPlayer
. Un oggetto di questa classe può recuperare, decodificare e riprodurre sia audio che video
con una configurazione minima. Supporta diverse fonti multimediali, tra cui:
- Risorse locali
- URI interni, ad esempio quello che potresti ottenere da un resolver di contenuti
- URL esterni (streaming)
Per un elenco dei formati multimediali supportati da Android, consulta la sezione Contenuti multimediali supportati Formati.
Ecco un esempio
di come riprodurre l'audio disponibile come risorsa locale non elaborata (salvato nel
directory 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
In questo caso, un file "grezzo" risorsa è un file che il sistema non provare ad analizzare in un modo particolare. Tuttavia, i contenuti di questa risorsa non devono essere audio RAW. Deve essere un file multimediale codificato e formattato correttamente in un dei formati supportati.
Ed ecco come potresti giocare da un URI disponibile localmente nel sistema (ottenuti, ad esempio, tramite un sistema di risoluzione dei contenuti):
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();
La riproduzione da un URL remoto tramite streaming HTTP ha il seguente aspetto:
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();
Nota: Se passi un URL per lo streaming di un file multimediale online, il file deve essere in grado di: un download progressivo.
Attenzione: devi rilevare o superare
IllegalArgumentException
e IOException
quando utilizzi
setDataSource()
, perché
il file a cui fai riferimento potrebbe non esistere.
Preparazione asincrona
L'utilizzo di MediaPlayer
può essere semplice
dell'IA. Tuttavia, è importante tenere presente che vengono
necessario per integrarlo correttamente in una tipica applicazione Android. Per
Ad esempio, la chiamata a prepare()
può
richiedono tempi di esecuzione lunghi,
potrebbe comportare il recupero e la decodifica dei dati multimediali. Quindi, come avviene per qualsiasi
la cui esecuzione può richiedere molto tempo, non dovresti mai chiamarlo dai tuoi
thread interfaccia utente dell'applicazione. In questo modo, la UI si blocca finché non viene restituito il metodo.
che causa un'esperienza utente molto scadente e può causare un errore ANR (L'applicazione non risponde). Anche se
ti aspetti che la risorsa venga caricata rapidamente, ricorda che tutto ciò che richiede più di un decimo
di secondo per rispondere nell'UI comporta una notevole pausa e
all'utente l'impressione che l'applicazione sia lenta.
Per evitare il blocco del thread della UI, genera un altro thread in
prepara MediaPlayer
e invia una notifica al thread principale al termine dell'operazione. Tuttavia, anche se
potresti scrivere la logica del thread
di persona, questo pattern è talmente comune quando si utilizza MediaPlayer
che il framework
un modo conveniente per svolgere questa attività utilizzando
Metodo prepareAsync()
. Questo metodo
inizia a preparare i contenuti multimediali
in background e ritorna immediatamente. Quando i contenuti multimediali
ha terminato la preparazione, onPrepared()
di MediaPlayer.OnPreparedListener
, configurato tramite
Chiamata setOnPreparedListener()
.
Gestione dello stato
Un altro aspetto di MediaPlayer
che dovresti tenere a mente è
che sia basato sullo stato. Questo significa che MediaPlayer
ha uno stato interno
di cui devi sempre essere a conoscenza quando scrivi il codice, poiché alcune operazioni
sono valide solo quando il player si trova in stati specifici. Se esegui un'operazione
stato errato, il sistema potrebbe generare un'eccezione o causare altri comportamenti indesiderati.
La documentazione nel
MediaPlayer
classe mostra un diagramma di stato completo,
che chiarisce quali metodi consentono di spostare MediaPlayer
da uno stato all'altro.
Ad esempio, quando crei un nuovo MediaPlayer
, questo è in Inattivo
stato. A quel punto, dovresti inizializzarlo chiamando
setDataSource()
, ora lo metto
allo stato Inizializzato. Dopodiché, devi prepararlo utilizzando
prepare()
o
Metodo prepareAsync()
. Quando
MediaPlayer
ha terminato la preparazione, entra nello stato Preparato
stato, il che significa che puoi chiamare start()
per riprodurre i contenuti multimediali. A quel punto, come illustrato nel diagramma,
puoi spostarti tra gli stati Iniziato, In pausa e Riproduzione completata
chiamare questi metodi
start()
,
pause()
e
seekTo()
,
tra gli altri. Quando
chiama stop()
, tuttavia, noterai che
non puoi chiamare di nuovo start()
finché non
prepara di nuovo MediaPlayer
.
Mantieni sempre il diagramma di stato
quando si scrive un codice che interagisce
MediaPlayer
, perché chiamare i suoi metodi dallo stato errato è una
causa comune di insetti.
Rilascio di MediaPlayer
Un MediaPlayer
può consumare preziose
risorse di sistema.
Pertanto, prendi sempre precauzioni aggiuntive per assicurarti di non
restando in attesa a un'istanza MediaPlayer
più a lungo del necessario. Quando
hai finito, dovresti sempre chiamare
release()
per assicurarti
e le risorse di sistema assegnate al suo sistema
siano rilasciate correttamente. Ad esempio, se
utilizzando MediaPlayer
e la tua attività riceve una chiamata al numero onStop()
, devi rilasciare MediaPlayer
,
perché
ha poco senso tenerla mentre non interagisci con la tua attività
all'utente (a meno che tu non stia riproducendo i contenuti multimediali in background, come descritto nella prossima sezione).
Quando l'attività viene ripresa o riavviata, naturalmente, è necessario
crea un nuovo MediaPlayer
e preparalo di nuovo prima di riprendere la riproduzione.
Ecco come devi rilasciare e annullare MediaPlayer
:
Kotlin
mediaPlayer?.release() mediaPlayer = null
Java
mediaPlayer.release(); mediaPlayer = null;
Considera ad esempio i problemi che potrebbero verificarsi se
hai dimenticato di rilasciare MediaPlayer
quando la tua attività viene interrotta, ma crea un
una nuova sveglia quando l'attività ricomincia. Come forse saprai, quando l'utente modifica
orientamento dello schermo (o modifica la configurazione del dispositivo in altro modo),
il sistema lo gestisce riavviando l'attività (per impostazione predefinita), quindi potresti
e consuma tutte le risorse di sistema mentre
ruota il dispositivo avanti e indietro in orizzontale e in verticale,
cambia l'orientamento, crei un nuovo MediaPlayer
. Per ulteriori informazioni sui riavvii del runtime, consulta Gestione delle modifiche del runtime.
Forse ti starai chiedendo cosa succede se vuoi continuare a giocare
"contenuti multimediali in background" anche quando l'utente abbandona la tua attività, quasi
il comportamento dell'applicazione Music integrata. In questo caso, ti serve
un MediaPlayer
controllato da un servizio, come
di cui parleremo nella prossima sezione.
Utilizzo di MediaPlayer in un servizio
Se vuoi riprodurre i contenuti multimediali in background anche quando l'applicazione
non viene mostrato sullo schermo, vale a dire che vuoi che continui la riproduzione mentre l'utente
interagire con altre applicazioni, allora devi avviare
Fornire e controllare
MediaPlayer
istanza da lì.
Devi incorporare
MediaPlayer in un servizio MediaBrowserServiceCompat
e ha
interagisce con
MediaBrowserCompat
in un'altra attività.
Devi prestare attenzione alla configurazione client/server. Ci sono aspettative su come un player eseguito in un servizio in background interagisce con il resto dei di un sistema operativo completo. Se la tua applicazione non soddisfa queste aspettative, l'utente può hanno una brutta esperienza. Letto Creazione di un'app audio per tutti i dettagli.
In questa sezione vengono descritte le istruzioni speciali per la gestione di un MediaPlayer quando è implementato all'interno di un servizio.
Esecuzione asincrona
Innanzitutto, come in un Activity
, tutti lavorano in un
Service
viene svolto in un singolo thread da
predefinita: se esegui un'attività e un servizio dalla stessa applicazione,
usa lo stesso thread (il "thread principale") per impostazione predefinita. Pertanto, i servizi devono
elaborare rapidamente gli intent in arrivo
e non eseguire mai calcoli lunghi quando si risponde. Se intensa
di lavoro o di blocco delle chiamate, devi eseguire queste attività in modo asincrono:
un altro thread che implementi personalmente o utilizzando le numerose strutture del framework
per l'elaborazione asincrona.
Ad esempio, se usi MediaPlayer
dal thread principale,
dovresti chiamare prepareAsync()
anziché
prepare()
e implementa
un MediaPlayer.OnPreparedListener
per ricevere una notifica quando la preparazione è terminata e potrai iniziare a giocare.
Ad esempio:
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(); } }
Gestione degli errori asincroni
Nelle operazioni sincrone, gli errori normalmente
essere segnalata con un'eccezione o un codice di errore, ma ogni volta che utilizzi il
devi assicurarti che la tua richiesta venga informata
di errori in modo appropriato. Nel caso di un MediaPlayer
,
puoi farlo implementando un
MediaPlayer.OnErrorListener
e
impostandolo nella tua istanza 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! } }
È importante ricordare che, quando si verifica un errore, MediaPlayer
passa allo stato Errore (consulta la documentazione per
MediaPlayer
per il diagramma dello stato completo)
e devi reimpostarlo prima di poterlo riutilizzare.
Utilizzo dei wakelock
Durante la progettazione di applicazioni per la riproduzione di contenuti multimediali in background, il dispositivo potrebbe entrare in modalità di sospensione mentre il servizio è in esecuzione. Poiché il sistema Android cerca di risparmiare batteria mentre il dispositivo è in sospensione, il sistema tenta di spegnere delle funzionalità dello smartphone come la CPU e l'hardware Wi-Fi. Tuttavia, se il servizio riproduce musica o riproduce musica in streaming, vuoi evitare il sistema non interferisca con la riproduzione.
Per assicurarti che il servizio continui a essere eseguito in in queste condizioni, è necessario usare i "wakelock". Un wakelock è un modo per segnalare a al sistema che la tua applicazione stia usando una funzionalità che dovrebbe rimangono disponibili anche quando il telefono è inattivo.
Avviso: dovresti sempre usare i wakelock con parsimonia e tenerli in mano solo per il tempo realmente necessario, poiché riducono notevolmente la durata della batteria del dispositivo.
Per assicurarti che la CPU continui a funzionare mentre MediaPlayer
è
la riproduzione, chiama il metodo setWakeMode()
durante l'inizializzazione di MediaPlayer
. Dopodiché,
MediaPlayer
mantiene il blocco specificato durante la riproduzione e rilascia il blocco
se messo in pausa o interrotto:
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);
Tuttavia, il wakelock acquisito in questo esempio garantisce solo che la CPU rimanga attiva. Se
stai trasmettendo contenuti multimediali in streaming
e stai utilizzando il Wi-Fi, probabilmente vorrai mantenere una
WifiLock
sotto forma di
che devi acquisire e rilasciare manualmente. Quindi, quando inizi a preparare
MediaPlayer
con l'URL remoto, devi creare e acquisire il blocco Wi-Fi.
Ad esempio:
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();
Quando metti in pausa o interrompi i contenuti multimediali o quando non hai più bisogno del devi rilasciare il blocco:
Kotlin
wifiLock.release()
Java
wifiLock.release();
Pulizia in corso
Come accennato in precedenza, un oggetto MediaPlayer
può consumare una quantità
una quantità di risorse di sistema, quindi dovresti conservarla solo per il tempo necessario e richiamare
release()
quando hai finito. È importante
di chiamare esplicitamente questo metodo di pulizia anziché fare affidamento sulla garbage collection del sistema
potrebbe essere necessario un po' di tempo prima che il garbage collection recuperi l'oggetto MediaPlayer
,
poiché è sensibile solo alle esigenze di memoria e non alla carenza di altre risorse relative ai media.
Quindi, nel caso in cui utilizzi un servizio, dovresti sempre eseguire l'override
onDestroy()
metodo per assicurarti di rilasciare
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(); } }
Dovresti sempre cercare altre opportunità per rilasciare MediaPlayer
oltre a rilasciarlo quando viene arrestato. Ad esempio, se non prevedi che
poter riprodurre contenuti multimediali per un lungo periodo di tempo (ad esempio, dopo aver perso l'audio attivo),
devi sicuramente rilasciare il tuo MediaPlayer
esistente e crearlo di nuovo
in un secondo momento. Il giorno
dall'altra parte, se prevedi di interrompere la riproduzione solo per un breve periodo, probabilmente
tieniti stretto MediaPlayer
per evitare di sprecare tempo per crearlo e prepararlo
di nuovo.
Gestione dei diritti digitali (DRM)
A partire da Android 8.0 (livello API 26), MediaPlayer
include API che
per la riproduzione di materiale protetto da DRM. Sono simili all'API di basso livello fornita
MediaDrm
, ma operano a un livello superiore e non
esporre gli estrattori, gli oggetti drm e le criptovalute sottostanti.
Sebbene l'API DRM MediaPlayer non fornisca la funzionalità completa
MediaDrm
, supporta i casi d'uso più comuni. La
l'implementazione attuale è in grado di gestire i seguenti tipi di contenuti:
- File multimediali locali protetti da Widevine
- File multimediali remoti/in streaming protetti da Widevine
Il seguente snippet di codice mostra come utilizzare il nuovo DRM MediaPlayer in una semplice implementazione sincrona.
Per gestire i contenuti multimediali controllati da DRM, devi includere i nuovi metodi insieme il normale flusso di chiamate a MediaPlayer, come mostrato di seguito:
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();
Inizia inizializzando l'oggetto e l'impostazione MediaPlayer
la sua origine utilizzando setDataSource()
,
come al solito. Quindi, per utilizzare DRM, segui questi passaggi:
- Se vuoi che la tua app esegua la configurazione personalizzata, definisci
OnDrmConfigHelper
e collegala all'interfaccia un lettore consetOnDrmConfigHelper()
. - Chiama il numero
prepare()
. - Chiama il numero
getDrmInfo()
. Se l'origine ha DRM content, il metodo restituisce un valore ValoreMediaPlayer.DrmInfo
.
Se MediaPlayer.DrmInfo
esiste:
- Esamina la mappa degli UUID disponibili e scegline uno.
- Prepara la configurazione DRM per l'origine attuale chiamando
prepareDrm()
. - Se hai creato e registrato un
callback
OnDrmConfigHelper
, si chiama mentreprepareDrm()
è in esecuzione. Questo ti consente di eseguire la configurazione personalizzata di DRM prima di aprire la sessione DRM. Il callback viene chiamato in modo sincrono nel threadprepareDrm()
. A per accedere alle proprietà DRM, richiamagetDrmPropertyString()
esetDrmPropertyString()
. Evita di eseguire operazioni lunghe. - Se non è ancora stato eseguito il provisioning del dispositivo,
Anche
prepareDrm()
accede al server di provisioning per eseguire il provisioning del dispositivo. L'operazione può richiedere a seconda della connettività di rete. - Per ottenere un array di byte di richiesta di chiave opaco da inviare a un server licenze, richiama
getKeyRequest()
. - Per informare il motore DRM della risposta chiave ricevuta dal server di licenze, chiama
provideKeyResponse()
. Il risultato dipende dal tipo di richiesta della chiave:- Se la risposta riguarda una richiesta di chiave offline, il risultato è un identificatore del set di chiavi. Puoi utilizzare
questo identificatore del set di chiavi con
restoreKeys()
per ripristinare le chiavi durante la sessione. - Se la risposta è per una richiesta di flusso o di rilascio, il risultato è nullo.
- Se la risposta riguarda una richiesta di chiave offline, il risultato è un identificatore del set di chiavi. Puoi utilizzare
questo identificatore del set di chiavi con
Esecuzione di prepareDrm()
in modo asincrono
Per impostazione predefinita, prepareDrm()
viene eseguito in modo sincrono, bloccando il processo fino al termine della preparazione. Tuttavia, molto
la prima preparazione DRM su un nuovo dispositivo può richiedere anche il provisioning,
gestiti internamente
prepareDrm()
e
Il completamento dell'operazione potrebbe richiedere del tempo a causa dell'operazione di rete in questione. Puoi
evita di bloccare
prepareDrm()
di
la definizione e l'impostazione di un MediaPlayer.OnDrmPreparedListener
.
Quando imposti un valore OnDrmPreparedListener
,
prepareDrm()
esegue il provisioning (se necessario) e la preparazione in background. Quando
il provisioning e la preparazione sono terminati, viene chiamato il listener. Dovresti
non fare ipotesi sulla sequenza di chiamata o sul thread in cui
il listener viene eseguito (a meno che il listener sia registrato con un thread gestore).
Il listener può essere chiamato prima o dopo
prepareDrm()
i resi.
Configurazione di DRM in modo asincrono
Puoi inizializzare il DRM in modo asincrono creando e registrando il
MediaPlayer.OnDrmInfoListener
per la preparazione di DRM e
MediaPlayer.OnDrmPreparedListener
per avviare il player.
Lavorano in combinazione con
prepareAsync()
, come mostrato di seguito:
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(); }
Gestione dei contenuti multimediali criptati
A partire da Android 8.0 (livello API 26), MediaPlayer
può anche decriptare
CENC (Common Encryption Scheme) e
Contenuti multimediali criptati a livello di campione HLS (METHOD=Sample-AES) per i tipi di stream elementari
H.264 e AAC. I contenuti multimediali con crittografia completa (METHOD=AES-128) erano precedentemente supportati.
Recupero di contenuti multimediali da un ContentResolver
Un'altra funzione che può essere utile in un'applicazione di media player è la possibilità di
recuperare musica presente sul dispositivo dell'utente. Puoi farlo eseguendo una query su ContentResolver
per contenuti multimediali esterni:
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()); }
Per usare questa funzionalità con MediaPlayer
, puoi:
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...
Scopri di più
In queste pagine vengono trattati argomenti relativi alla registrazione, all'archiviazione e alla riproduzione di audio e video.