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 usandosetOnDrmConfigHelper()
. - Chame
prepare()
. - Chame
getDrmInfo()
. Se a origem tiver conteúdo DRM, o método retornará um valorMediaPlayer.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 enquantoprepareDrm()
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 chamouprepareDrm()
. Para acessar as propriedades de DRM, chamegetDrmPropertyString()
esetDrmPropertyString()
. 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.
- Se você criou e registrou um callback
- 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.
- 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
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: