Что такое ЭМЕ?

Encrypted Media Extensions предоставляет API, который позволяет веб-приложениям взаимодействовать с системами защиты контента, позволяя воспроизводить зашифрованные аудио и видео.

EME разработан так, чтобы одно и то же приложение и зашифрованные файлы можно было использовать в любом браузере, независимо от базовой системы защиты. Первое стало возможным благодаря стандартизированным API и потоку, а второе стало возможным благодаря концепции общего шифрования .

EME — это расширение спецификации HTMLMediaElement — отсюда и название. Будучи «расширением», означает, что поддержка EME браузером не является обязательной: если браузер не поддерживает зашифрованные носители, он не сможет воспроизводить зашифрованные носители, но EME не требуется для соответствия спецификациям HTML. Из спецификации EME :

Это предложение расширяет HTMLMediaElement, предоставляя API для управления воспроизведением защищенного контента.

API поддерживает различные варианты использования: от простой расшифровки с помощью открытого ключа до видео высокой ценности (при соответствующей реализации пользовательского агента). Обмен лицензиями/ключами контролируется приложением, что облегчает разработку надежных приложений воспроизведения, поддерживающих ряд технологий дешифрования и защиты контента.

Эта спецификация не определяет систему защиты контента или управления цифровыми правами. Скорее, он определяет общий API, который можно использовать для обнаружения, выбора и взаимодействия с такими системами, а также с более простыми системами шифрования контента. Внедрение управления цифровыми правами не требуется для соответствия этой спецификации: необходимо внедрить только систему Clear Key в качестве общей базовой версии.

Общий API поддерживает простой набор возможностей шифрования контента, оставляя функции приложения, такие как аутентификация и авторизация, на усмотрение авторов страниц. Это достигается за счет требования, чтобы сообщения, специфичные для системы защиты контента, передавались через страницу, а не за счет внеполосной связи между системой шифрования и лицензией или другим сервером.

Реализации EME используют следующие внешние компоненты:

  • Ключевая система: механизм защиты контента (DRM). EME не определяет сами системы ключей, за исключением Clear Key (подробнее об этом ниже ).
  • Модуль расшифровки контента (CDM): программный или аппаратный механизм на стороне клиента, который позволяет воспроизводить зашифрованные носители. Как и в случае с ключевыми системами, EME не определяет никаких CDM, но предоставляет приложениям интерфейс для взаимодействия с доступными CDM.
  • Сервер лицензий (ключей): взаимодействует с CDM для предоставления ключей для расшифровки мультимедиа. За согласование с сервером лицензий отвечает приложение.
  • Служба упаковки: кодирует и шифрует носители для распространения/потребления.

Обратите внимание, что приложение, использующее EME, взаимодействует с сервером лицензий, чтобы получить ключи для дешифрования, но идентификация и аутентификация пользователя не являются частью EME. Получение ключей для включения воспроизведения мультимедиа происходит после (необязательно) аутентификации пользователя. Такие службы, как Netflix, должны аутентифицировать пользователей в своем веб-приложении: когда пользователь входит в приложение, приложение определяет его личность и привилегии.

Как работает ЭМЕ?

Вот как взаимодействуют компоненты EME, что соответствует примеру кода ниже :

Если доступно несколько форматов или кодеков, для выбора правильного можно использовать MediaSource.isTypeSupported() или HTMLMediaElement.canPlayType() . Однако CDM может поддерживать только часть того, что браузер поддерживает для незашифрованного контента. Лучше всего согласовать конфигурацию MediaKeys перед выбором формата и кодека. Если приложение ожидает зашифрованного события, но затем MediaKeys показывает, что оно не может обработать выбранный формат/кодек, возможно, уже слишком поздно переключиться, не прерывая воспроизведение.

Рекомендуемый порядок действий — сначала согласовать MediaKeys, используя MediaKeysSystemAccess.getConfiguration(), чтобы узнать согласованную конфигурацию.

Если на выбор доступен только один формат/кодек, то нет необходимости в getConfiguration(). Однако все же предпочтительнее сначала настроить MediaKeys. Единственная причина ждать зашифрованного события — это отсутствие способа узнать, зашифрован контент или нет, но на практике это маловероятно.

  1. Веб-приложение пытается воспроизвести аудио или видео, содержащее один или несколько зашифрованных потоков.
  2. Браузер распознает, что носитель зашифрован (о том, как это происходит, см. в поле ниже), и запускает зашифрованное событие с метаданными (initData), полученными с носителя о шифровании.
  3. Приложение обрабатывает зашифрованное событие:

    1. Если объект MediaKeys не связан с медиа-элементом, сначала выберите доступную систему ключей с помощью navigator.requestMediaKeySystemAccess(), чтобы проверить, какие системы ключей доступны, затем создайте объект MediaKeys для доступной системы ключей с помощью объекта MediaKeySystemAccess. Обратите внимание, что инициализация объекта MediaKeys должна произойти до первого зашифрованного события. Получение URL-адреса сервера лицензий осуществляется приложением независимо от выбора доступной системы ключей. Объект MediaKeys представляет все ключи, доступные для расшифровки мультимедиа для аудио- или видеоэлемента. Он представляет собой экземпляр CDM и обеспечивает доступ к CDM, в частности, для создания сеансов ключей, которые используются для получения ключей с сервера лицензий.

    2. После создания объекта MediaKeys назначьте его медиа-элементу: setMediaKeys() связывает объект MediaKeys с HTMLMediaElement, чтобы его ключи можно было использовать во время воспроизведения, то есть во время декодирования.

  4. Приложение создает MediaKeySession, вызывая createSession() для MediaKeys. При этом создается MediaKeySession, который представляет срок действия лицензии и ее ключей.

  5. Приложение генерирует запрос лицензии, передавая мультимедийные данные, полученные в зашифрованном обработчике, в CDM, вызывая методgenerateRequest() в MediaKeySession.

  6. CDM запускает событие сообщения: запрос на получение ключа от сервера лицензий.

  7. Объект MediaKeySession получает событие сообщения, и приложение отправляет сообщение на сервер лицензий (например, через XHR).

  8. Приложение получает ответ от сервера лицензий и передает данные в CDM, используя метод update() сеанса MediaKeySession.

  9. CDM расшифровывает носитель, используя ключи лицензии. Можно использовать действительный ключ из любого сеанса в пределах MediaKeys, связанного с медиа-элементом. CDM получит доступ к ключу и политике, индексированным по идентификатору ключа.

Воспроизведение мультимедиа возобновляется.

Как браузер узнает, что медиафайлы зашифрованы?

Эта информация находится в метаданных файла медиаконтейнера, который будет иметь такой формат, как ISO BMFF или WebM. Для ISO BMFF это означает метаданные заголовка, называемые информационным блоком схемы защиты. WebM использует элемент Matroska ContentEncryption с некоторыми дополнениями, специфичными для WebM. Рекомендации предоставляются для каждого контейнера в реестре EME.

Обратите внимание, что между CDM и сервером лицензий может быть несколько сообщений, и вся связь в этом процессе непрозрачна для браузера и приложения: сообщения понимаются только CDM и сервером лицензий, хотя уровень приложения может видеть, какой тип сообщения CDM отправляет. Запрос лицензии содержит подтверждение действительности CDM (и доверительных отношений), а также ключ, который будет использоваться при шифровании ключа(ов) контента в полученной лицензии.

Но что на самом деле делают CDM?

Реализация EME сама по себе не обеспечивает способ расшифровки мультимедиа: она просто предоставляет API для взаимодействия веб-приложения с модулями расшифровки контента.

То, что на самом деле делают CDM, не определено спецификацией EME, и CDM может обрабатывать как декодирование (распаковку) мультимедиа, так и дешифрование. Существует несколько потенциальных вариантов функциональности CDM, от наименее до наиболее надежного:

  • Только расшифровка, обеспечивающая воспроизведение с использованием обычного медиаконвейера, например, через элемент <video>.
  • Расшифровка и декодирование, передача видеокадров в браузер для рендеринга.
  • Расшифровка и декодирование, рендеринг непосредственно в оборудовании (например, в графическом процессоре).

Существует несколько способов сделать CDM доступным для веб-приложения:

  • Объедините CDM с браузером.
  • Распространите CDM отдельно.
  • Встройте CDM в операционную систему.
  • Включите CDM в прошивку.
  • Встройте CDM в аппаратное обеспечение.

Способ предоставления CDM не определяется спецификацией EME, но во всех случаях браузер несет ответственность за проверку и раскрытие CDM.

EME не требует наличия конкретной системы ключей; Среди современных настольных и мобильных браузеров Chrome поддерживает Widevine, а IE11 поддерживает PlayReady.

Получение ключа с сервера лицензий

При типичном коммерческом использовании контент шифруется и кодируется с помощью службы или инструмента упаковки. Как только зашифрованный носитель становится доступным в Интернете, веб-клиент может получить ключ (содержащийся в лицензии) с сервера лицензий и использовать его для расшифровки и воспроизведения контента.

