A partire da Android 8.0 (livello API 26), MediaPlayer
include API che supportano la riproduzione di materiale protetto da DRM. Le API MediaPlayer DRM sono simili all'API di basso livello fornita da MediaDrm
, ma operano a un livello superiore e non espongono gli oggetti di estrazione, DRM e crittografia sottostanti.
Sebbene l'API MediaPlayer DRM non fornisca la funzionalità completa di
MediaDrm
, supporta i casi d'uso più comuni. L'attuale implementazione può gestire i seguenti tipi di contenuti:
- File multimediali locali protetti da Widevine
- File multimediali in streaming o remoti protetti da Widevine
Il seguente snippet di codice mostra come utilizzare i nuovi metodi DRM MediaPlayer
in un'implementazione sincrona.
Per gestire i contenuti multimediali con DRM, devi includere i nuovi metodi insieme al normale flusso di chiamate MediaPlayer, come mostrato in questo esempio:
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 MediaPlayer
e impostandone l'origine utilizzando
setDataSource()
, come di consueto. Per utilizzare il DRM, segui questi passaggi:
- Se vuoi che la tua app esegua una configurazione personalizzata, definisci un'interfaccia
OnDrmConfigHelper
e associala al player utilizzandosetOnDrmConfigHelper()
. - Chiama il numero
prepare()
. - Chiama il numero
getDrmInfo()
. Se l'origine contiene contenuti DRM, il metodo restituisce un valoreMediaPlayer.DrmInfo
non nullo.
Se MediaPlayer.DrmInfo
esiste:
- Esamina la mappa degli UUID disponibili e scegline uno.
- Prepara la configurazione DRM per l'origine corrente chiamando
prepareDrm()
.- Se hai creato e registrato un callback
OnDrmConfigHelper
, viene chiamato durante l'esecuzione diprepareDrm()
. In questo modo puoi eseguire la configurazione personalizzata delle proprietà DRM prima di aprire la sessione DRM. Il callback viene chiamato in modo sincrono nel thread che ha chiamatoprepareDrm()
. Per accedere alle proprietà DRM, chiamagetDrmPropertyString()
esetDrmPropertyString()
. Evita di eseguire operazioni lunghe. - Se il provisioning del dispositivo non è ancora stato eseguito,
prepareDrm()
accede anche al server di provisioning per eseguire il provisioning del dispositivo. Questa operazione può richiedere un tempo variabile, a seconda della connettività di rete.
- Se hai creato e registrato un callback
- Per ottenere un array di byte di richiesta di chiave opaca da inviare a un server delle licenze, chiama
getKeyRequest()
. - Per informare il motore DRM della risposta della chiave ricevuta dal
server delle licenze, chiama
provideKeyResponse()
. Il risultato dipende dal tipo di richiesta di chiave:- Se la risposta riguarda una richiesta di chiave offline, il risultato è un identificatore di set di chiavi. Puoi utilizzare questo identificatore dell'insieme di chiavi con
restoreKeys()
per ripristinare le chiavi in una nuova sessione. - Se la risposta riguarda una richiesta di streaming o di uscita, il risultato è nullo.
- Se la risposta riguarda una richiesta di chiave offline, il risultato è un identificatore di set di chiavi. Puoi utilizzare questo identificatore dell'insieme di chiavi con
Preparare il DRM in modo asincrono
Per impostazione predefinita, prepareDrm()
viene eseguito in modo sincrono e si blocca fino al completamento della preparazione. Tuttavia, la prima preparazione DRM su un nuovo dispositivo potrebbe anche richiedere il provisioning, gestito internamente da prepareDrm()
, e potrebbe richiedere un po' di tempo per essere completata a causa delle operazioni di rete coinvolte. Puoi evitare il blocco su prepareDrm()
definendo e impostando un MediaPlayer.OnDrmPreparedListener
.
Imposta un OnDrmPreparedListener
. prepareDrm()
esegue il provisioning (se necessario) e la preparazione in background. Al termine del provisioning
e della preparazione, il sistema chiama l'ascoltatore. Non fare supposizioni sulla sequenza di chiamate o sul thread in cui viene eseguito l'ascoltatore (a meno che non registri l'ascoltatore con un thread di gestore). Il sistema può chiamare il listener prima o dopo il ritorno di prepareDrm()
.
Configurare il DRM in modo asincrono
Puoi inizializzare il DRM in modo asincrono creando e registrando il messaggio MediaPlayer.OnDrmInfoListener
per la preparazione del DRM e il messaggio MediaPlayer.OnDrmPreparedListener
per avviare il player. Funzionano in combinazione con prepareAsync()
, come mostrato in questo esempio:
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();
}
Gestire i contenuti multimediali criptati
A partire da Android 8.0 (livello API 26), MediaPlayer
può anche decriptare i contenuti multimediali criptati a livello di Sample con Common Encryption Scheme (CENC) e HLS (METHOD=SAMPLE-AES) per i tipi di stream elementari H.264 e AAC. In precedenza, i contenuti multimediali con crittografia del segmento completo (METHOD=AES-128) erano supportati.
Scopri di più
Jetpack Media3 è la soluzione consigliata per la riproduzione di contenuti multimediali nella tua app. Scopri di più.
Queste pagine trattano argomenti relativi alla registrazione, allo stoccaggio e alla riproduzione di audio e video: