Trabalhar com MediaPlayer e Gerenciamento de direitos digitais (DRM)
Mantenha tudo organizado com as coleções
Salve e categorize o conteúdo com base nas suas preferências.
A partir do Android 8.0 (nível 26 da API), a MediaPlayer
inclui APIs compatíveis com a
reprodução de material protegido por DRM. As APIs MediaPlayer DRM são
semelhantes à API de baixo nível fornecida por MediaDrm
, mas operam em um
nível mais alto e não expõem o extrator, o DRM e os objetos criptografados.
Embora a API MediaPlayer DRM não ofereça a funcionalidade completa de
MediaDrm
, ela é compatível com os casos de uso mais comuns. A implementação
atual pode processar os seguintes tipos de conteúdo:
- Arquivos locais de mídia protegidos pelo Widevine
- Arquivos de mídia remota ou de streaming protegidos pelo Widevine
O snippet de código abaixo demonstra como usar os novos métodos MediaPlayer
DRM em uma implementação síncrona.
Para gerenciar mídia controlada por DRM, é preciso incluir os novos métodos junto do
fluxo normal de chamadas da MediaPlayer, conforme mostrado neste exemplo:
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();
Comece inicializando o objeto MediaPlayer
e definindo a origem dele usando
setDataSource()
, como de costume. Em seguida, siga estas etapas para usar o DRM:
- Se você quiser que seu app faça uma configuração personalizada, defina uma
interface
OnDrmConfigHelper
e anexe-a ao player usando
setOnDrmConfigHelper()
.
- Chame
prepare()
.
- Chame
getDrmInfo()
. Se a origem tiver conteúdo DRM, o método retornará
um valor MediaPlayer.DrmInfo
não nulo.
Se MediaPlayer.DrmInfo
existir:
- analise o mapa dos UUIDs disponíveis e escolha um;
- Prepare a configuração de DRM para a origem atual chamando
prepareDrm()
.
- Se você criou e registrou um callback
OnDrmConfigHelper
, ele
será chamado enquanto prepareDrm()
estiver em execução. Isso permite fazer a
configuração personalizada das propriedades de DRM antes de abrir a sessão
de DRM. O callback é chamado de forma síncrona na linha de execução que chamou
prepareDrm()
. Para acessar as propriedades de DRM, chame
getDrmPropertyString()
e setDrmPropertyString()
. Evite
realizar operações demoradas.
- Se o dispositivo ainda não tiver sido provisionado,
prepareDrm()
também
acessará o servidor de provisionamento para fazer isso. Isso pode levar
um tempo variável, dependendo da conectividade de rede.
- Para conseguir uma matriz de bytes de solicitação de chave opaca para enviar a um servidor de licença, chame
getKeyRequest()
.
- Para informar o mecanismo de DRM sobre a resposta de chave recebida do servidor de
licença, chame
provideKeyResponse()
. O resultado depende do tipo de
solicitação de chave:
- Se a resposta for para uma solicitação de chave off-line, o resultado será um identificador de conjunto
de chaves. Você pode usar esse identificador de conjunto de chaves com
restoreKeys()
para restaurar as chaves em uma nova sessão.
- Se a resposta for para uma solicitação de streaming ou liberação, o resultado será
nulo.
Preparar o DRM de forma assíncrona
Por padrão, prepareDrm()
é executado de forma síncrona, bloqueando até que a preparação
seja concluída. No entanto, a primeira preparação de DRM em um novo dispositivo também pode
exigir provisionamento, que é processado internamente por prepareDrm()
e pode demorar
para ser concluído devido à operação de rede envolvida. É possível evitar
o bloqueio em prepareDrm()
definindo e configurando um
MediaPlayer.OnDrmPreparedListener
.
Defina um OnDrmPreparedListener
. prepareDrm()
realiza o
provisionamento (se necessário) e a preparação em segundo plano. Quando o provisionamento
e a preparação são concluídos, o sistema chama o listener. Não faça
suposições sobre a sequência de chamada ou a linha de execução em que o listener é executado
(a menos que você registre o listener com uma linha de execução gerenciadora). O sistema pode chamar
o listener antes ou depois do retorno de prepareDrm()
.
Configurar o DRM de forma assíncrona
Você pode inicializar o DRM de forma assíncrona criando e registrando o
MediaPlayer.OnDrmInfoListener
para preparação de DRM e o
MediaPlayer.OnDrmPreparedListener
para iniciar o player. Eles funcionam em
conjunto com prepareAsync()
, conforme mostrado neste exemplo:
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();
}
Processar mídia criptografada
A partir do Android 8.0 (nível 26 da API), MediaPlayer
também pode descriptografar mídia criptografada em nível de amostra com o Common
Encryption Scheme (CENC) e HLS (METHOD=SAMPLE-AES) para os tipos básicos de streaming H.264 e AAC. A mídia criptografada de segmento
completo (METHOD=AES-128) era compatível anteriormente.
Saiba mais
O Jetpack Media3 é a solução recomendada para a reprodução de mídia no seu app. Saiba
mais.
Estas páginas abrangem tópicos relacionados à gravação, ao armazenamento e à reprodução de áudio
e vídeo:
O conteúdo e os exemplos de código nesta página estão sujeitos às licenças descritas na Licença de conteúdo. Java e OpenJDK são marcas registradas da Oracle e/ou suas afiliadas.
Última atualização 2025-07-27 UTC.
[[["Fácil de entender","easyToUnderstand","thumb-up"],["Meu problema foi resolvido","solvedMyProblem","thumb-up"],["Outro","otherUp","thumb-up"]],[["Não contém as informações de que eu preciso","missingTheInformationINeed","thumb-down"],["Muito complicado / etapas demais","tooComplicatedTooManySteps","thumb-down"],["Desatualizado","outOfDate","thumb-down"],["Problema na tradução","translationIssue","thumb-down"],["Problema com as amostras / o código","samplesCodeIssue","thumb-down"],["Outro","otherDown","thumb-down"]],["Última atualização 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)"]]