Следующий код (адаптированный из примеров спецификации ) показывает, как приложение может выбрать подходящую систему ключей и получить ключ с сервера лицензий.

    var video = document.querySelector('video');

    var config = [{initDataTypes: ['webm'],
      videoCapabilities: [{contentType: 'video/webm; codecs="vp09.00.10.08"'}]}];

    if (!video.mediaKeys) {
      navigator.requestMediaKeySystemAccess('org.w3.clearkey',
          config).then(
        function(keySystemAccess) {
          var promise = keySystemAccess.createMediaKeys();
          promise.catch(
            console.error.bind(console, 'Unable to create MediaKeys')
          );
          promise.then(
            function(createdMediaKeys) {
              return video.setMediaKeys(createdMediaKeys);
            }
          ).catch(
            console.error.bind(console, 'Unable to set MediaKeys')
          );
          promise.then(
            function(createdMediaKeys) {
              var initData = new Uint8Array([...]);
              var keySession = createdMediaKeys.createSession();
              keySession.addEventListener('message', handleMessage,
                  false);
              return keySession.generateRequest('webm', initData);
            }
          ).catch(
            console.error.bind(console,
              'Unable to create or initialize key session')
          );
        }
      );
    }

    function handleMessage(event) {
      var keySession = event.target;
      var license = new Uint8Array([...]);
      keySession.update(license).catch(
        console.error.bind(console, 'update() failed')
      );
    }

Общее шифрование

Решения Common Encryption позволяют поставщикам контента шифровать и упаковывать свой контент один раз для каждого контейнера/кодека и использовать его с различными ключевыми системами, CDM и клиентами: то есть с любым CDM, поддерживающим Common Encryption. Например, видео, упакованное с помощью Playready, можно воспроизвести в браузере с помощью CDM Widevine, получившего ключ с сервера лицензий Widevine.

В этом отличие от устаревших решений, которые работали только с полным вертикальным стеком, включая один клиент, который часто также включал среду выполнения приложения.

Common Encryption (CENC) — это стандарт ISO , определяющий схему защиты ISO BMFF; аналогичная концепция применима и к WebM.

Очистить ключ

Хотя EME не определяет функциональность DRM, в настоящее время спецификация требует, чтобы все браузеры, поддерживающие EME, реализовывали Clear Key. Используя эту систему, медиафайлы можно зашифровать с помощью ключа, а затем воспроизвести, просто предоставив этот ключ. Clear Key может быть встроен в браузер: он не требует использования отдельного модуля расшифровки.

Хотя Clear Key вряд ли будет использоваться для многих типов коммерческого контента, он полностью совместим со всеми браузерами, поддерживающими EME. Это также удобно для тестирования реализаций EME и приложений, использующих EME, без необходимости запрашивать ключ контента с сервера лицензий. На simpl.info/ck есть простой пример Clear Key. Ниже приведено пошаговое описание кода, которое аналогично описанным выше шагам, но без взаимодействия с сервером лицензий.

// Define a key: hardcoded in this example
// – this corresponds to the key used for encryption
var KEY = new Uint8Array([
  0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, 0x68, 0xef, 0x12, 0x2a, 0xfc,
  0xe4, 0xae, 0x3c,
]);

var config = [
  {
    initDataTypes: ['webm'],
    videoCapabilities: [
      {
        contentType: 'video/webm; codecs="vp8"',
      },
    ],
  },
];

var video = document.querySelector('video');
video.addEventListener('encrypted', handleEncrypted, false);

navigator
  .requestMediaKeySystemAccess('org.w3.clearkey', config)
  .then(function (keySystemAccess) {
    return keySystemAccess.createMediaKeys();
  })
  .then(function (createdMediaKeys) {
    return video.setMediaKeys(createdMediaKeys);
  })
  .catch(function (error) {
    console.error('Failed to set up MediaKeys', error);
  });

function handleEncrypted(event) {
  var session = video.mediaKeys.createSession();
  session.addEventListener('message', handleMessage, false);
  session
    .generateRequest(event.initDataType, event.initData)
    .catch(function (error) {
      console.error('Failed to generate a license request', error);
    });
}

function handleMessage(event) {
  // If you had a license server, you would make an asynchronous XMLHttpRequest
  // with event.message as the body.  The response from the server, as a
  // Uint8Array, would then be passed to session.update().
  // Instead, we will generate the license synchronously on the client, using
  // the hard-coded KEY at the top.
  var license = generateLicense(event.message);

  var session = event.target;
  session.update(license).catch(function (error) {
    console.error('Failed to update the session', error);
  });
}

// Convert Uint8Array into base64 using base64url alphabet, without padding.
function toBase64(u8arr) {
  return btoa(String.fromCharCode.apply(null, u8arr))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=*$/, '');
}

// This takes the place of a license server.
// kids is an array of base64-encoded key IDs
// keys is an array of base64-encoded keys
function generateLicense(message) {
  // Parse the clearkey license request.
  var request = JSON.parse(new TextDecoder().decode(message));
  // We only know one key, so there should only be one key ID.
  // A real license server could easily serve multiple keys.
  console.assert(request.kids.length === 1);

  var keyObj = {
    kty: 'oct',
    alg: 'A128KW',
    kid: request.kids[0],
    k: toBase64(KEY),
  };
  return new TextEncoder().encode(
    JSON.stringify({
      keys: [keyObj],
    }),
  );
}

Чтобы протестировать этот код, вам понадобится зашифрованное видео для воспроизведения. Шифрование видео для использования с помощью Clear Key можно выполнить для WebM в соответствии с инструкциями webm_crypt. Также доступны коммерческие услуги (по крайней мере, для ISO BMFF/MP4) и разрабатываются другие решения.

HTMLMediaElement — это создание простой красоты.

Мы можем загружать, декодировать и воспроизводить мультимедиа, просто указав URL-адрес src:

<video src="foo.webm"></video>

API источника мультимедиа — это расширение HTMLMediaElement, обеспечивающее более детальный контроль над источником мультимедиа, позволяя JavaScript создавать потоки для воспроизведения из «кусков» видео. Это, в свою очередь, позволяет использовать такие методы, как адаптивная потоковая передача и сдвиг во времени.

Почему MSE важен для EME? Потому что помимо распространения защищенного контента поставщики коммерческого контента должны иметь возможность адаптировать доставку контента к условиям сети и другим требованиям. Netflix, например, динамически меняет битрейт потока при изменении условий сети. EME работает с воспроизведением медиапотоков, предоставляемых реализацией MSE, так же, как и с мультимедиа, предоставляемым через атрибут src.

Как разбить и воспроизвести медиафайлы, закодированные с разным битрейтом? См. раздел DASH ниже .

Вы можете увидеть MSE в действии по адресу simpl.info/mse ; для целей этого примера видео WebM разделено на пять частей с помощью API-интерфейсов файлов. В производственном приложении фрагменты видео будут извлекаться через AJAX.

Сначала создается SourceBuffer:

var sourceBuffer = mediaSource.addSourceBuffer(
  'video/webm; codecs="vorbis,vp8"',
);

Затем весь фильм «транслируется» в элемент видео путем добавления каждого фрагмента с помощью метода AppendBuffer():

reader.onload = function (e) {
  sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
  if (i === NUM_CHUNKS - 1) {
    mediaSource.endOfStream();
  } else {
    if (video.paused) {
      // start playing after first chunk is appended
      video.play();
    }
    readChunk_(++i);
  }
};

Узнайте больше о MSE в учебнике MSE .

Мульти-устройство, мультиплатформенность, мобильность — как бы вы это ни называли, Интернет часто работает в условиях изменчивого подключения. Динамическая, адаптивная доставка имеет решающее значение для преодоления ограничений пропускной способности и изменчивости в мире множества устройств.

DASH (также известный как MPEG-DASH) предназначен для обеспечения наилучшей доставки мультимедиа в нестабильном мире как для потоковой передачи, так и для загрузки. Некоторые другие технологии делают нечто подобное, например HTTP Live Streaming (HLS) от Apple и Smooth Streaming от Microsoft, но DASH — единственный метод потоковой передачи с адаптивным битрейтом через HTTP, основанный на открытом стандарте. DASH уже используется на таких сайтах, как YouTube.

Какое это имеет отношение к EME и MSE? Реализации DASH на основе MSE могут анализировать манифест, загружать сегменты видео с соответствующим битрейтом и передавать их видеоэлементу, когда он становится голодным, используя существующую инфраструктуру HTTP.

Другими словами, DASH позволяет поставщикам коммерческого контента осуществлять адаптивную потоковую передачу защищенного контента.

DASH делает то, что написано на банке:

  • Динамический: реагирует на изменяющиеся условия.
  • Адаптивный: адаптируется для обеспечения соответствующего битрейта аудио или видео.
  • Потоковая передача: позволяет как потоковую передачу, так и загрузку.
  • HTTP: обеспечивает доставку контента с преимуществами HTTP, без недостатков традиционного сервера потоковой передачи.

BBC начала предоставлять тестовые трансляции с использованием DASH :

Мультимедиа кодируется несколько раз с разными битрейтами. Каждая кодировка называется представлением. Они разделены на несколько медиа-сегментов. Клиент запускает программу, по порядку запрашивая сегменты из представления через HTTP. Представления могут быть сгруппированы в наборы адаптации представлений, содержащих эквивалентное содержание. Если клиент желает изменить битрейт, он может выбрать альтернативу из текущего набора адаптации и начать запрашивать сегменты из этого представления. Контент кодируется таким образом, чтобы клиенту было легко выполнить это переключение. В дополнение к ряду медиа-сегментов представление обычно также имеет сегмент инициализации. Его можно рассматривать как заголовок, содержащий информацию о кодировке, размерах кадров и т. д. Клиенту необходимо получить это для данного представления, прежде чем использовать медиасегменты из этого представления.

Подводя итог:

  1. Мультимедиа кодируется с разными битрейтами.
  2. Файлы с различным битрейтом доступны с HTTP-сервера.
  3. Клиентское веб-приложение выбирает битрейт для получения и воспроизведения с помощью DASH.

В рамках процесса сегментации видео программно создается XML-манифест, известный как описание медиапрезентации (MPD). Здесь описываются наборы адаптации и представления с длительностью и URL-адресами. МПД выглядит следующим образом:

    <MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" mediaPresentationDuration="PT0H3M1.63S" minBufferTime="PT1.5S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011"
    type="static">
      <Period duration="PT0H3M1.63S" start="PT0S">
        <AdaptationSet>
          <ContentComponent contentType="video" id="1" />
          <Representation bandwidth="4190760" codecs="avc1.640028" height="1080" id="1" mimeType="video/mp4" width="1920">
            <BaseURL>car-20120827-89.mp4</BaseURL>
            <SegmentBase indexRange="674-1149">
              <Initialization range="0-673" />
            </SegmentBase>
          </Representation>
          <Representation bandwidth="2073921" codecs="avc1.4d401f" height="720" id="2" mimeType="video/mp4" width="1280">
            <BaseURL>car-20120827-88.mp4</BaseURL>
            <SegmentBase indexRange="708-1183">
              <Initialization range="0-707" />
            </SegmentBase>
          </Representation>

                  </AdaptationSet>
      </Period>
    </MPD>

(Этот XML-файл взят из файла .mpd, используемого для демонстрационного проигрывателя YouTube DASH .)

Согласно спецификации DASH, файл MPD теоретически может использоваться в качестве источника видео. Однако, чтобы предоставить веб-разработчикам больше гибкости, производители браузеров решили оставить поддержку DASH на усмотрение библиотек JavaScript, использующих MSE, таких как Dash.js. Реализация DASH в JavaScript позволяет алгоритму адаптации развиваться без необходимости обновления браузера. Использование MSE также позволяет экспериментировать с альтернативными форматами манифестов и механизмами доставки, не требуя изменений в браузере. Google Shaka Player реализует клиент DASH с поддержкой EME.

В сети разработчиков Mozilla есть инструкции по использованию инструментов WebM и FFmpeg для сегментации видео и построения MPD.

Заключение

Использование Интернета для доставки платного видео и аудио растет огромными темпами . Кажется, что каждое новое устройство, будь то планшет, игровая консоль, подключенный телевизор или телеприставка, способно передавать потоковое мультимедиа от основных поставщиков контента через HTTP. Более 85% мобильных и настольных браузеров теперь поддерживают <video> и <audio>, и, по оценкам Cisco, к 2017 году видео будет составлять от 80 до 90 процентов глобального потребительского интернет-трафика. В этом контексте поддержка браузерами защищенного распространения контента, вероятно, будет становится все более значимым, поскольку производители браузеров сокращают поддержку API, на которые опирается большинство медиа-плагинов.

Дальнейшее чтение

Спецификации и стандарты

Спецификация EME : последний редакторский проект Common Encryption (CENC) Расширения медиа-источников : последний редакторский проект стандарта DASH (да, это PDF-файл) Обзор стандарта DASH

Статьи

Вебинар DTG (частично устаревший) Что такое EME? , Анри Сивонен. Учебное пособие по расширениям медиа-источников. Тестовые потоки MPEG-DASH: сообщение в блоге BBC R&D

Демо

Демонстрация Clear Key: демонстрация simpl.info/ck Media Source Extensions (MSE) Google Shaka Player реализует клиент DASH с поддержкой EME

Обратная связь