Lavorare con MediaPlayer e DRM (Digital Rights Management)

A partire da Android 8.0 (livello API 26), MediaPlayer include API che supportano la riproduzione di materiale protetto da DRM. Le API DRM di MediaPlayer sono simili all'API di basso livello fornita da MediaDrm, ma operano a un livello superiore e non espongono gli oggetti sottostanti di estrazione, DRM e crittografia.

Sebbene l'API DRM di MediaPlayer non fornisca tutte le funzionalità di MediaDrm, supporta i casi d'uso più comuni. L'implementazione attuale può gestire i seguenti tipi di contenuti:

  • File multimediali locali protetti da Widevine
  • File multimediali remoti o di streaming 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 controllati da DRM, devi includere i nuovi metodi insieme al flusso abituale delle 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. Poi, per utilizzare DRM, segui questi passaggi:

  1. Se vuoi che la tua app esegua una configurazione personalizzata, definisci un' OnDrmConfigHelper interfaccia e collegala al player utilizzando setOnDrmConfigHelper().
  2. Chiama prepare().
  3. Chiama getDrmInfo(). Se l'origine contiene contenuti DRM, il metodo restituisce un valore MediaPlayer.DrmInfo non nullo.

Se MediaPlayer.DrmInfo esiste:

  1. Esamina la mappa degli UUID disponibili e scegliene uno.
  2. Prepara la configurazione DRM per l'origine corrente chiamando prepareDrm().
    • Se hai creato e registrato un OnDrmConfigHelper callback, viene chiamato durante l'esecuzione di prepareDrm(). 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 chiamato prepareDrm(). Per accedere alle proprietà DRM, chiama getDrmPropertyString() e setDrmPropertyString(). Evita di eseguire operazioni lunghe.
    • Se il dispositivo non è ancora stato sottoposto a provisioning, 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.
  3. Per ottenere un array di byte di richiesta di chiave opaca da inviare a un server di licenze, chiama getKeyRequest().
  4. Per informare il motore DRM della risposta della chiave ricevuta dal server di 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 del set di chiavi. Puoi utilizzare questo identificatore del set di chiavi con restoreKeys() per ripristinare le chiavi in una nuova sessione.
    • Se la risposta riguarda una richiesta di streaming o di rilascio, il risultato è null.

Preparare DRM in modo asincrono

Per impostazione predefinita, prepareDrm() viene eseguito in modo sincrono, bloccando l'esecuzione fino al termine della preparazione. Tuttavia, la prima preparazione DRM su un nuovo dispositivo potrebbe anche richiedere il provisioning, che prepareDrm() gestisce internamente e il cui completamento potrebbe richiedere del tempo a causa dell'operazione di rete coinvolta. 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 il listener. Non fare ipotesi sulla sequenza di chiamate o sul thread in cui viene eseguito il listener (a meno che tu non registri il listener con un thread di gestione). Il sistema può chiamare il listener prima o dopo la restituzione di prepareDrm().

Configurare DRM in modo asincrono

Puoi inizializzare DRM in modo asincrono creando e registrando il MediaPlayer.OnDrmInfoListener per la preparazione DRM e il MediaPlayer.OnDrmPreparedListener per avviare il player. Questi listener 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 campione Common Encryption Scheme (CENC) e HLS (METHOD=SAMPLE-AES) per i tipi di stream elementari H.264 e AAC. In precedenza erano supportati i contenuti multimediali criptati a livello di segmento completo (METHOD=AES-128).

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, all'archiviazione e alla riproduzione di audio e video: