Partager via


Extension EME (Encrypted Media Extension) PlayReady

Cette section explique comment modifier votre application web PlayReady pour prendre en charge les modifications apportées de la version précédente de Windows 8.1 à la version de Windows 10.

L’utilisation d’éléments multimédias PlayReady dans Internet Explorer permet aux développeurs de créer des applications web capables de fournir du contenu PlayReady à l’utilisateur tout en appliquant les règles d’accès définies par le fournisseur de contenu. Cette section explique comment ajouter des éléments multimédias PlayReady à vos applications web existantes en utilisant uniquement HTML5 et JavaScript.

Nouveautés de l’extension de média chiffré PlayReady

Cette section fournit la liste des modifications apportées à l’extension EME (PlayReady Encrypted Media Extension) pour activer la protection du contenu PlayReady sur Windows 10.

La liste suivante décrit les nouvelles fonctionnalités et les modifications apportées à l’extension PlayReady Encrypted Media pour Windows 10 :

  • Ajout de la gestion des droits numériques matériels (DRM).

    La prise en charge de la protection de contenu basée sur le matériel permet la lecture sécurisée du contenu haute définition (HD) et ultra-haute définition (UDP) sur plusieurs plateformes d’appareils. Matériel de clé (y compris les clés privées, les clés de contenu et tout autre matériel de clé utilisé pour dériver ou déverrouiller ces clés), et les exemples vidéo compressés et non compressés déchiffrés sont protégés en tirant parti de la sécurité matérielle.

  • Fournit une acquisition proactive de licences non persistantes.

  • Fournit l’acquisition de plusieurs licences dans un message.

    Vous pouvez utiliser un objet PlayReady avec plusieurs identificateurs de clé (KeyID) comme dans Windows 8.1 ou utiliser des données de modèle de déchiffrement de contenu (CDMData) avec plusieurs KeyID.

    Remarque

    Dans Windows 10, plusieurs identificateurs de clé sont pris en charge sous <KeyID> dans CDMData.

  • Ajout de la prise en charge de l’expiration en temps réel ou d’une licence de durée limitée (LDL).

    Permet de définir l’expiration en temps réel sur les licences.

  • Ajout de la prise en charge de la stratégie HDCP Type 1 (version 2.2).

  • Miracast est désormais implicite en tant que sortie.

  • Ajout d’un arrêt sécurisé.

    L’arrêt sécurisé permet à un appareil PlayReady d’affirmer en toute confiance auprès d’un service de diffusion en continu multimédia que la lecture multimédia s’est arrêtée pour n’importe quel élément de contenu donné.

  • Ajout de la séparation des licences audio et vidéo.

    Les pistes distinctes empêchent le décodage de la vidéo en tant qu’audio ; activation d’une protection de contenu plus robuste. Les normes émergentes nécessitent des clés distinctes pour les pistes audio et visuelles.

  • Ajout de MaxResDecode.

    Cette fonctionnalité a été ajoutée pour limiter la lecture du contenu à une résolution maximale, même en possession d’une clé plus compatible (mais pas d’une licence). Il prend en charge les cas où plusieurs tailles de flux sont encodées avec une seule clé.

Prise en charge de l’extension multimédia chiffrée dans PlayReady

Cette section décrit la version de l’extension de média chiffré W3C prise en charge par PlayReady.

PlayReady pour Web Apps est actuellement lié au projet EME (Encrypted Media Extension) W3C du 10 mai 2013. Cette prise en charge sera modifiée par la spécification EME mise à jour dans les futures versions de Windows.

Utiliser la gestion des droits numériques matériels

Cette section décrit comment votre application web peut utiliser la gestion des droits numériques du matériel PlayReady et comment désactiver la gestion des droits numériques matériels si le contenu protégé ne le prend pas en charge.

Pour utiliser la gestion des droits numériques matériels PlayReady, votre application web JavaScript doit utiliser la méthode isTypeSupported EME avec un identificateur système clé permettant d’interroger com.microsoft.playready.hardware la prise en charge de la gestion des droits numériques du matériel PlayReady à partir du navigateur.

Parfois, certains contenus ne sont pas pris en charge dans la gestion des droits numériques matériels. Le contenu cocktail n’est jamais pris en charge dans la gestion des droits numériques matériels ; si vous souhaitez lire du contenu cocktail, vous devez refuser la gestion des droits numériques matériels. Certaines drm matérielles prennent en charge HEVC et certaines ne le seront pas ; si vous souhaitez lire le contenu HEVC et la gestion des droits numériques matériels ne le prennent pas en charge, vous souhaiterez également vous désinscrire.

