Encrypted Media Extensions fornisce un'API che consente alle applicazioni web di interagire con i sistemi di protezione dei contenuti per consentire la riproduzione di audio e video criptati.
EME è progettato per consentire di utilizzare la stessa app e gli stessi file criptati in qualsiasi browser, indipendentemente dal sistema di protezione sottostante. La prima è resa possibile dalle API e dal flusso standardizzati, mentre la seconda è resa possibile dal concetto di crittografia comune.
EME è un'estensione della specifica HTMLMediaElement, da cui deriva il nome. Poiché si tratta di un'estensione, il supporto di EME da parte del browser è facoltativo: se un browser non supporta i contenuti multimediali criptati, non potrà riprodurli, ma EME non è necessario per la conformità alle specifiche HTML. Dalla specifica EME:
Questa proposta estende HTMLMediaElement fornendo API per controllare la riproduzione dei contenuti protetti.
L'API supporta casi d'uso che vanno dalla semplice decrittografia della chiave chiara ai video di alto valore (in base a un'implementazione appropriata dello user-agent). Lo scambio di licenze/chiavi è controllato dall'applicazione, facilitando lo sviluppo di applicazioni di riproduzione solide che supportano una serie di tecnologie di decrittografia e protezione dei contenuti.
Questa specifica non definisce un sistema di protezione dei contenuti o di gestione dei diritti digitali. Piuttosto, definisce un'API comune che può essere utilizzata per scoprire, selezionare e interagire con tali sistemi, nonché con sistemi di crittografia dei contenuti più semplici. L'implementazione della gestione dei diritti digitali non è richiesta per la conformità a questa specifica: è necessario implementare solo il sistema Clear Key come base comune.
L'API comune supporta un semplice insieme di funzionalità di crittografia dei contenuti, lasciando le funzioni di applicazione come l'autenticazione e l'autorizzazione agli autori delle pagine. Ciò si ottiene richiedendo che la messaggistica specifica del sistema di protezione dei contenuti sia mediata dalla pagina anziché presupporre una comunicazione out-of-band tra il sistema di crittografia e una licenza o un altro server.
Le implementazioni EME utilizzano i seguenti componenti esterni:
- Sistema chiave: un meccanismo di protezione dei contenuti (DRM). EME non definisce i sistemi di chiavi stessi, a parte Clear Key (di seguito sono riportate maggiori informazioni in merito).
- Modulo di decrittografia dei contenuti (CDM): un meccanismo hardware o software lato client che consente la riproduzione di contenuti multimediali criptati. Come per Key Systems, EME non definisce alcun CDM, ma fornisce un'interfaccia per consentire alle applicazioni di dialogare con i CDM disponibili.
- Server delle licenze (chiavi): interagisce con un CDM per fornire le chiavi per decriptare i contenuti multimediali. La negoziazione con il server delle licenze è responsabilità dell'applicazione.
- Servizio di imballaggio: codifica e cripta i contenuti multimediali per la distribuzione/il consumo.
Tieni presente che un'applicazione che utilizza EME interagisce con un server di licenze per ottenere chiavi che consentano la decriptazione, ma l'identità e l'autenticazione dell'utente non fanno parte di EME. Il recupero delle chiavi per abilitare la riproduzione dei contenuti multimediali avviene dopo (facoltativo) l'autenticazione di un utente. Servizi come Netflix devono autenticare gli utenti all'interno della loro applicazione web: quando un utente accede all'applicazione, questa determina la sua identità e i suoi privilegi.
Come funziona l'EME?
Ecco come interagiscono i componenti di EME, corrispondente all'esempio di codice riportato di seguito:
Se sono disponibili più formati o codec, MediaSource.isTypeSupported() o HTMLMediaElement.canPlayType() possono essere utilizzati entrambi per selezionare quello corretto. Tuttavia, il CDM potrebbe supportare solo un sottoinsieme di ciò che supporta il browser per i contenuti non criptati. È meglio negoziare una configurazione di MediaKeys prima di selezionare un formato e un codec. Se l'applicazione attende l'evento criptato, ma MediaKeys indica che non può gestire il formato/il codec scelto, potrebbe essere troppo tardi per cambiare senza interrompere la riproduzione.
Il flusso consigliato è negoziare prima MediaKeys, utilizzando MediaKeysSystemAccess.getConfiguration() per scoprire la configurazione negoziata.
Se è possibile scegliere un solo formato/codec, non è necessario utilizzare getConfiguration(). Tuttavia, è comunque preferibile configurare prima MediaKeys. L'unico motivo per attendere l'evento criptato è se non c'è modo di sapere se i contenuti sono criptati o meno, ma in pratica è improbabile.
- Un'applicazione web tenta di riprodurre audio o video con uno o più stream criptati.
- Il browser riconosce che i contenuti multimediali sono criptati (vedi la casella di seguito per sapere come accade) e attiva un evento criptato con i metadati (initData) ottenuti dai contenuti multimediali relativi alla crittografia.
L'applicazione gestisce l'evento criptato:
Se non è stato associato alcun oggetto MediaKeys all'elemento multimediale, innanzitutto seleziona un Key System disponibile utilizzando navigator.requestMediaKeySystemAccess() per controllare quali Key System sono disponibili, quindi crea un oggetto MediaKeys per un Key System disponibile tramite un oggetto MediaKeySystemAccess. Tieni presente che l'inizializzazione dell'oggetto MediaKeys deve avvenire prima del primo evento criptato. L'app ottiene un URL del server delle licenze indipendente dalla selezione di un sistema di chiavi disponibile. Un oggetto MediaKeys rappresenta tutte le chiavi disponibili per decriptare i contenuti multimediali per un elemento audio o video. Rappresenta un'istanza CDM e fornisce l'accesso al CDM, in particolare per la creazione di sessioni di chiavi, che vengono utilizzate per ottenere le chiavi da un server delle licenze.
Dopo aver creato l'oggetto MediaKeys, assegnalo all'elemento media: setMediaKeys() associa l'oggetto MediaKeys a un HTMLMediaElement, in modo che le relative chiavi possano essere utilizzate durante la riproduzione, ovvero durante la decodifica.
L'app crea una sessione MediaKeySession richiamando createSession() su MediaKeys. Viene creata una MediaKeySession, che rappresenta il ciclo di vita di una licenza e delle relative chiavi.
L'app genera una richiesta di licenza trasmettendo al CDM i dati multimediali ottenuti nel gestore criptato, chiamando il metodo generateRequest() su MediaKeySession.
Il CDM attiva un evento di messaggio: una richiesta di acquisizione di una chiave da un server delle licenze.
L'oggetto MediaKeySession riceve l'evento messaggio e l'applicazione invia un messaggio al server delle licenze (ad esempio tramite XHR).
L'applicazione riceve una risposta dal server delle licenze e passa i dati al CDM utilizzando il metodo update() di MediaKeySession.
Il CDM decripta i contenuti multimediali utilizzando le chiavi nella licenza. È possibile utilizzare una chiave valida da qualsiasi sessione all'interno di MediaKeys associata all'elemento media. Il CDM accederà alla chiave e al criterio, indicizzati dall'ID chiave.
La riproduzione dei contenuti multimediali riprende.
Come fa il browser a sapere che i contenuti multimediali sono criptati?
Queste informazioni si trovano nei metadati del file del contenitore multimediale, che sarà in un formato come ISO BMFF o WebM. Per ISO BMFF si tratta dei metadati dell'intestazione, chiamati riquadro delle informazioni sullo schema di protezione. WebM utilizza l'elemento Matroska ContentEncryption, con alcune aggiunte specifiche per WebM. Le linee guida sono fornite per ogni contenitore in un registry specifico per EME.
Tieni presente che potrebbero esserci più messaggi tra il CDM e il server di licenze e tutte le comunicazioni in questo processo sono opace per il browser e l'applicazione: i messaggi vengono compresi solo dal CDM e dal server di licenze, anche se il livello dell'app può vedere il tipo di messaggio inviato da CDM. La richiesta di licenza contiene la prova della validità del CDM (e della relazione di attendibilità) nonché una chiave da utilizzare per criptare le chiavi dei contenuti nella licenza risultante.
Ma cosa fanno esattamente i CDM?
Un'implementazione EME di per sé non offre un modo per decriptare i contenuti multimediali: fornisce semplicemente un'API per consentire a un'applicazione web di interagire con i moduli di decriptazione dei contenuti.
Ciò che fanno effettivamente i CDM non è definito dalle specifiche EME e un CDM può gestire la decodifica (decompressione) dei contenuti multimediali e anche la decrittografia. Dalla meno alla più efficace, esistono diverse potenziali opzioni per la funzionalità CDM:
- Solo decrittografia, che consente la riproduzione utilizzando la normale pipeline multimediale, ad esempio tramite un elemento <video>.
- Decrittografia e decodifica, con passaggio dei frame video al browser per il rendering.
- Decrittografia e decodifica, rendering direttamente nell'hardware (ad esempio la GPU).
Esistono diversi modi per rendere disponibile un CDM a un'app web:
- Raggruppa un CDM con il browser.
- Distribuire un CDM separatamente.
- Crea un CDM nel sistema operativo.
- Includi un CDM nel firmware.
- Incorpora un CDM nell'hardware.
La modalità di messa a disposizione di un CDM non è definita dalla specifica EME, ma in ogni caso è il browser a essere responsabile della verifica e dell'esposizione del CDM.
EME non richiede un particolare sistema di chiavi; tra i browser desktop e mobile attuali, Chrome supporta Widevine e IE11 supporta PlayReady.
Ottenere una chiave da un server delle licenze
In un normale utilizzo commerciale, i contenuti vengono criptati e codificati utilizzando un servizio o uno strumento di packaging. Una volta che i contenuti multimediali criptati sono resi disponibili online, un client web può ottenere una chiave (contenuta all'interno di una licenza) da un server di licenze e utilizzarla per consentire la decrittografia e la riproduzione dei contenuti.
Il seguente codice (adattato dagli esempi di specifiche) mostra come un'applicazione può selezionare un sistema di chiavi appropriato e ottenere una chiave da un server di licenze.
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')
);
}
Crittografia comune
Le soluzioni di crittografia comune consentono ai fornitori di contenuti di criptare e pacchettizzare i propri contenuti una volta per contenitore/codec e di utilizzarli con una serie di sistemi di chiavi, CDM e client, ovvero qualsiasi CDM che supporti la crittografia comune. Ad esempio, un video pacchettizzato utilizzando Playready può essere riprodotto in un browser utilizzando un Widevine CDM che ottiene una chiave da un server di licenze Widevine.
Ciò è in contrasto con le soluzioni precedenti che funzionavano solo con un insieme verticale completo, incluso un singolo client che spesso includeva anche un runtime dell'applicazione.
Crittografia comune (CENC) è uno standard ISO che definisce uno schema di protezione per ISO BMFF; un concetto simile si applica a WebM.
Cancella chiave
Sebbene EME non definisca la funzionalità DRM, la specifica attualmente prevede che tutti i browser che supportano EME debbano implementare Clear Key. Con questo sistema, i contenuti multimediali possono essere criptati con una chiave e poi riprodotti semplicemente fornendo la chiave. Clear Key può essere integrato nel browser: non richiede l'uso di un modulo di decrittografia separato.
Sebbene non sia probabile che venga utilizzato per molti tipi di contenuti commerciali, Clear Key è completamente interoperabile su tutti i browser che supportano EME. È utile anche per testare le implementazioni di EME e le applicazioni che utilizzano EME, senza dover richiedere una chiave dei contenuti da un server delle licenze. Puoi trovare un semplice esempio di Clear Key su simpl.info/ck. Di seguito è riportata una procedura dettagliata del codice, che corrisponde ai passaggi descritti sopra, anche se senza interazione con il server delle licenze.
// 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],
}),
);
}
Per testare questo codice, devi riprodurre un video criptato. La crittografia di un video per l'utilizzo con Clear Key può essere eseguita per WebM come da istruzioni di webm_crypt. Sono disponibili anche servizi commerciali (almeno per ISO BMFF/MP4) e sono in fase di sviluppo altre soluzioni.
Tecnologia correlata 1: estensioni Media Source (MSE)
HTMLMediaElement è una creatura di semplice bellezza.
Possiamo caricare, decodificare e riprodurre i contenuti multimediali semplicemente fornendo un URL di origine:
<video src="foo.webm"></video>
L'API Media Source è un'estensione di HTMLMediaElement che consente un controllo più granulare sulla sorgente dei contenuti multimediali, consentendo a JavaScript di creare stream per la riproduzione da "chunk" di video. Ciò consente a sua volta tecniche come lo streaming adattivo e il time shifting.
Perché la MSE è importante per l'EME? Perché, oltre a distribuire contenuti protetti, i fornitori di contenuti commerciali devono essere in grado di adattare la distribuzione dei contenuti alle condizioni della rete e ad altri requisiti. Netflix, ad esempio, modifica dinamicamente la velocità in bit dello stream in base alle condizioni della rete. EME funziona con la riproduzione di stream multimediali forniti da un'implementazione MSE, come avviene con i contenuti multimediali forniti tramite un attributo src.
Come suddividere e riprodurre contenuti multimediali codificati a velocità in bit diverse? Consulta la sezione DASH in basso.
Puoi vedere MSE in azione all'indirizzo simpl.info/mse; ai fini di questo esempio, un video WebM viene suddiviso in cinque blocchi utilizzando le API File. In un'applicazione di produzione, i chunk di video vengono recuperati tramite AJAX.
Per prima cosa viene creato un SourceBuffer:
var sourceBuffer = mediaSource.addSourceBuffer(
'video/webm; codecs="vorbis,vp8"',
);
L'intero film viene quindi "trasmesso in streaming" a un elemento video aggiungendo ogni chunk utilizzando il metodo 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);
}
};
Scopri di più sull'MSE nella primer MSE.
Tecnologia correlata 2: Dynamic Adaptive Streaming over HTTP (DASH)
Multi-dispositivo, multipiattaforma, mobile: a prescindere dal nome, il web viene spesso utilizzato in condizioni di connettività mutevole. La pubblicazione dinamica e adattativa è fondamentale per far fronte alle limitazioni di larghezza di banda e alla variabilità nel mondo dei dispositivi multipiattaforma.
DASH (noto anche come MPEG-DASH) è progettato per consentire la migliore esperienza di caricamento di contenuti multimediali in un ambiente incerto, sia per lo streaming che per il download. Diverse altre tecnologie fanno qualcosa di simile, ad esempio HTTP Live Streaming (HLS) di Apple e Smooth Streaming di Microsoft, ma DASH è l'unico metodo di streaming con velocità in bit adattiva tramite HTTP basato su uno standard aperto. DASH è già in uso su siti come YouTube.
Che cosa c'entra questo con EME e MSE? Le implementazioni DASH basate su MSE possono analizzare un manifest, scaricare segmenti di video a una velocità in bit appropriata e inviarli a un elemento video quando necessario, utilizzando l'infrastruttura HTTP esistente.
In altre parole, DASH consente ai fornitori di contenuti commerciali di eseguire uno streaming adattivo dei contenuti protetti.
DASH fa esattamente quello che promette:
- Dinamico: risponde alle condizioni in evoluzione.
- Adattiva:si adatta per fornire una velocità in bit audio o video appropriata.
- Streaming: consente lo streaming e il download.
- HTTP:consente la pubblicazione di contenuti con il vantaggio di HTTP, senza i svantaggi di un server di streaming tradizionale.
La BBC ha iniziato a fornire stream di prova utilizzando DASH:
I contenuti multimediali vengono codificati più volte a velocità in bit diverse. Ogni codifica è chiamata rappresentazione. Questi sono suddivisi in una serie di segmenti multimediali. Il client riproduce un programma richiedendo i segmenti, in ordine, da una rappresentazione tramite HTTP. Le rappresentazioni possono essere raggruppate in set di adattamento di rappresentazioni contenenti contenuti equivalenti. Se il cliente desidera modificare la velocità in bit, può scegliere un'alternativa dal set di adattamento corrente e iniziare a richiedere segmenti da quella rappresentazione. I contenuti vengono codificati in modo da semplificare il passaggio al client. Oltre a un certo numero di segmenti multimediali, una rappresentazione in genere ha anche un segmento di inizializzazione. Può essere considerato un'intestazione contenente informazioni sulla codifica, sulle dimensioni dei frame e così via. Un client deve ottenerlo per una determinata rappresentazione prima di utilizzare i segmenti multimediali di quella rappresentazione.
In sintesi:
- I contenuti multimediali vengono codificati a velocità in bit diverse.
- I diversi file con velocità in bit vengono resi disponibili da un server HTTP.
- Un'app web client sceglie la velocità in bit da recuperare e riprodurre con DASH.
Nell'ambito del processo di segmentazione dei video, viene creato in modo programmatico un file manifest XML noto come Media Presentation Description (MPD). Descrive gli adattamenti e le rappresentazioni, con durate e URL. Un file MPD ha il seguente aspetto:
<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>
(Questo XML è tratto dal file .mpd utilizzato per il player dimostrativo DASH di YouTube.)
Secondo le specifiche DASH, in teoria un file MPD potrebbe essere utilizzato come src per un video. Tuttavia, per offrire maggiore flessibilità agli sviluppatori web, i fornitori di browser hanno scelto di lasciare il supporto di DASH alle librerie JavaScript che utilizzano MSE, come dash.js. L'implementazione di DASH in JavaScript consente all'algoritmo di adattamento di evolversi senza richiedere aggiornamenti del browser. L'utilizzo di MSE consente inoltre di sperimentare con formati manifest alternativi e meccanismi di caricamento senza richiedere modifiche al browser. Shaka Player di Google implementa un client DASH con supporto EME.
La Mozilla Developer Network fornisce istruzioni su come utilizzare gli strumenti WebM e FFmpeg per segmentare i video e creare un file MPD.
Conclusione
L'utilizzo del web per la pubblicazione di contenuti video e audio a pagamento è in crescita a un ritmo esponenziale. Sembra che ogni nuovo dispositivo, che si tratti di tablet, console per videogiochi, TV connesse a internet o decoder, sia in grado di trasmettere in streaming contenuti multimediali dai principali fornitori di contenuti tramite HTTP. Oltre l'85% dei browser per computer e dispositivi mobili ora supporta <video> e <audio> e Cisco stima che, entro il 2017, i video rappresenteranno l'80-90% del traffico internet dei consumatori a livello globale. In questo contesto, è probabile che il supporto dei browser per la distribuzione di contenuti protetti diventerà sempre più significativo, in quanto i fornitori di browser riducono il supporto delle API su cui si basa la maggior parte dei plug-in multimediali.
Per approfondire
Specifiche e standard
Specifiche EME: bozza dell'editor più recente Crittografia comune (CENC) Estensioni Media Source: bozza dell'editor più recente Standard DASH (sì, è un PDF) Panoramica dello standard DASH
Articoli
Webinar DTG (parzialmente obsoleto) What is EME?, di Henri Sivonen Prime di Media Source Extensions MPEG-DASH Test Streams: post del blog BBC R&D
Demo
Demo di Clear Key: simpl.info/ck Demo di Media Source Extensions (MSE) Shaka Player di Google implementa un client DASH con supporto EME