Encrypted Media Extensions (EME) udostępnia interfejs API, który umożliwia aplikacjom internetowym interakcję z systemami ochrony treści w celu odtwarzania zaszyfrowanego dźwięku i filmu.
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 na ten temat znajdziesz 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): współpracuje z CDM, aby udostępniać klucze do odszyfrowywania multimediów. Za negocjacje z serwerem licencji odpowiada aplikacja.
- 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 ich aplikacji internetowej: gdy użytkownik loguje się w aplikacji, określa ona 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, używając narzędzianavigator.requestMediaKeySystemAccess()
, aby sprawdzić dostępne systemy kluczy, 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 instancję CDM i zapewnia dostęp do CDM, zwłaszcza na potrzeby tworzenia sesji kluczy, które służą 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 pozyskania 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 zostanie wznowione.
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 wygenerowanej 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.
Specyfikacja EME nie definiuje, co dokładnie robi CDM. 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);
Istnieje kilka sposobów udostępnienia CDM aplikacji internetowej:
- Dołącz CDM do przeglądarki.
- rozpowszechniać CDM osobno;
- Zaimplementuj CDM z systemem operacyjnym.
- Umieść CDM w oprogramowaniu.
- Osadzanie CDM w sprzęcie.
Metoda udostępniania CDM nie jest określona w specyfikacji EME, ale w każdym przypadku to przeglądarka jest odpowiedzialna za sprawdzenie i ujawnienie CDM.
EME nie narzuca określonego systemu kluczy. Wśród obecnych przeglądarek na komputerach i urządzeniach mobilnych Chrome obsługuje Widevine, a IE11 obsługuje 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) od serwera licencji i użyć go do odszyfrowania oraz odtworzenia treści.
Poniższy kod (zaadaptowany na podstawie przykładów 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 kompletnym stosem pionowym, obejmującym pojedynczego klienta, który często zawiera też środowisko uruchomieniowe aplikacji.
Wspólne szyfrowanie (CENC) to norma ISO definiująca schemat ochrony dla ISO BMFF; podobna koncepcja dotyczy 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 obsługujących 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 wtyczki szyfrującej 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
Rozszerzenia multimediów (MSE)
Element HTMLMediaElement to stworzenie o prostym pięknie.
Aby wczytywać, dekodować i odtwarzać multimedia, wystarczy podać 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ą być w stanie dostosować dostarczanie treści do warunków sieci i innych wymagań. Na przykład Netflix dynamicznie zmienia szybkość transmisji bitów zgodnie ze zmianami warunków sieci. Działa ona z odtwarzaniem strumieni multimediów dostarczanych przez implementację MSE, tak samo jak w przypadku multimediów dostarczanych za pomocą atrybutu src
.
Jak dzielić na fragmenty i odtwarzać multimedia zakodowane z różnymi szybkościami transmisji bitów? Zobacz sekcję DASH poniżej.
Jak działa MSE, możesz zobaczyć go na stronie simpl.info/mse. Na potrzeby tego przykładu film WebM jest podzielony na 5 fragmentów za pomocą interfejsów File API. W aplikacji produkcyjnej fragmenty wideo były pobierane przy użyciu technologii Ajax.
Najpierw tworzony jest element SourceBuffer:
var sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
Następnie cały film jest „przesyłany strumieniowo” do elementu wideo poprzez 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 nr 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, dostosowująca się 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. Format DASH jest już używany przez takie witryny 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.
Inaczej mówiąc, DASH umożliwia dostawcom treści komercyjnych elastyczne strumieniowanie treści chronionych.
DASH robi to, co jest w puszce:
- Dynamiczny: reaguje na zmieniające się warunki.
- Adaptacyjna: dostosowuje się, aby zapewnić odpowiednią szybkość transmisji bitów dźwięku lub wideo.
- Przesyłanie strumieniowe: umożliwia przesyłanie strumieniowe i pobieranie.
- HTTP: umożliwia dostarczanie treści z zaletami protokołu HTTP, bez wad tradycyjnego serwera strumieniowego.
BBC rozpoczęło przesyłanie transmisji testowych za pomocą DASH:
Podsumowując:
- Multimedia są kodowane z różnymi szybkościami transmisji.
- Pliki o różnej szybkości transmisji bitów są udostępniane z serwera HTTP.
- Aplikacja internetowa klienta wybiera, jaką szybkość transmisji danych ma pobrać i odtworzyć za pomocą DASH.
W ramach procesu segmentacji wideo plik manifestu XML, nazywany opisem Media PresentationDescription (MPD), jest tworzony automatycznie. Zawiera ona informacje o zestawach i reprezentacjach adaptacyjnych, w tym ich długości i adresy 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 plik XML pochodzi z pliku .mpd używanego na potrzeby odtwarzacza demonstracyjnego DASH w YouTube)
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. Firma Google Shaka Player wdraża 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 treści wideo i audio rozwija się w ogromnym 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)
- Co to jest EME?, Henri Sivonen
- Artykuł HTML5 Rocks Media Source Extensions
- MPEG-DASH Test Streams: post na blogu BBC R&D