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. Единственная причина ждать зашифрованного события — это отсутствие способа узнать, зашифрован контент или нет, но на практике это маловероятно.
- Веб-приложение пытается воспроизвести аудио или видео, содержащее один или несколько зашифрованных потоков.
- Браузер распознает, что носитель зашифрован (о том, как это происходит, см. в поле ниже), и запускает зашифрованное событие с метаданными (initData), полученными с носителя о шифровании.
Приложение обрабатывает зашифрованное событие:
Если объект MediaKeys не связан с медиа-элементом, сначала выберите доступную систему ключей с помощью navigator.requestMediaKeySystemAccess(), чтобы проверить, какие системы ключей доступны, затем создайте объект MediaKeys для доступной системы ключей с помощью объекта MediaKeySystemAccess. Обратите внимание, что инициализация объекта MediaKeys должна произойти до первого зашифрованного события. Получение URL-адреса сервера лицензий осуществляется приложением независимо от выбора доступной системы ключей. Объект MediaKeys представляет все ключи, доступные для расшифровки мультимедиа для аудио- или видеоэлемента. Он представляет собой экземпляр CDM и обеспечивает доступ к CDM, в частности, для создания сеансов ключей, которые используются для получения ключей с сервера лицензий.
После создания объекта MediaKeys назначьте его медиа-элементу: setMediaKeys() связывает объект MediaKeys с HTMLMediaElement, чтобы его ключи можно было использовать во время воспроизведения, то есть во время декодирования.
Приложение создает MediaKeySession, вызывая createSession() для MediaKeys. При этом создается MediaKeySession, который представляет срок действия лицензии и ее ключей.
Приложение генерирует запрос лицензии, передавая мультимедийные данные, полученные в зашифрованном обработчике, в CDM, вызывая методgenerateRequest() в MediaKeySession.
CDM запускает событие сообщения: запрос на получение ключа от сервера лицензий.
Объект MediaKeySession получает событие сообщения, и приложение отправляет сообщение на сервер лицензий (например, через XHR).
Приложение получает ответ от сервера лицензий и передает данные в CDM, используя метод update() сеанса MediaKeySession.
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) и разрабатываются другие решения.
Связанная технология 1: Расширения источников мультимедиа (MSE)
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 .
Связанная технология 2. Динамическая адаптивная потоковая передача через HTTP (DASH).
Мульти-устройство, мультиплатформенность, мобильность — как бы вы это ни называли, Интернет часто работает в условиях изменчивого подключения. Динамическая, адаптивная доставка имеет решающее значение для преодоления ограничений пропускной способности и изменчивости в мире множества устройств.
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. Представления могут быть сгруппированы в наборы адаптации представлений, содержащих эквивалентное содержание. Если клиент желает изменить битрейт, он может выбрать альтернативу из текущего набора адаптации и начать запрашивать сегменты из этого представления. Контент кодируется таким образом, чтобы клиенту было легко выполнить это переключение. В дополнение к ряду медиа-сегментов представление обычно также имеет сегмент инициализации. Его можно рассматривать как заголовок, содержащий информацию о кодировке, размерах кадров и т. д. Клиенту необходимо получить это для данного представления, прежде чем использовать медиасегменты из этого представления.
Подводя итог:
- Мультимедиа кодируется с разными битрейтами.
- Файлы с различным битрейтом доступны с HTTP-сервера.
- Клиентское веб-приложение выбирает битрейт для получения и воспроизведения с помощью 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
Обратная связь
,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. Единственная причина ждать зашифрованного события — это отсутствие возможности узнать, зашифрован контент или нет, но на практике это маловероятно.
- Веб-приложение пытается воспроизвести аудио или видео, содержащее один или несколько зашифрованных потоков.
- Браузер распознает, что носитель зашифрован (см. поле ниже, как это происходит), и запускает зашифрованное событие с метаданными (initData), полученными с носителя о шифровании.
Приложение обрабатывает зашифрованное событие:
Если объект MediaKeys не связан с медиа-элементом, сначала выберите доступную систему ключей с помощью navigator.requestMediaKeySystemAccess(), чтобы проверить, какие системы ключей доступны, затем создайте объект MediaKeys для доступной системы ключей с помощью объекта MediaKeySystemAccess. Обратите внимание, что инициализация объекта MediaKeys должна произойти до первого зашифрованного события. Получение URL-адреса сервера лицензий осуществляется приложением независимо от выбора доступной системы ключей. Объект MediaKeys представляет все ключи, доступные для расшифровки мультимедиа для аудио- или видеоэлемента. Он представляет собой экземпляр CDM и обеспечивает доступ к CDM, в частности, для создания сеансов ключей, которые используются для получения ключей с сервера лицензий.
После создания объекта MediaKeys назначьте его медиа-элементу: setMediaKeys() связывает объект MediaKeys с HTMLMediaElement, чтобы его ключи можно было использовать во время воспроизведения, то есть во время декодирования.
Приложение создает MediaKeySession, вызывая createSession() для MediaKeys. При этом создается MediaKeySession, который представляет срок действия лицензии и ее ключей.
Приложение генерирует запрос лицензии, передавая мультимедийные данные, полученные в зашифрованном обработчике, в CDM, вызывая методgenerateRequest() в MediaKeySession.
CDM запускает событие сообщения: запрос на получение ключа от сервера лицензий.
Объект MediaKeySession получает событие сообщения, и приложение отправляет сообщение на сервер лицензий (например, через XHR).
Приложение получает ответ от сервера лицензий и передает данные в CDM, используя метод update() сеанса MediaKeySession.
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) и разрабатываются другие решения.
Связанная технология 1: Расширения источников мультимедиа (MSE)
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 .
Связанная технология 2. Динамическая адаптивная потоковая передача через HTTP (DASH).
Мульти-устройство, мультиплатформенность, мобильность — как бы вы это ни называли, Интернет часто работает в условиях изменчивого подключения. Динамическая, адаптивная доставка имеет решающее значение для преодоления ограничений пропускной способности и изменчивости в мире множества устройств.
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. Представления могут быть сгруппированы в наборы адаптации представлений, содержащих эквивалентное содержание. Если клиент желает изменить битрейт, он может выбрать альтернативу из текущего набора адаптации и начать запрашивать сегменты из этого представления. Контент кодируется таким образом, чтобы клиенту было легко выполнить это переключение. В дополнение к ряду медиа-сегментов представление обычно также имеет сегмент инициализации. Его можно рассматривать как заголовок, содержащий информацию о кодировке, размерах кадров и т. д. Клиенту необходимо получить это для данного представления, прежде чем использовать медиасегменты из этого представления.
Подводя итог:
- Мультимедиа кодируется с разными битрейтами.
- Различные файлы битрейта доступны на HTTP -сервере.
- Клиентское веб -приложение выбирает, какой битрейт для извлечения и воспроизведения с Dash.
В рамках процесса сегментации видео, XML -манифест, известный как описание презентации среды (MPD), создан программно. Это описывает наборы адаптации и представления, с продолжительностью и URL. MPD выглядит так:
<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, используемого для демонстрации Dash YouTube .)
Согласно спецификации DASH, файл MPD может быть теоретически использовать в качестве SRC для видео. Однако, чтобы дать большую гибкость веб -разработчикам, поставщики браузеров решили вместо этого оставить поддержку DASH в библиотеках JavaScript, используя MSE, такой как dash.js. Реализация Dash в JavaScript позволяет развиваться алгоритм адаптации, не требуя обновлений браузера. Использование MSE также позволяет экспериментировать с альтернативными манифестными форматами и механизмами доставки, не требуя изменений в браузере. Игрок Google Shaka реализует клиента Dash с поддержкой EME.
Mozilla Developer Network имеет инструкции по использованию инструментов WebM и FFMPEG для сегмента видео и создания MPD.
Заключение
Использование сети для доставки платного видео и аудио растет с огромной скоростью . Похоже, что каждое новое устройство, будь то планшет, игровая консоль, подключенная телевизор или серия, способно транслировать носитель от основных поставщиков контента по сравнению с HTTP. Более 85% мобильных и настольных браузеров в настоящее время поддерживают <ideo> и <Audio>, и Cisco к 2017 году составит от 80 до 90 процентов глобального потребительского интернет -трафика .
Дальнейшее чтение
Спецификации и стандарты
EME Spec : Проект Последнего редактора общего шифрования (CENC) Расширения источника СМИ : Стандарт Draft Dash последнего редактора (да, это PDF) Обзор стандарта DASH
Статьи
Вебинар DTG (частично устаревший) Что такое EME? , от Анри Сивоненс- Средства Средства Средства массовой информации праймер Mpeg-Dash Test Streams: BBC R & D Post в блоге
Демо
Clear Key Demo: Simpl.info/ck Media Source Extensions (MSE) Демо -игрок Google Shaka Player реализует клиента Dash с поддержкой EME
Обратная связь
,Зашифрованные средства массовой информации предоставляют API, который позволяет веб -приложениям взаимодействовать с системами защиты контента, чтобы обеспечить воспроизведение зашифрованного аудио и видео.
EME предназначена для того, чтобы использовать то же приложение и зашифрованные файлы для использования в любом браузере, независимо от базовой системы защиты. Первое стало возможным благодаря стандартизированным API и потоку, в то время как последний стал возможным благодаря концепции общего шифрования .
EME является расширением спецификации HTMLMEDIAEELEMENT - отсюда и название. Быть «расширением» означает, что поддержка браузера для EME не является обязательной: если браузер не поддерживает зашифрованные носители, он не сможет воспроизводить зашифрованные носители, но EME не требуется для соответствия спецификации HTML. От спецификации EME :
Это предложение расширяет HTMlMedieElement , обеспечивая API для контроля воспроизведения защищенного контента.
API поддерживает варианты использования, начиная от простых дешифрования клавиш, до видео с высоким значением (с учетом соответствующей реализации пользовательского агента). Лицензия/обмен ключами контролируется приложением, способствуя разработке надежных приложений для воспроизведения, поддерживающих ряд технологий расшифровки контента и защиты.
Эта спецификация не определяет систему защиты контента или цифрового управления правами. Скорее, он определяет общий API, который можно использовать для обнаружения, выбора и взаимодействия с такими системами, а также с более простыми системами шифрования контента. Внедрение управления цифровыми правами не требуется для соответствия этой спецификации: необходимо реализовать только прозрачную ключевую систему в качестве общего базового уровня.
Общий API поддерживает простой набор возможностей шифрования контента, оставляя такие функции приложений, как аутентификация и авторизация авторам страниц. Это достигается за счет того, что обмен сообщением для защиты контента, которые были опосредованы страницей, а не предполагали, что связь между системой шифрования и лицензией или другим сервером.
Реализации EME Используйте следующие внешние компоненты:
- Ключевая система: механизм защиты контента (DRM). EME не определяет сами ключевые системы, кроме прозрачного ключа (подробнее об этом ниже ).
- Модуль дешифрования контента (CDM): программный или аппаратный механизм на стороне клиента, который позволяет воспроизводить зашифрованные носители. Как и в случае с ключевыми системами, EME не определяет каких -либо CDM, но предоставляет интерфейс для взаимодействия приложений с доступными CDM.
- Сервер лицензии (ключ): взаимодействует с CDM, чтобы предоставить ключи для расшифровки носителя. Переговоры с сервером лицензий являются обязанностью приложения.
- Служба упаковки: кодирует и шифрует носитель для распространения/потребления.
Обратите внимание, что приложение, использующее EME, взаимодействует с сервером лицензий, чтобы получить ключи для включения дешифрования, но идентификация пользователя и аутентификация не являются частью EME. Поиск ключей для включения воспроизведения медиа происходит после (необязательно) аутентификации пользователя. Такие услуги, как Netflix, должны аутентифицировать пользователей в их веб -приложении: когда пользователь подписывает в приложение, приложение определяет идентичность и привилегии пользователя.
Как работает EME?
Вот как взаимодействуют компоненты EME, соответствующие примеру кода ниже :
Если доступны несколько форматов или кодеков, MediaSource.istypeSupported () или htmlMedieElement.CanPlayType () можно использовать для выбора правильного. Тем не менее, CDM может поддерживать только подмножество того, что поддерживает браузер для нерашифрованного контента. Лучше всего договориться о конфигурации Mediakeys, прежде чем выбрать формат и кодек. Если приложение ждет зашифрованного события, но тогда Mediakeys показывает, что оно не может обрабатывать выбранное формат/кодек, может быть слишком поздно переключаться без прерывания воспроизведения.
Рекомендуемый поток состоит в том, чтобы в первую очередь договориться о Mediakeys, используя Mediakeyssystemaccess.getConfiguration (), чтобы выяснить согласованную конфигурацию.
Если есть только один формат/кодек на выбор, то нет необходимости в getConfiguration (). Тем не менее, в первую очередь предпочтительно настроить медиакийс. Единственная причина, по которой будет ждать зашифрованного события, заключается в том, что нет возможности узнать, зашифрован ли контент или нет, но на практике это маловероятно.
- Веб -приложение пытается воспроизводить аудио или видео, которое имеет один или несколько зашифрованных потоков.
- Браузер признает, что средства массовой информации зашифрованы (см. Вставку ниже для того, как это происходит) и запускает зашифрованное событие с метаданными (initData), полученными от среды о шифровании.
Приложение обрабатывает зашифрованное событие:
Если ни один объект Mediakeys не был связан с элементом медиа, сначала выберите доступную систему ключей, используя Navigator.RequestMediaKeySystemaccess (), чтобы проверить, какие доступны ключевые системы, затем создайте объект MediaKeys для доступной системы ключей через объект MediaKeySySteMaccess. Обратите внимание, что инициализация объекта Mediakeys должна произойти до первого зашифрованного события. Получение URL -адреса сервера лицензий выполняется приложением независимо от выбора доступной ключевой системы. Объект Mediakeys представляет все ключи, доступные для расшифровки медиа для аудио или видео элемента. Он представляет экземпляр CDM и обеспечивает доступ к CDM, в частности для создания сеансов ключей, которые используются для получения клавиш с сервера лицензий.
Как только объект Mediakeys был создан, назначьте его элементу медиа: SetMediaKeys () связывает объект MediaKeys с HTMlMedieElement, чтобы его ключи можно было использовать во время воспроизведения, т.е. во время декодирования.
Приложение создает медиакисессию, вызывая CreateSession () на медиаки. Это создает медиакисессию, которая представляет собой срок службы лицензии и ее ключ (ы).
Приложение генерирует запрос на лицензию путем передачи данных среды, полученных в зашифрованном обработчике в CDM, позвонив GenateRequest () в MediaKeySession.
CDM запускает событие сообщения: запрос на получение ключа от сервера лицензий.
Объект MediaKeySession получает событие сообщения, а приложение отправляет сообщение на сервер лицензий (например, через XHR).
Приложение получает ответ от сервера лицензий и передает данные в CDM, используя метод Update () MediaKeySession.
CDM расшифровывает средства массовой информации, используя ключи в лицензии. Можно использовать допустимый ключ из любого сеанса в медиаки, связанных с элементом медиа. CDM будет получить доступ к ключу и политике, проиндексированной идентификатором ключа.
СМИ воспроизведение резюме.
Как браузер узнает, что СМИ зашифрованы?
Эта информация находится в метаданных файла контейнера для медиа -контейнера, который будет в таком формате, как ISO BMFF или WebM. Для ISO BMFF это означает метаданные заголовка, называемые информацией о схеме защиты. Webm использует элемент Matroska ContentEncryption с некоторыми дополнительными дополнениями. Руководящие принципы предоставляются для каждого контейнера в реестре EME-специфического.
Обратите внимание, что между CDM и сервером лицензий может быть несколько сообщений, и вся связь в этом процессе является непрозрачной для браузера и приложения: сообщения понимаются только CDM и сервером лицензий, хотя уровень приложения может видеть, какой тип сообщения отправляет CDM. Запрос лицензии содержит доказательство достоверности (и доверительных отношений CDM), а также ключ для использования при шифровании ключа (ы) контента в полученной лицензии.
Но что на самом деле делают CDM?
Реализация EME само по себе не предоставляет способ расшифровать медиа: она просто предоставляет API для веб -приложения для взаимодействия с модулями расшифровки контента.
То, что на самом деле делают CDM, не определяется спецификацией EME, и CDM может обрабатывать декодирование (декомпрессию) среды, а также расшифровку. От наименьшего до наиболее надежного, есть несколько потенциальных вариантов функциональности CDM:
- Только дешифрование, обеспечивая воспроизведение с использованием обычного медиа -конвейера, например, через элемент <dide>.
- Дешифрование и декодирование, передача видео кадров в браузер для рендеринга.
- Дешифрование и декодирование, рендеринг непосредственно в аппаратном обеспечении (например, графический процессор).
Есть несколько способов сделать 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')
);
}
Общее шифрование
Распространенные решения для шифрования позволяют поставщикам контента шифровать и упаковывать свой контент один раз на контейнер/кодек и использовать его с различными ключевыми системами, CDM и клиентами: то есть любой CDM, который поддерживает общее шифрование. Например, видео, упакованное с использованием PlayReady, может быть воспроизведено в браузере с использованием CDM Widevine, получившего ключ с сервера лицензий Widevine.
Это в отличие от устаревших решений, которые будут работать только с полным вертикальным стеком, включая одного клиента, который часто также включал время выполнения приложения.
Общее шифрование (CENC) - это стандарт ISO, определяющий схему защиты для ISO BMFF; Аналогичная концепция относится к WebM.
Чистый ключ
Хотя EME не определяет функциональность DRM, в настоящее время спецификация требует, чтобы все браузеры, поддерживающие EME, должны реализовать CLEAR Key. Используя эту систему, медиа может быть зашифрован с помощью ключа, а затем воспроизводится просто, просто предоставив этот ключ. Чистый ключ может быть встроен в браузер: он не требует использования отдельного модуля расшифровки.
Хотя вряд ли будет использоваться для многих типов коммерческого контента, прозрачный ключ полностью совместимый во всех браузерах, которые поддерживают EME. Это также удобно для тестирования реализаций EME и приложений, использующих EME, без необходимости запросить ключ контента с сервера лицензий. Существует простой пример CLEAR KEY в Simpl.info/ck . Ниже приведено прохождение кода, который параллельно описанным выше шагам, хотя и без взаимодействия с сервером лицензий.
// 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), и разработаны другие решения.
Связанная технология 1: расширения источника медиа (MSE)
HtmlMedieEment - это существо простой красоты.
Мы можем загрузить, декодировать и играть в СМИ, просто предоставив URL SRC:
<video src="foo.webm"></video>
API источника медиа-источника является расширением HTMlMedieElement, позволяющим более мелкомутральному контролю над источником носителя, позволяя JavaScript создавать потоки для воспроизведения из «кусков» видео. Это, в свою очередь, обеспечивает такие методы, как адаптивная потоковая передача и смещение времени.
Почему MSE важно для EME? Поскольку в дополнение к распределению защищенного контента, поставщики коммерческого контента должны иметь возможность адаптировать доставку контента к условиям сети и другими требованиями. Netflix, например, динамически изменяет Bitrate Stream Bitrate по мере изменения условий сети. EME работает с воспроизведением медиа -потоков, предоставленных реализацией MSE, так же, как это было бы с медиа -предоставленными с помощью атрибута SRC.
Как купить и воспроизводить носитель, закодированные в разных битратах? Смотрите раздел приборной приборной ниже .
Вы можете увидеть MSE в действии на Simpl.info/mse ; Для целей этого примера видео WebM разделено на пять кусков с использованием API -интерфейсов файлов. В производственном приложении куски видео будут извлечены через Ajax.
Сначала создан источник -буфер:
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 .
Связанная технология 2: динамическая адаптивная потоковая передача по http (dash)
Многократная, многоплатформенная, мобильная-как бы вы его ни называли, Интернет часто испытывает в условиях изменчивой связи. Динамическая адаптивная доставка имеет решающее значение для преодоления ограничений полосы пропускания и изменчивости в мире с несколькими устройствами.
Dash (AKA MPEG-DASH) предназначен для обеспечения наилучшей возможной доставки СМИ в сложном мире, как для потоковой передачи, так и для загрузки. Несколько других технологий делают что -то подобное, например, HTTP Live Streaming (HLS) Apple (HLS) и плавная потоковая передача Microsoft, но Dash является единственным методом адаптивной потоковой передачи битрейта через HTTP, который основан на открытом стандарте. Dash уже используется на таких сайтах, как YouTube.
Какое это имеет отношение к EME и MSE? Реализации DASH на основе MSE могут анализировать манифест, загружать сегменты видео на соответствующем битрейте и подавать их в видео элемент, когда он голоден-используя существующую HTTP-инфраструктуру.
Другими словами, Dash позволяет коммерческим поставщикам контента делать адаптивную потоковую передачу защищенного контента.
Дэш делает то, что говорит на жестяной банке:
- Динамика: реагирует на изменение условий.
- Адаптивные: адаптации для обеспечения соответствующего аудио или видео битрейта.
- Потоковая передача: позволяет потоковой передаче и загрузке.
- HTTP: обеспечивает доставку контента с преимуществом HTTP без недостатков традиционного потокового сервера.
Би -би -си начала предоставлять тестовые потоки, используя Dash :
СМИ кодируются несколько раз в разных битрейтах. Каждое кодирование называется представлением. Они разделены на ряд сегментов СМИ. Клиент играет программу, запрашивая сегменты, по порядку, из представления над HTTP. Представления могут быть сгруппированы в наборы адаптации представлений, содержащих эквивалентный контент. Если клиент хочет изменить битрейт, он может выбрать альтернативу из текущего набора адаптации и начать запрос сегментов из этого представления. Контент кодируется таким образом, чтобы сделать это переключение легко для клиента. В дополнение к ряду сегментов СМИ, представление, как правило, также имеет сегмент инициализации. Это можно рассматривать как заголовок, содержащий информацию о кодировании, размерах кадров и т. Д. Клиент должен получить это для данного представления, прежде чем употреблять сегменты носителя от этого представления.
Подводя итог:
- СМИ кодируются в разных битрейтах.
- Различные файлы битрейта доступны на HTTP -сервере.
- Клиентское веб -приложение выбирает, какой битрейт для извлечения и воспроизведения с Dash.
В рамках процесса сегментации видео, XML -манифест, известный как описание презентации среды (MPD), создан программно. Это описывает наборы адаптации и представления, с продолжительностью и URL. MPD выглядит так:
<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, используемого для демонстрации Dash YouTube .)
Согласно спецификации DASH, файл MPD может быть теоретически использовать в качестве SRC для видео. Однако, чтобы дать большую гибкость веб -разработчикам, поставщики браузеров решили вместо этого оставить поддержку DASH в библиотеках JavaScript, используя MSE, такой как dash.js. Реализация Dash в JavaScript позволяет развиваться алгоритм адаптации, не требуя обновлений браузера. Использование MSE также позволяет экспериментировать с альтернативными манифестными форматами и механизмами доставки, не требуя изменений в браузере. Игрок Google Shaka реализует клиента Dash с поддержкой EME.
Mozilla Developer Network имеет инструкции по использованию инструментов WebM и FFMPEG для сегмента видео и создания MPD.
Заключение
Использование сети для доставки платного видео и аудио растет с огромной скоростью . Похоже, что каждое новое устройство, будь то планшет, игровая консоль, подключенная телевизор или серия, способно транслировать носитель от основных поставщиков контента по сравнению с HTTP. Более 85% мобильных и настольных браузеров в настоящее время поддерживают <ideo> и <Audio>, и Cisco к 2017 году составит от 80 до 90 процентов глобального потребительского интернет -трафика .
Дальнейшее чтение
Спецификации и стандарты
EME Spec : Проект Последнего редактора общего шифрования (CENC) Расширения источника СМИ : Стандарт Draft Dash последнего редактора (да, это PDF) Обзор стандарта DASH
Статьи
Вебинар DTG (частично устаревший) Что такое EME? , от Анри Сивоненс- Средства Средства Средства массовой информации праймер Mpeg-Dash Test Streams: BBC R & D Post в блоге
Демо
Clear Key Demo: Simpl.info/ck Media Source Extensions (MSE) Демо -игрок Google Shaka Player реализует клиента Dash с поддержкой EME