Remarque

Pour déterminer si le contenu HEVC est pris en charge, après instanciation com.microsoft.playready, utilisez la méthode PlayReadyStatics.CheckSupportedHardware .

Ajouter un arrêt sécurisé à votre application web

Cette section explique comment ajouter un arrêt sécurisé à votre application web.

L’arrêt sécurisé permet à un appareil PlayReady d’affirmer en toute confiance auprès d’un service de diffusion en continu multimédia que la lecture multimédia s’est arrêtée pour n’importe quel élément de contenu donné. Cette fonctionnalité garantit que vos services de diffusion en continu multimédia fournissent une application précise et un signalement précis des limitations d’utilisation sur différents appareils pour un compte donné.

Il existe deux scénarios principaux pour l’envoi d’un défi d’arrêt sécurisé :

  • Lorsque la présentation multimédia s’arrête en raison de la fin du contenu a été atteinte ou lorsque l’utilisateur a arrêté la présentation multimédia quelque part au milieu.
  • Lorsque la session précédente se termine de façon inattendue (par exemple, en raison d’un blocage du système ou de l’application). L’application doit interroger, au démarrage ou à l’arrêt, les sessions d’arrêt sécurisées en attente et envoyer des défis distincts de toute autre lecture multimédia.

Les procédures suivantes décrivent comment configurer un arrêt sécurisé pour différents scénarios.

Pour configurer un arrêt sécurisé pour une fin normale d’une présentation :

  1. Inscrivez l’événement onEnded avant le démarrage de la lecture.
  2. Le gestionnaire d’événements onEnded doit appeler removeAttribute("src") à partir de l’objet élément vidéo/audio pour définir la source sur NULL , ce qui déclenchera la destruction de la topologie, détruire le ou les déchiffreurs et définir l’état d’arrêt.
  3. Vous pouvez démarrer la session CDM d’arrêt sécurisé à l’intérieur du gestionnaire pour envoyer le défi d’arrêt sécurisé au serveur pour avertir que la lecture s’est arrêtée pour le moment, mais elle peut également être effectuée ultérieurement.

Pour configurer un arrêt sécurisé si l’utilisateur quitte la page ou ferme l’onglet ou le navigateur :

  • Aucune action d’application n’est requise pour enregistrer l’état d’arrêt ; il sera enregistré pour vous.

Pour configurer un arrêt sécurisé pour les contrôles de page personnalisés ou les actions utilisateur (par exemple, les boutons de navigation personnalisés ou le démarrage d’une nouvelle présentation avant la fin de la présentation actuelle) :

  • Lorsque l’action utilisateur personnalisée se produit, l’application doit définir la source sur NULL , ce qui déclenchera la destruction de la topologie, détruire le ou les déchiffreurs et définir l’état d’arrêt.

L’exemple suivant montre comment utiliser un arrêt sécurisé dans votre application 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;
}

Remarque

Les données d’arrêt sécurisées dans <SessionID>B64 encoded session ID</SessionID> l’exemple ci-dessus peuvent être un astérisque (*), qui est une carte générique pour toutes les sessions d’arrêt sécurisées enregistrées. Autrement dit, la balise SessionID peut être une session spécifique ou une carte générique (*) pour sélectionner toutes les sessions d’arrêt sécurisées.

Considérations relatives à la programmation pour l’extension de média chiffré

Cette section répertorie les considérations de programmation que vous devez prendre en compte lors de la création de votre application web compatible PlayReady pour Windows 10.

Les objets MSMediaKeys et MSMediaKeySession créés par votre application doivent être conservés en vie jusqu’à ce que votre application se ferme. L’une des façons de s’assurer que ces objets restent actifs consiste à les affecter en tant que variables globales (les variables deviennent hors de portée et soumises au garbage collection si elles sont déclarées en tant que variable locale à l’intérieur d’une fonction). Par exemple, l’exemple suivant affecte les variables g_msMediaKeys et g_mediaKeySession en tant que variables globales, qui sont ensuite affectées aux objets MSMediaKeys et MSMediaKeySession dans la fonction.

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;
  });
}

Pour plus d’informations, consultez les exemples d’applications.

Voir aussi