PlayReady Encrypted Media Extension
Questa sezione descrive come modificare l'app web PlayReady per supportare le modifiche apportate dalla versione precedente di Windows 8.1 alla versione di Windows 10.
L'uso di elementi multimediali PlayReady in Internet Explorer consente agli sviluppatori di creare app Web in grado di fornire contenuto PlayReady all'utente applicando al tempo stesso le regole di accesso definite dal provider di contenuti. Questa sezione descrive come aggiungere elementi multimediali PlayReady alle app Web esistenti usando solo HTML5 e JavaScript.
Novità dell'estensione multimediale crittografata PlayReady
Questa sezione fornisce un elenco delle modifiche apportate all'estensione EME (PlayReady Encrypted Media Extension) per abilitare la protezione del contenuto PlayReady in Windows 10.
L'elenco seguente descrive le nuove funzionalità e le modifiche apportate a PlayReady Encrypted Media Extension per Windows 10:
Aggiunta di DRM (Digital Rights Management) hardware.
Il supporto della protezione del contenuto basato su hardware consente la riproduzione sicura di contenuti HD (High Definition) e Ultra-High Definition (UHD) su più piattaforme per dispositivi. Il materiale della chiave (incluse chiavi private, chiavi simmetriche e qualsiasi altro materiale della chiave usato per derivare o sbloccare le chiavi) e gli esempi video compressi e non compressi decrittografati sono protetti sfruttando la sicurezza hardware.
Fornisce l'acquisizione proattiva di licenze non persistenti.
Fornisce l'acquisizione di più licenze in un unico messaggio.
È possibile usare un oggetto PlayReady con più identificatori chiave (KeyID) come in Windows 8.1 oppure usare i dati del modello di decrittografia del contenuto (CDMData) con più KEYID.
Nota
In Windows 10 sono supportati più identificatori di chiave in <KeyID> in CDMData.
Aggiunta del supporto per la scadenza in tempo reale o licenza LDL (Limited Duration License).
Consente di impostare la scadenza in tempo reale per le licenze.
Aggiunta del supporto dei criteri HDCP Type 1 (versione 2.2).
Miracast è ora implicito come output.
Aggiunta dell'arresto sicuro.
L'arresto sicuro consente a un dispositivo PlayReady di affermare in modo sicuro a un servizio di streaming multimediale che la riproduzione multimediale è stata arrestata per una determinata parte di contenuto.
Aggiunta della separazione delle licenze audio e video.
Le tracce separate impediscono la decodifica del video come audio; abilitazione di una protezione del contenuto più affidabile. Gli standard emergenti richiedono chiavi separate per le tracce audio e visive.
Aggiunta di MaxResDecode.
Questa funzionalità è stata aggiunta per limitare la riproduzione del contenuto a una risoluzione massima anche se in possesso di una chiave più idonea (ma non di una licenza). Supporta i casi in cui più dimensioni del flusso vengono codificate con una singola chiave.
Supporto dell'estensione multimediale crittografata in PlayReady
Questa sezione descrive la versione dell'estensione W3C Encrypted Media supportata da PlayReady.
PlayReady per App Web è attualmente associato alla bozza W3C Encrypted Media Extension (EME) del 10 maggio 2013. Questo supporto verrà modificato nella specifica EME aggiornata nelle versioni future di Windows.
Usare DRM hardware
Questa sezione descrive come l'app Web può usare la tecnologia DRM hardware PlayReady e come disabilitare la tecnologia DRM hardware se il contenuto protetto non lo supporta.
Per usare la tecnologia DRM hardware PlayReady, l'app Web JavaScript deve usare il metodo isTypeSupported EME con un identificatore di sistema chiave di com.microsoft.playready.hardware
per eseguire una query per il supporto DRM hardware PlayReady dal browser.
Occasionalmente, alcuni contenuti non sono supportati in DRM hardware. Il contenuto cocktail non è mai supportato in DRM hardware; se si vuole riprodurre contenuti cocktail, si deve rifiutare esplicitamente la tecnologia DRM hardware. Alcuni DRM hardware supporteranno HEVC e alcuni non lo faranno; se si vuole riprodurre contenuti HEVC e DRM hardware non lo supporta, si vuole rifiutare esplicitamente anche.
Nota
Per determinare se il contenuto HEVC è supportato, dopo aver creato un'istanza di com.microsoft.playready
, usare il metodo PlayReadyStatics.CheckSupportedHardware.
Aggiungere un arresto sicuro all'app Web
Questa sezione descrive come aggiungere un arresto sicuro all'app Web.
L'arresto sicuro consente a un dispositivo PlayReady di affermare in modo sicuro a un servizio di streaming multimediale che la riproduzione multimediale è stata arrestata per una determinata parte di contenuto. Questa funzionalità garantisce che i servizi di streaming multimediale forniscano un'applicazione accurata e la segnalazione delle limitazioni di utilizzo su dispositivi diversi per un determinato account.
Esistono due scenari principali per l'invio di una richiesta di arresto sicuro:
- Quando la presentazione multimediale si interrompe a causa del raggiungimento della fine del contenuto o quando l'utente ha arrestato la presentazione multimediale in un punto centrale.
- Quando la sessione precedente termina in modo imprevisto ,ad esempio a causa di un arresto anomalo del sistema o dell'app). L'app dovrà eseguire query, all'avvio o all'arresto, per eventuali sessioni di arresto sicuro in sospeso e inviare richieste separate da qualsiasi altra riproduzione multimediale.
Le procedure seguenti descrivono come configurare l'arresto sicuro per vari scenari.
Per configurare l'arresto sicuro per una fine normale di una presentazione:
- Registrare l'evento onEnded prima dell'avvio della riproduzione.
- Il gestore eventi onEnded deve chiamare
removeAttribute("src")
dall'oggetto elemento video/audio per impostare l'origine su NULL che attiverà la base multimediale per eliminare la topologia, distruggere i decrittografi e impostare lo stato di arresto. - È possibile avviare la sessione CDM di arresto sicuro all'interno del gestore per inviare la richiesta di arresto sicuro al server per notificare che la riproduzione è stata arrestata in questo momento, ma può essere eseguita anche in un secondo momento.
Per configurare l'arresto sicuro se l'utente si allontana dalla pagina o chiude la scheda o il browser:
- Non è necessaria alcuna azione dell'app per registrare lo stato di arresto; sarà registrato per l'utente.
Per configurare l'arresto sicuro per i controlli pagina personalizzati o le azioni dell'utente, ad esempio pulsanti di spostamento personalizzati o l'avvio di una nuova presentazione prima del completamento della presentazione corrente:
- Quando si verifica un'azione utente personalizzata, l'app deve impostare l'origine su NULL, che attiverà le basi multimediali per eliminare la topologia, distruggere i decrittografi e impostare lo stato di arresto.
L'esempio seguente illustra come usare l'arresto sicuro nell'app Web:
// JavaScript source code
var g_prkey = null;
var g_keySession = null;
var g_fUseSpecificSecureStopSessionID = false;
var g_encodedMeteringCert = 'Base64 encoded of your metering cert (aka publisher cert)';
// Note: g_encodedLASessionId is the CDM session ID of the proactive or reactive license acquisition
// that we want to initiate the secure stop process.
var g_encodedLASessionId = null;
function main()
{
...
g_prkey = new MSMediaKeys("com.microsoft.playready");
...
// add 'onended' event handler to the video element
// Assume 'myvideo' is the ID of the video element
var videoElement = document.getElementById("myvideo");
videoElement.onended = function (e) {
//
// Calling removeAttribute("src") will set the source to null
// which will trigger the MF to tear down the topology, destroy the
// decryptor(s) and set the stop state. This is required in order
// to set the stop state.
//
videoElement.removeAttribute("src");
videoElement.load();
onEndOfStream();
};
}
function onEndOfStream()
{
...
createSecureStopCDMSession();
...
}
function createSecureStopCDMSession()
{
try{
var targetMediaCodec = "video/mp4";
var customData = "my custom data";
var encodedSessionId = g_encodedLASessionId;
if( !g_fUseSpecificSecureStopSessionID )
{
// Use "*" (wildcard) as the session ID to include all secure stop sessions
// TODO: base64 encode "*" and place encoded result to encodedSessionId
}
var int8ArrayCDMdata = formatSecureStopCDMData( encodedSessionId, customData, g_encodedMeteringCert );
var emptyArrayofInitData = new Uint8Array();
g_keySession = g_prkey.createSession(targetMediaCodec, emptyArrayofInitData, int8ArrayCDMdata);
addPlayreadyKeyEventHandler();
} catch( e )
{
// TODO: Handle exception
}
}
function addPlayreadyKeyEventHandler()
{
// add 'keymessage' eventhandler
g_keySession.addEventListener('mskeymessage', function (event) {
// TODO: Get the keyMessage from event.message.buffer which contains the secure stop challenge
// The keyMessage format for the secure stop is similar to LA as below:
//
// <PlayReadyKeyMessage type="SecureStop" >
// <SecureStop version="1.0" >
// <Challenge encoding="base64encoded">
// secure stop challenge
// </Challenge>
// <HttpHeaders>
// <HttpHeader>
// <name>Content-Type</name>
// <value>"content type data"</value>
// </HttpHeader>
// <HttpHeader>
// <name>SOAPAction</name>
// <value>soap action</value>
// </HttpHeader>
// ....
// </HttpHeaders>
// </SecureStop>
// </PlayReadyKeyMessage>
// TODO: send the secure stop challenge to a server that handles the secure stop challenge
// TODO: Receive and response and call event.target.Update() to process the response
});
// add 'keyerror' eventhandler
g_keySession.addEventListener('mskeyerror', function (event) {
var session = event.target;
...
session.close();
});
// add 'keyadded' eventhandler
g_keySession.addEventListener('mskeyadded', function (event) {
var session = event.target;
...
session.close();
});
}
/**
* desc@ formatSecureStopCDMData
* generate playready CDMData
* CDMData is in xml format:
* <PlayReadyCDMData type="SecureStop">
* <SecureStop version="1.0">
* <SessionID>B64 encoded session ID</SessionID>
* <CustomData>B64 encoded custom data</CustomData>
* <ServerCert>B64 encoded server cert</ServerCert>
* </SecureCert>
* </PlayReadyCDMData>
*/
function formatSecureStopCDMData(encodedSessionId, customData, encodedPublisherCert)
{
var encodedCustomData = null;
// TODO: base64 encode the custom data and place the encoded result to encodedCustomData
var CDMDataStr = "<PlayReadyCDMData type=\"SecureStop\">" +
"<SecureStop version=\"1.0\" >" +
"<SessionID>" + encodedSessionId + "</SessionID>" +
"<CustomData>" + encodedCustomData + "</CustomData>" +
"<ServerCert>" + encodedPublisherCert + "</ServerCert>" +
"</SecureStop></PlayReadyCDMData>";
var int8ArrayCDMdata = null
// TODO: Convert CDMDataStr to Uint8 byte array and palce the converted result to int8ArrayCDMdata
return int8ArrayCDMdata;
}
Nota
I dati di arresto sicuro nell'esempio <SessionID>B64 encoded session ID</SessionID>
precedente possono essere un asterisco (*), che è un carattere jolly per tutte le sessioni di arresto sicure registrate. Ovvero, il tag SessionID può essere una sessione specifica o un carattere jolly (*) per selezionare tutte le sessioni di arresto sicure.
Considerazioni sulla programmazione per l'estensione dei supporti crittografati
Questa sezione elenca le considerazioni sulla programmazione da tenere in considerazione durante la creazione dell'app web abilitata per PlayReady per Windows 10.
Gli oggetti MSMediaKeys e MSMediaKeySession creati dall'app devono essere mantenuti attivi fino alla chiusura dell'app. Un modo per garantire che questi oggetti rimangano attivi consiste nell'assegnarli come variabili globali (le variabili diventano fuori ambito e soggette a Garbage Collection se dichiarate come variabile locale all'interno di una funzione). L'esempio seguente, ad esempio, assegna le variabili g_msMediaKeys e g_mediaKeySession come variabili globali, che vengono quindi assegnate agli oggetti MSMediaKeys e MSMediaKeySession nella funzione.
var g_msMediaKeys;
var g_mediaKeySession;
function foo() {
...
g_msMediaKeys = new MSMediaKeys("com.microsoft.playready");
...
g_mediaKeySession = g_msMediaKeys.createSession("video/mp4", intiData, null);
g_mediaKeySession.addEventListener(this.KEYMESSAGE_EVENT, function (e)
{
...
downloadPlayReadyKey(url, keyMessage, function (data)
{
g_mediaKeySession.update(data);
});
});
g_mediaKeySession.addEventListener(this.KEYADDED_EVENT, function ()
{
...
g_mediaKeySession.close();
g_mediaKeySession = null;
});
}
Per altre informazioni, vedere le applicazioni di esempio.