Rozszerzenia Encrypted Media Extensions (EME) udostępniają interfejs API, który umożliwia aplikacjom internetowym interakcję z systemami ochrony treści, aby umożliwić odtwarzanie zaszyfrowanych plików audio i wideo.
EME umożliwia korzystanie z tej samej aplikacji i zaszyfrowanych plików w dowolnej przeglądarce, niezależnie od systemu ochrony. Pierwsza opcja jest możliwa dzięki standardowym interfejsom API i standardowemu przepływowi danych, a druga – dzięki koncepcji wspólnego szyfrowania.
EME to rozszerzenie specyfikacji HTMLMediaElement
, stąd nazwa. „Rozszerzenie” oznacza, że obsługa szyfrowania multimediów przez przeglądarkę jest opcjonalna: jeśli przeglądarka nie obsługuje szyfrowania multimediów, nie będzie mogła odtwarzać zaszyfrowanych multimediów, ale szyfrowanie nie jest wymagane do zgodności ze specyfikacją HTML. Z specyfikacji EME:
Implementacje EME korzystają z tych komponentów zewnętrznych:
- System kluczy: mechanizm ochrony treści (DRM). EME nie definiuje systemów kluczy, z wyjątkiem Clear Key (więcej informacji poniżej).
- Moduł odszyfrowywania treści (CDM): oprogramowanie lub mechanizm sprzętowy po stronie klienta, który umożliwia odtwarzanie zaszyfrowanych multimediów. Podobnie jak w przypadku systemów kluczy, EME nie definiuje żadnych CDM, ale udostępnia interfejs, który umożliwia aplikacjom współpracę z dostępnymi CDM.
- Serwer licencji (kluczy): komunikuje się z CDM, aby udostępniać klucze do odszyfrowywania multimediów. Negocjacje z serwerem licencji są obowiązkiem aplikacji.
- Usługa pakowania: koduje i szyfruje media na potrzeby dystrybucji i konsumpcji.
Pamiętaj, że aplikacja korzystająca z EME wchodzi w interakcję z serwerem licencji, aby uzyskać klucze umożliwiające odszyfrowywanie, ale tożsamość użytkownika i uwierzytelnianie nie są częścią EME. Pobieranie kluczy umożliwiających odtwarzanie multimediów odbywa się po (opcjonalnym) uwierzytelnieniu użytkownika. Usługi takie jak Netflix muszą uwierzytelniać użytkowników w swojej aplikacji internetowej: gdy użytkownik loguje się w aplikacji, aplikacja określa jego tożsamość i uprawnienia.
Jak działa EME?
Oto jak komponenty EME współdziałają ze sobą w przypadku tego przykładowego kodu:
- Aplikacja internetowa próbuje odtworzyć dźwięk lub film z co najmniej 1 zaszyfrowanym strumieniem.
- Przeglądarka rozpoznaje, że treści multimedialne są zaszyfrowane (jak to się dzieje, wyjaśnia ramka poniżej), i wywołuje zdarzenie
encrypted
z metadanymi (initData
) uzyskanymi z treści multimedialnych na temat szyfrowania. - Aplikacja obsługuje zdarzenie
encrypted
:- Jeśli z elementem multimedialnym nie jest powiązany żaden obiekt
MediaKeys
, najpierw wybierz dostępny system kluczy, korzystając z obiektunavigator.requestMediaKeySystemAccess()
, aby sprawdzić, jakie systemy kluczy są dostępne, a następnie utwórz obiektMediaKeys
dla dostępnego systemu kluczy za pomocą obiektuMediaKeySystemAccess
. Pamiętaj, że inicjalizacja obiektu MediaKeys powinna nastąpić przed pierwszym zdarzeniemencrypted
. Uzyskiwanie adresu URL serwera licencji jest wykonywane przez aplikację niezależnie od wyboru dostępnego systemu kluczy. ObiektMediaKeys
reprezentuje wszystkie klucze dostępne do odszyfrowywania multimediów w przypadku elementu audio lub wideo. Reprezentuje on instancję CDM i zapewnia dostęp do CDM, w szczególności do tworzenia sesji kluczy, które są używane do uzyskiwania kluczy z serwera licencji. - Po utworzeniu obiektu
MediaKeys
przypisz go do elementu multimedialnego:setMediaKeys()
łączy obiektMediaKeys
z elementem HTMLMediaElement, aby można było używać jego kluczy podczas odtwarzania, czyli dekodowania.
- Jeśli z elementem multimedialnym nie jest powiązany żaden obiekt
- Aplikacja tworzy
MediaKeySession
, wywołując funkcjęcreateSession()
w obiekcieMediaKeys
. Spowoduje to utworzenieMediaKeySession
, który reprezentuje czas trwania licencji i jej kluczy. - Aplikacja generuje żądanie licencji, przekazując dane multimediów uzyskane w obiekcie
encrypted
do CDM, wywołując funkcjęgenerateRequest()
w obiekcieMediaKeySession
. - CDM uruchamia zdarzenie
message
: żądanie uzyskania klucza z serwera licencji. - Obiekt
MediaKeySession
odbiera zdarzeniemessage
, a aplikacja wysyła wiadomość do serwera licencji (np. za pomocą XHR). - Aplikacja otrzymuje odpowiedź od serwera licencji i przekazuje dane do CDM za pomocą metody
update()
wMediaKeySession
. - CDM odszyfrowuje media za pomocą kluczy z licencji. Można użyć prawidłowego klucza z dowolnej sesji w ramach
MediaKey
powiązanych z elementem multimedialnym. CDM będzie mieć dostęp do klucza i zasady, indeksowanych za pomocą identyfikatora klucza. - Odtwarzanie multimediów wznowi się.
Uff…
Pamiętaj, że między CDM a serwerem licencji może być wysyłanych wiele wiadomości, a cała komunikacja w ramach tego procesu jest niewidoczna dla przeglądarki i aplikacji: wiadomości są zrozumiałe tylko dla CDM i serwera licencji, ale warstwa aplikacji może zobaczyć rodzaj wiadomości wysyłanej przez CDM. Prośba o licencję zawiera potwierdzenie ważności CDM (i związku zaufania), a także klucz do szyfrowania kluczy treści w wynikającej z niego licencji.
…ale do czego właściwie służą CDM?
Implementacja EME sama w sobie nie zapewnia sposobu na odszyfrowanie multimediów: udostępnia ona tylko interfejs API, który umożliwia aplikacji internetowej interakcję z modułami odszyfrowywania treści.
To, co robi CDM, nie jest określone w specyfikacji EME. CDM może obsługiwać dekodowanie (dekompresję) multimediów, a także odszyfrowywanie. Oto kilka opcji funkcji CDM, od najmniej do najbardziej niezawodnej:
- Tylko odszyfrowywanie, umożliwiające odtwarzanie za pomocą normalnego potoku multimediów, na przykład za pomocą elementu
<video>
. - Odszyfrowanie i dekodowanie, przekazywanie ramek wideo do przeglądarki w celu renderowania.
- odszyfrowywanie i dekodowanie, renderowanie bezpośrednio na sprzęcie (np. na karcie graficznej);
CDM można udostępnić aplikacji internetowej na kilka sposobów:
- Dołącz CDM do przeglądarki.
- rozpowszechniać CDM osobno;
- Wbudowanie CDM w system operacyjny.
- Dołącz CDM do oprogramowania układowego.
- umieszczać CDM w sprzęcie;
Specyfikacja EME nie określa sposobu udostępniania CDM, ale w każdym przypadku przeglądarka jest odpowiedzialna za weryfikację i udostępnianie CDM.
EME nie wymaga korzystania z konkretnego systemu kluczy. Wśród obecnych przeglądarek na komputery i urządzenia mobilne Chrome obsługuje Widevine, a IE11 – PlayReady.
Pobieranie klucza z serwera licencji
W przypadku typowego użytku komercyjnego treści są szyfrowane i kodowane za pomocą usługi lub narzędzia do pakowania. Gdy zaszyfrowane media zostaną udostępnione online, klient internetowy może uzyskać klucz (zawarty w licencji) z serwera licencji i użyć go do odszyfrowania oraz odtworzenia treści.
Poniższy kod (przekształcony z specyfikacji) pokazuje, jak aplikacja może wybrać odpowiedni system kluczy i uzyskać klucz z serwera licencji.
var video = document.querySelector('video');
var config = [{initDataTypes: ['webm'],
videoCapabilities: [{contentType: 'video/webm; codecs="vp9"'}]}];
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')
);
}
Szyfrowanie wspólne
Rozwiązania wspólnego szyfrowania umożliwiają dostawcom treści szyfrowanie i pakowanie treści raz na kontener lub kodek oraz korzystanie z nich z różnymi systemami kluczy, CDM i klientami, czyli z dowolnym CDM obsługującym wspólne szyfrowanie. Na przykład film zapakowany za pomocą Playready może być odtwarzany w przeglądarce przy użyciu CDM Widevine, który pobiera klucz z serwera licencji Widevine.
W przeciwieństwie do starszych rozwiązań, które działają tylko z pełnym stosem pionowym, w tym z jednym klientem, który często obejmuje też środowisko uruchomienia aplikacji.
Wspólne szyfrowanie (CENC) to norma ISO definiująca schemat ochrony dla ISO BMFF; podobna koncepcja dotyczy formatu WebM.
Wyczyść klucz
Chociaż specyfikacja EME nie definiuje funkcji DRM, wymaga ona obecnie, aby wszystkie przeglądarki obsługujące EME implementowały Clear Key. Dzięki temu systemowi można szyfrować treści za pomocą klucza, a następnie odtwarzać je po prostu podając ten klucz. Clear Key może być wbudowany w przeglądarkę: nie wymaga korzystania z osobnego modułu odszyfrowywania.
Chociaż nie jest on używany w przypadku wielu rodzajów treści komercyjnych, Clear Key jest w pełni interoperacyjny we wszystkich przeglądarkach, które obsługują EME. Jest ona też przydatna do testowania implementacji EME i aplikacji korzystających z EME bez konieczności wysyłania żądania klucza treści do serwera licencji. Prosty przykład Clear Key znajdziesz na stronie simpl.info/ck. Poniżej znajdziesz instrukcje dotyczące kodu, które są równoważne z opisanymi powyżej czynnościami, ale bez interakcji z serwerem licencji.
// 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]
}));
}
Aby przetestować ten kod, musisz odtworzyć zaszyfrowany film. Szyfrowanie filmu do użycia z Clear Key można wykonać w przypadku formatu WebM zgodnie z instrukcjami dotyczącymi szyfrowania WebM. Dostępne są też usługi komercyjne (przynajmniej w przypadku formatów ISO BMFF/MP4), a inne rozwiązania są w trakcie opracowywania.
Powiązana technologia 1
Media Source Extensions (MSE)
Element HTMLMediaElement to proste piękno.
Możemy wczytywać, dekodować i odtwarzać multimedia, podając tylko adres URL źródła:
<video src='foo.webm'></video>
Interfejs Media Source API jest rozszerzeniem elementu HTMLMediaElement, który umożliwia bardziej szczegółową kontrolę nad źródłem multimediów. Umożliwia on JavaScriptowi tworzenie strumieni do odtwarzania z „kawałków” filmu. Umożliwia to stosowanie takich technik jak strumieniowanie adaptacyjne i przesuwanie w czasie.
Dlaczego MSE jest ważne dla EME? Oprócz rozpowszechniania treści chronionych dostawcy treści komercyjnych muszą mieć możliwość dostosowania dostarczania treści do warunków sieci i innych wymagań. Na przykład Netflix dynamicznie zmienia bitrate strumienia w zależności od warunków sieci. EME działa z odtwarzaniem strumieni multimediów udostępnianych przez implementację MSE, tak jak w przypadku multimediów udostępnianych za pomocą atrybutu src
.
Jak dzielić i odtwarzać media zakodowane z różnymi szybkościami transmisji? Zobacz sekcję DASH poniżej.
Aby zobaczyć, jak działa MSE, wejdź na stronę simpl.info/mse. W tym przykładzie film WebM jest dzielony na 5 części za pomocą interfejsów File API. W wersji produkcyjnej fragmenty filmu byłyby pobierane za pomocą Ajaxa.
Najpierw tworzony jest SourceBuffer:
var sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
Następnie cały film jest „przesyłany strumieniowo” do elementu wideo przez dołączanie każdego fragmentu za pomocą metody 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);
}
};
Więcej informacji o MSE znajdziesz w artykule HTML5 Rocks.
Powiązana technologia 2
Dynamiczne adaptacyjne strumieniowe przesyłanie danych przez HTTP (DASH)
Wieloplatformowość, wielozadaniowość, mobilność – niezależnie od tego, jak nazywasz internet, często korzystasz z niego w warunkach zmiennej łączności. Dynamiczna, dostosowywana transmisja jest kluczowa dla radzenia sobie z ograniczeniami przepustowości i zmiennością w świecie urządzeń.
DASH (MPEG-DASH) ma zapewnić najlepszą możliwą jakość przesyłania multimediów w niestabilnym środowisku, zarówno w przypadku strumieniowego przesyłania, jak i pobierania. Kilka innych technologii działa w podobny sposób, np. Transmisja na żywo przez HTTP (HLS) firmy Apple i płynne przesyłanie danych firmy Microsoft, ale DASH to jedyna metoda strumieniowego przesyłania danych z adaptacyjną szybkością transmisji bitów przez HTTP, która opiera się na otwartym standardzie. Interfejs DASH jest już używany w witrynach takich jak YouTube.
Jaki jest związek między EME i MSE? Implementacje DASH oparte na MSE mogą analizować plik manifestu, pobierać segmenty wideo z odpowiednią szybkością transmisji bitów i przesyłać je do elementu wideo, gdy ten potrzebuje więcej danych – za pomocą istniejącej infrastruktury HTTP.
Innymi słowy, DASH umożliwia dostawcom treści komercyjnych strumieniowanie adaptacyjne treści chronionych.
DASH spełnia swoje zadania:
- Dynamiczny: reaguje na zmieniające się warunki.
- Adaptacyjna: dostosowuje się, aby zapewnić odpowiednią szybkość transmisji bitów dźwięku lub wideo.
- Streaming: umożliwia przesyłanie strumieniowe i pobieranie.
- HTTP: umożliwia dostarczanie treści z zaletami protokołu HTTP, bez wad tradycyjnego serwera strumieniowego.
BBC zaczęło testować strumienie korzystające z DASH:
Podsumowując:
- Multimedia są kodowane z różnymi szybkościami transmisji.
- Pliki o różnych szybkościach transmisji danych są dostępne na serwerze HTTP.
- Aplikacja internetowa klienta wybiera, jaką szybkość transmisji danych ma pobrać i odtworzyć za pomocą DASH.
W ramach procesu podziału filmu na segmenty tworzymy programowo manifest XML, czyli opis prezentacji multimediów (MPD). Zawiera ona informacje o zestawach i reprezentacjach adaptacyjnych wraz z czasem trwania i adresami URL. Plik MPD wygląda tak:
<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>
(Ten kod XML został pobrany z pliku .mpd używanego w demo odtwarzacza YouTube DASH)
Zgodnie ze specyfikacją DASH plik MPD może teoretycznie służyć jako src
dla filmu. Aby jednak zapewnić deweloperom większą elastyczność, dostawcy przeglądarek zdecydowali się pozostawić obsługę DASH w bibliotekach JavaScript korzystających z MSE, takich jak dash.js. Wdrożenie DASH w JavaScript pozwala na ewolucję algorytmu adaptacji bez konieczności aktualizowania przeglądarki. Korzystanie z MSE pozwala też eksperymentować z alternatywnymi formatami i mechanizmami dostarczania manifestu bez konieczności wprowadzania zmian w przeglądarce. Odtwarzacz Shaka firmy Google implementuje klienta DASH z obsługą EME.
W Mozilla Developer Network znajdziesz instrukcje dotyczące używania narzędzi WebM i FFmpeg do dzielenia filmu na segmenty i tworzenia MPD.
Podsumowanie
Korzystanie z internetu do dostarczania płatnych filmów i dźwięku rośnie w bardzo szybkim tempie. Wygląda na to, że każde nowe urządzenie, niezależnie od tego, czy jest to tablet, konsola do gier, telewizor z funkcją łączności internetowej czy dekoder, może przesyłać strumieniowo treści od głównych dostawców treści przez HTTP. Ponad 85% przeglądarek mobilnych i na komputery obsługuje teraz <video>
i <audio>
. Według szacunków Cisco do 2017 r. 80–90% globalnego ruchu w internecie generowanego przez konsumentów będzie pochodzić z filmów. W tym kontekście obsługa przeglądarki w zakresie dystrybucji treści chronionych prawdopodobnie nabierze coraz większego znaczenia, ponieważ producenci przeglądarek ograniczają obsługę interfejsów API, z których korzysta większość wtyczek multimedialnych.
Więcej informacji
Specyfikacje i standardy
- Specyfikacja EME: najnowsza wersja robocza Edytora<
- Common Encryption (CENC)
- Rozszerzenia źródeł multimediów
- standard DASH (tak, jest to plik PDF);
- Informacje o standardzie DASH
Artykuły
- Webinar dotyczący DTG (częściowo nieaktualny)
- Henri Sivonen – What is EME?
- Artykuł HTML5 Rocks Media Source Extensions
- MPEG-DASH Test Streams: post na blogu BBC R&D