Lavorare con MediaPlayer e DRM (Digital Rights Management)
Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
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 utilizzando setOnDrmConfigHelper()
.
- Chiama il numero
prepare()
.
- Chiama il numero
getDrmInfo()
. Se l'origine contiene contenuti DRM, il metodo restituisce un valore MediaPlayer.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 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 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.
- 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.
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:
I campioni di contenuti e codice in questa pagina sono soggetti alle licenze descritte nella Licenza per i contenuti. Java e OpenJDK sono marchi o marchi registrati di Oracle e/o delle sue società consociate.
Ultimo aggiornamento 2025-07-27 UTC.
[[["Facile da capire","easyToUnderstand","thumb-up"],["Il problema è stato risolto","solvedMyProblem","thumb-up"],["Altra","otherUp","thumb-up"]],[["Mancano le informazioni di cui ho bisogno","missingTheInformationINeed","thumb-down"],["Troppo complicato/troppi passaggi","tooComplicatedTooManySteps","thumb-down"],["Obsoleti","outOfDate","thumb-down"],["Problema di traduzione","translationIssue","thumb-down"],["Problema relativo a esempi/codice","samplesCodeIssue","thumb-down"],["Altra","otherDown","thumb-down"]],["Ultimo aggiornamento 2025-07-27 UTC."],[],[],null,["# Work with MediaPlayer and Digital Rights Management (DRM)\n\nStarting with Android 8.0 (API level 26), [`MediaPlayer`](/reference/android/media/MediaPlayer) includes APIs that\nsupport the playback of DRM-protected material. The MediaPlayer DRM APIs are\nsimilar to the low-level API provided by [`MediaDrm`](/reference/android/media/MediaDrm), but they operate at a\nhigher level and don't expose the underlying extractor, DRM, and crypto objects.\n\nAlthough the MediaPlayer DRM API does not provide the full functionality of\n[`MediaDrm`](/reference/android/media/MediaDrm), it supports the most common use cases. The current\nimplementation can handle the following content types:\n\n- Widevine-protected local media files\n- Widevine-protected remote or streaming media files\n\nThe following code snippet demonstrates how to use the new DRM `MediaPlayer`\nmethods in a synchronous implementation.\n\nTo manage DRM-controlled media, you need to include the new methods alongside\nthe usual flow of MediaPlayer calls, as shown in this example: \n\n### Kotlin\n\n mediaPlayer?.apply {\n setDataSource()\n setOnDrmConfigHelper() // optional, for custom configuration\n prepare()\n drmInfo?.also {\n prepareDrm()\n getKeyRequest()\n provideKeyResponse()\n }\n\n // MediaPlayer is now ready to use\n start()\n // ...play/pause/resume...\n stop()\n releaseDrm()\n }\n\n### Java\n\n setDataSource();\n setOnDrmConfigHelper(); // optional, for custom configuration\n prepare();\n if (getDrmInfo() != null) {\n prepareDrm();\n getKeyRequest();\n provideKeyResponse();\n }\n\n // MediaPlayer is now ready to use\n start();\n // ...play/pause/resume...\n stop();\n releaseDrm();\n\nStart by initializing the [`MediaPlayer`](/reference/android/media/MediaPlayer) object and setting its source using\n[`setDataSource()`](/reference/android/media/MediaPlayer#setDataSource(android.content.Context,%20android.net.Uri)), as usual. Then, to use DRM, perform these steps:\n\n1. If you want your app to perform custom configuration, define an [`OnDrmConfigHelper`](/reference/android/media/MediaPlayer.OnDrmConfigHelper) interface, and attach it to the player using [`setOnDrmConfigHelper()`](/reference/android/media/MediaPlayer#setOnDrmConfigHelper(android.media.MediaPlayer.OnDrmConfigHelper)).\n2. Call [`prepare()`](/reference/android/media/MediaPlayer#prepare()).\n3. Call [`getDrmInfo()`](/reference/android/media/MediaPlayer#getDrmInfo()). If the source has DRM content, the method returns a non-null [`MediaPlayer.DrmInfo`](/reference/android/media/MediaPlayer.DrmInfo) value.\n\nIf [`MediaPlayer.DrmInfo`](/reference/android/media/MediaPlayer.DrmInfo) exists:\n\n1. Examine the map of available UUIDs and choose one.\n2. Prepare the DRM configuration for the current source by calling [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)).\n - If you created and registered an [`OnDrmConfigHelper`](/reference/android/media/MediaPlayer.OnDrmConfigHelper) callback, it is called while [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) is executing. This lets you perform custom configuration of the DRM properties before opening the DRM session. The callback is called synchronously in the thread that called [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)). To access the DRM properties, call [`getDrmPropertyString()`](/reference/android/media/MediaPlayer#getDrmPropertyString(java.lang.String)) and [`setDrmPropertyString()`](/reference/android/media/MediaPlayer#setDrmPropertyString(java.lang.String,%20java.lang.String)). Avoid performing lengthy operations.\n - If the device has not yet been provisioned, [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) also accesses the provisioning server to provision the device. This can take a variable amount of time, depending on the network connectivity.\n3. To get an opaque key request byte array to send to a license server, call [`getKeyRequest()`](/reference/android/media/MediaPlayer#getKeyRequest(byte%5B%5D,%20byte%5B%5D,%20java.lang.String,%20int,%20java.util.Map%3Cjava.lang.String,%20java.lang.String%3E)).\n4. To inform the DRM engine about the key response received from the license server, call [`provideKeyResponse()`](/reference/android/media/MediaPlayer#provideKeyResponse(byte%5B%5D,%20byte%5B%5D)). The result depends on the type of key request:\n - If the response is for an offline key request, the result is a key-set identifier. You can use this key-set identifier with [`restoreKeys()`](/reference/android/media/MediaPlayer#restoreKeys(byte%5B%5D)) to restore the keys to a new session.\n - If the response is for a streaming or release request, the result is null.\n\nPrepare DRM asynchronously\n--------------------------\n\nBy default, [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) runs synchronously, blocking until preparation\nfinishes. However, the very first DRM preparation on a new device may also\nrequire provisioning, which [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) handles internally, and may take\nsome time to finish due to the network operation involved. You can avoid\nblocking on [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) by defining and setting a\n[`MediaPlayer.OnDrmPreparedListener`](/reference/android/media/MediaPlayer.OnDrmPreparedListener).\n\nSet an [`OnDrmPreparedListener`](/reference/android/media/MediaPlayer.OnDrmPreparedListener). [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) performs the\nprovisioning (if needed) and preparation in the background. When provisioning\nand preparation finish, the system calls the listener. Don't make any\nassumptions about the calling sequence or the thread in which the listener runs\n(unless you register the listener with a handler thread). The system can call\nthe listener before or after [`prepareDrm()`](/reference/android/media/MediaPlayer#prepareDrm(java.util.UUID)) returns.\n\nSet up DRM asynchronously\n-------------------------\n\nYou can initialize the DRM asynchronously by creating and registering the\n[`MediaPlayer.OnDrmInfoListener`](/reference/android/media/MediaPlayer.OnDrmInfoListener) for DRM preparation and the\n[`MediaPlayer.OnDrmPreparedListener`](/reference/android/media/MediaPlayer.OnDrmPreparedListener) to start the player. They work in\nconjunction with [`prepareAsync()`](/reference/android/media/MediaPlayer#prepareAsync()), as shown in this example: \n\n### Kotlin\n\n setOnPreparedListener()\n setOnDrmInfoListener()\n setDataSource()\n prepareAsync()\n // ...\n\n // If the data source content is protected you receive a call to the onDrmInfo() callback.\n override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) {\n mediaPlayer.apply {\n prepareDrm()\n getKeyRequest()\n provideKeyResponse()\n }\n }\n\n // When prepareAsync() finishes, you receive a call to the onPrepared() callback.\n // If there is a DRM, onDrmInfo() sets it up before executing this callback,\n // so you can start the player.\n override fun onPrepared(mediaPlayer: MediaPlayer) {\n mediaPlayer.start()\n }\n\n### Java\n\n setOnPreparedListener();\n setOnDrmInfoListener();\n setDataSource();\n prepareAsync();\n // ...\n\n // If the data source content is protected you receive a call to the onDrmInfo() callback.\n onDrmInfo() {\n prepareDrm();\n getKeyRequest();\n provideKeyResponse();\n }\n\n // When prepareAsync() finishes, you receive a call to the onPrepared() callback.\n // If there is a DRM, onDrmInfo() sets it up before executing this callback,\n // so you can start the player.\n onPrepared() {\n\n start();\n }\n\nHandle encrypted media\n----------------------\n\nStarting with Android 8.0 (API level 26) `MediaPlayer` can also decrypt Common\nEncryption Scheme (CENC) and HLS sample-level encrypted media\n(METHOD=SAMPLE-AES) for the elementary stream types H.264, and AAC. Full-segment\nencrypted media (METHOD=AES-128) was previously supported.\n\nLearn more\n----------\n\nJetpack Media3 is the recommended solution for media playback in your app. [Read\nmore](/media/media3) about it.\n\nThese pages cover topics relating to recording, storing, and playing back audio\nand video:\n\n- [Supported Media Formats](/guide/topics/media/media-formats)\n- [MediaRecorder](/guide/topics/media/mediarecorder)\n- [Data Storage](/guide/topics/data/data-storage)"]]