Работа с MediaPlayer и управлением цифровыми правами (DRM)

Начиная с Android 8.0 (уровень API 26), MediaPlayer включает API, поддерживающие воспроизведение материалов, защищенных DRM. API MediaPlayer для DRM аналогичны низкоуровневому API, предоставляемому MediaDrm , но работают на более высоком уровне и не предоставляют доступ к базовым объектам извлечения, DRM и криптографии.

Хотя API DRM для MediaPlayer не предоставляет полный функционал MediaDrm , он поддерживает наиболее распространенные сценарии использования. Текущая реализация может обрабатывать следующие типы контента:

  • Локальные медиафайлы, защищенные Widevine
  • Защищенные Widevine удаленные или потоковые медиафайлы

Приведённый ниже фрагмент кода демонстрирует, как использовать новые методы DRM MediaPlayer в синхронной реализации.

Для управления медиафайлами, защищенными DRM, необходимо добавить новые методы к обычному потоку вызовов MediaPlayer, как показано в этом примере:

Котлин

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();

Для начала инициализируйте объект MediaPlayer и установите его источник с помощью setDataSource() , как обычно. Затем, чтобы использовать DRM, выполните следующие действия:

  1. Если вы хотите, чтобы ваше приложение выполняло пользовательскую настройку, определите интерфейс OnDrmConfigHelper и прикрепите его к плееру с помощью setOnDrmConfigHelper() .
  2. Вызовите метод prepare() .
  3. Вызовите метод getDrmInfo() . Если источник содержит контент с DRM-защитой, метод вернет ненулевое значение MediaPlayer.DrmInfo .

Если MediaPlayer.DrmInfo существует:

  1. Изучите карту доступных UUID и выберите один из них.
  2. Подготовьте конфигурацию DRM для текущего источника, вызвав функцию prepareDrm() .
    • Если вы создали и зарегистрировали обратный вызов OnDrmConfigHelper , он вызывается во время выполнения prepareDrm() . Это позволяет выполнить пользовательскую настройку свойств DRM перед открытием сессии DRM. Обратный вызов выполняется синхронно в потоке, который вызвал prepareDrm() . Для доступа к свойствам DRM вызовите getDrmPropertyString() и setDrmPropertyString() . Избегайте выполнения длительных операций.
    • Если устройство еще не было подготовлено, prepareDrm() также обращается к серверу подготовки для его подготовки. Это может занять различное количество времени в зависимости от скорости сетевого соединения.
  3. Чтобы получить непрозрачный массив байтов запроса ключа для отправки на сервер лицензий, вызовите функцию getKeyRequest() .
  4. Чтобы сообщить системе DRM о ключевом ответе, полученном от лицензионного сервера, вызовите метод provideKeyResponse() . Результат зависит от типа запроса ключа:
    • Если ответ относится к запросу ключа в автономном режиме, результатом является идентификатор набора ключей. Вы можете использовать этот идентификатор набора ключей с restoreKeys() для восстановления ключей в новой сессии.
    • Если ответ относится к запросу на потоковую передачу или релиз, результат равен null.

Подготовка DRM асинхронно.

By default, prepareDrm() runs synchronously, blocking until preparation finishes. However, the very first DRM preparation on a new device may also require provisioning, which prepareDrm() handles internally, and may take some time to finish due to the network operation involved. You can avoid blocking on prepareDrm() by defining and setting a MediaPlayer.OnDrmPreparedListener .

Установите обработчик OnDrmPreparedListener . prepareDrm() выполняет подготовку (при необходимости) и выделение ресурсов в фоновом режиме. После завершения подготовки и выделения ресурсов система вызывает обработчик. Не следует делать никаких предположений о последовательности вызовов или потоке, в котором работает обработчик (если только вы не зарегистрируете обработчик в потоке обработчика). Система может вызвать обработчик до или после возврата из prepareDrm() .

Настройка DRM в асинхронном режиме

Асинхронную инициализацию DRM можно выполнить, создав и зарегистрировав MediaPlayer.OnDrmInfoListener для подготовки DRM и MediaPlayer.OnDrmPreparedListener для запуска проигрывателя. Они работают совместно с prepareAsync() , как показано в этом примере:

Котлин

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();
}

Обработка зашифрованных медиафайлов

Начиная с Android 8.0 (уровень API 26), MediaPlayer также может расшифровывать медиафайлы, зашифрованные с помощью Common Encryption Scheme (CENC) и HLS на уровне выборок (METHOD=SAMPLE-AES) для элементарных типов потоков H.264 и AAC. Ранее поддерживалась расшифровка медиафайлов, зашифрованных с помощью Full-Segment (METHOD=AES-128).

Узнать больше

Jetpack Media3 — рекомендуемое решение для воспроизведения мультимедиа в вашем приложении. Узнайте больше об этом.

На этих страницах рассматриваются вопросы, касающиеся записи, хранения и воспроизведения аудио- и видеоматериалов: