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
OnDrmConfigHelpere anexe-a ao player usandosetOnDrmConfigHelper(). - Chame
prepare(). - Chame
getDrmInfo(). Se a origem tiver conteúdo DRM, o método retornará um valorMediaPlayer.DrmInfonã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: