A partir do Android 8.0 (nível 26 da API), MediaPlayer inclui APIs que oferecem suporte à 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 subjacentes.
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 remotos ou de streaming protegidos pelo Widevine
O snippet de código a seguir 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 por meio de
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
OnDrmConfigHelperinterface e 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
OnDrmConfigHelpercallback, 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 correspondente. 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 conexão de rede.
- Se você criou e registrou um
- 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 de 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 prepareDrm() processa internamente e pode demorar
para ser concluído devido à operação de rede envolvida. Você pode 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 forem concluídos, o sistema vai chamar o listener. Não faça nenhuma suposição 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), a MediaPlayer também pode descriptografar mídia criptografada em nível de amostra com 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 reprodução de mídia no seu app. Saiba mais.
Essas páginas abrangem tópicos relacionados à gravação, ao armazenamento e à reprodução de áudio e vídeo: