Présentation du flux de travail associé au contenu protégé

Flash Player 10.1 et ultérieur, Adobe AIR 2.0 et ultérieur

Le flux de travail de haut niveau suivant indique comment une application peut récupérer et lire un contenu protégé. Il part du principe que l’application est conçue spécifiquement pour lire un contenu protégé par Flash Access :

  1. Récupérez les métadonnées du contenu.

  2. Exécutez les mises à jour de Flash Player, s’il y a lieu.

  3. Vérifiez si une licence est disponible localement. Si tel est le cas, chargez-la et passez à l’étape 7. Dans le cas contraire, passez à l’étape 4.

  4. Vérifiez si l’authentification est obligatoire. Dans le cas contraire, passez à l’étape 7.

  5. Si l’authentification est obligatoire, demandez les informations d’identification à l’utilisateur et transmettez-les au serveur de licences.

  6. Lorsque l’authentification aboutit, téléchargez la licence du serveur.

  7. Lisez le contenu.

Si aucune erreur n’est survenue et si l’utilisateur a été autorisé à visionner le contenu, l’objet NetStream distribue un objet DRMStatusEvent. L’application procède alors à la lecture. L’objet DRMStatusEvent mémorise les informations relatives au voucher, qui identifient les régulations et autorisations de l’utilisateur. Il contient par exemple des informations relatives à la disponibilité du contenu hors connexion ou à la date d’expiration de la licence. L’application peut utiliser ces données pour avertir l’utilisateur de l’état de ses régulations. Elle peut par exemple afficher dans une barre d’état le nombre de jours restants pendant lesquels l’utilisateur est autorisé à visionner le contenu.

(AIR uniquement) Si l’utilisateur est autorisé à accéder au contenu hors connexion, le voucher est mis en mémoire cache et le contenu chiffré est téléchargé sur la machine de l’utilisateur. L’utilisateur peut accéder au contenu pendant le nombre de jours défini par la période de location hors connexion. La propriété detail de l’événement contient "DRM.voucherObtained". L’application décide de l’emplacement local de stockage du contenu pour assurer sa disponibilité hors connexion. Vous pouvez également précharger les vouchers à l’aide de la classe DRMManager.

Toutes les erreurs DRM entraînent la distribution par l’application d’un objet d’événement DRMErrorEvent ou, dans AIR, d’un objet DRMAuthenticationErrorEvent. C’est l’application elle-même qui est chargée de gérer explicitement tous les autres événements d’erreur, notamment lorsque l’utilisateur saisit correctement ses informations d’identification, mais que le voucher qui protège le contenu chiffré limite l’accès au contenu. Un utilisateur authentifié ne peut par exemple pas accéder au contenu s’il ne s’est pas acquitté des droits. Ce cas peut également se produire lorsque deux membres inscrits du même éditeur tentent de partager du contenu que seul l’un d’entre eux a payé. L’application doit informer l’utilisateur de l’erreur et proposer une solution de remplacement. Par exemple, l’application peut donner à l’utilisateur des instructions sur le mode d’inscription et de paiement des droits d’affichage.

Flux de travail détaillé des API

Ce flux de travail illustre de manière plus détaillée le flux de travail associé à un contenu protégé. Il décrit les API impliquées dans la lecture du contenu protégé par Flash Access.

  1. Par le biais d’un objet URLLoader, chargez les octets du fichier de métadonnées du contenu protégé. Définissez cet objet sur une variable, telle que metadata_bytes.

    Tout contenu contrôlé par Flash Access contient des métadonnées Flash Access. Lorsque le contenu est mis en package, ces métadonnées peuvent être enregistrées dans un fichier de métadonnées distinct (.metadata) parallèlement au contenu. Pour plus d’informations, voir la documentation de Flash Access.

  2. Créez une occurrence de DRMContentData. Placez ce code dans un bloc try-catch :

    new DRMContentData(metadata_bytes)

    metadata_bytes est l’objet URLLoader obtenu à l’étape 1.

  3. (Flash Player uniquement) Le moteur d’exécution recherche le module Flash Access. S’il ne le trouve pas, un message IllegalOperationError associé au code d’erreur 3344 est renvoyé.

    Pour gérer cette erreur, téléchargez le module Flash Access à l’aide de l’API SystemUpdater. Une fois ce module téléchargé, l’objet SystemUpdater distribue un événement COMPLETE. Définissez un écouteur d’événement qui retourne à l’étape 2 lors de la distribution de cet événement. Le code suivant illustre ces étapes :

    flash.system.SystemUpdater.addEventListener(Event.COMPLETE, updateCompleteHandler); 
    flash.system.SystemUpdater.update(flash.system.SystemUpdaterType.DRM)
    private function updateCompleteHandler (event:Event):void { 
        /*redo step 2*/ 
        drmContentData = new DRMContentData(metadata_bytes); 
    } 

    Si le lecteur en tant que tel doit être mis à jour, un événement d’état est distribué. Pour plus d’informations sur la gestion de cet événement, voir Ecoute d’un événement de mise à jour.

    Remarque : dans les applications AIR, le programme d’installation AIR gère la mise à jour du module Flash Access et les mises à jour du moteur d’exécution requises.
  4. Créez des écouteurs qui écoutent les événements DRMStatusEvent et DRMErrorEvent distribués par l’objet DRMManager :

    DRMManager.addEventListener(DRMStatusEvent.DRM_STATUS, onDRMStatus); 
    DRMManager.addEventListener(DRMErrorEvent.DRM_ERROR, onDRMError);

    Dans l’écouteur d’événements DRMStatusEvent, vérifiez que le voucher est valide (valeur autre que null). Dans l’écouteur d’événements DRMErrorEvent, gérez les événements DRMErrorEvents. Voir Utilisation de la classe DRMStatusEvent et Utilisation de la classe DRMErrorEvent.

  5. Chargez le voucher (la licence) requis pour lire le contenu.

    Essayez tout d’abord de charger une licence stockée localement pour lire le contenu :

    DRMManager.loadvoucher(drmContentData, LoadVoucherSetting.LOCAL_ONLY)

    Une fois le chargement terminé, l’objet DRMManager distribue DRMStatusEvent.DRM_Status.

  6. Si l’objet DRMVoucher possède une valeur autre que null, le voucher est valide. Passez à l’étape 13.

  7. Si l’objet DRMVoucher est défini sur null, vérifiez la méthode d’authentification requise par la régulation associée au contenu. Faites appel à la propriété DRMContentData.authenticationMethod.

  8. Si la méthode d’authentification est ANONYMOUS, passez à l’étape 13.

  9. Si la méthode d’authentification est USERNAME_AND_PASSWORD, l’application doit intégrer un mécanisme permettant à l’utilisateur d’entrer des informations d’identification. Transmettez ces informations d’identification au serveur de licences pour authentifier l’utilisateur :

    DRMManager.authenticate(metadata.serverURL, metadata.domain, username, password)

    DRMManager distribue un événement DRMAuthenticationErrorEvent si l’authentification échoue, un événement DRMAuthenticationCompleteEvent si elle aboutit. Associez des écouteurs à ces événements.

  10. Si l’authentification échoue, l’application doit retourner à l’étape 9. Assurez-vous que l’application intègre un mécanisme permettant de gérer et restreindre les échecs successifs d’authentification. Après trois tentatives, vous pouvez, par exemple, afficher un message indiquant à l’utilisateur que l’authentification a échoué et qu’il est impossible de lire le contenu.

  11. Si l’authentification aboutit, téléchargez la licence du serveur de licences :

    DRMManager.loadvoucher(drmContentData, LoadVoucherSetting.FORCE_REFRESH)

    Une fois le chargement terminé, l’objet DRMManager distribue l’événement DRMStatusEvent.DRM_STATUS. Ecoutez cet événement. Une fois ce dernier distribué, vous pouvez lire le contenu.

  12. (Facultatif) Si l’authentification aboutit, vous pouvez capturer le jeton d’authentification, à savoir un tableau d’octets placé en mémoire cache. Récupérez ce jeton à l’aide de la propriété DRMAuthenticationCompleteEvent.token. Vous pouvez stocker et utiliser le jeton d’authentification pour éviter à l’utilisateur d’avoir à entrer plusieurs fois les informations d’identification associées au contenu. Le serveur de licences détermine la période de validité du jeton d’authentification.

    Pour utiliser le jeton stocké au lieu d’inviter l’utilisateur à entrer des informations d’identification, définissez-le à l’aide de la méthode DRMManager.setAuthenticationToken(). Téléchargez ensuite la licence à partir du serveur de licences et lisez le contenu (voir étape 8).

  13. Lisez la vidéo en créant un objet NetStream, puis en appelant sa méthode play() :

    stream = new NetStream(connection); 
    stream.addEventListener(DRMStatusEvent.DRM _STATUS, drmStatusHandler); 
    stream.addEventListener(DRMErrorEvent.DRM_ERROR, drmErrorHandler); 
    stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); 
    stream.client = new CustomClient(); 
    video.attachNetStream(stream); 
    stream.play(videoURL); 

Evénements DRM

Le moteur d’exécution distribue un grand nombre d’événements lorsqu’une application essaie de lire un contenu protégé :

  • DRMAuthenticateEvent (AIR uniquement), distribué par NetStream

  • DRMAuthenticationCompleteEvent, distribué par DRMManager

  • DRMAuthenticationErrorEvent, distribué par DRMManager

  • DRMErrorEvent, distribué par NetStream et DRMManager

  • DRMStatusEvent, distribué par NetStream et DRMManager

  • StatusEvent

  • NetStatusEvent (voir Ecoute d’un événement de mise à jour)

Pour prendre en charge un contenu protégé par Flash Access, associez des écouteurs aux événements DRM.

Préchargement de vouchers pour une lecture hors connexion

Vous pouvez précharger les vouchers (licences) requis pour lire le contenu protégé par Flash Access. Les vouchers préchargés permettent aux utilisateurs de visionner le contenu même si leur connexion Internet n’est pas active. (Le processus de préchargement à proprement parler requiert une connexion à Internet.) Faites appel à la méthode preloadEmbeddedMetadata() de la classe NetStream et à la classe DRMManager pour précharger les vouchers. Dans AIR 2.0 et ultérieur, vous pouvez précharger directement des vouchers par le biais d’un objet DRMContentData. Il est préférable d’utiliser cette technique, car elle permet de mettre à jour l’objet DRMContentData indépendamment du contenu. (La méthode preloadEmbeddedData() extrait l’objet DRMContentData du contenu.)

Utilisation de l’objet DRMContentData

La procédure ci-dessous décrit le flux de travail de préchargement du voucher pour un fichier multimédia protégé par le biais d’un objet DRMContentData.

  1. Extrayez les métadonnées binaires associées au contenu mis en package. Si vous utilisez Flash Access Java Reference Packager, ce fichier de métadonnées est automatiquement généré avec une extension .metadata. Vous pourriez, par exemple, télécharger ces métadonnées à l’aide de la classe URLLoader.

  2. Créez un objet DRMContentData en transmettant les métadonnées à la fonction constructeur :

    var drmData:DRMContentData = new DRMContentData( metadata );
  3. Les autres étapes sont identiques au flux de travail décrit à la section Présentation du flux de travail associé au contenu protégé.

Utilisation de preloadEmbeddedMetadata()

La procédure suivante décrit le flux de travail de préchargement du voucher associé à un fichier multimédia protégé par DRM par le biais de preloadEmbeddedMetadata() :

  1. Téléchargez et stockez le fichier multimédia. (Les métadonnées DRM ne peuvent être préchargées qu’à partir de fichiers stockés localement.)

  2. Créez les objets NetConnection et NetStream, en fournissant des implémentations pour les fonctions de rappel onDRMContentData() et onPlayStatus() de l’objet client NetStream.

  3. Créez un objet NetStreamPlayOptions et définissez la propriété stream sur l’URL du fichier multimédia local.

  4. Appelez la méthode NetStream preloadEmbeddedMetadata(), en transmettant l’objet NetStreamPlayOptions identifiant le fichier multimédia à analyser.

  5. Si le fichier multimédia contient des métadonnées DRM, la fonction de rappel onDRMContentData() est invoquée. Les métadonnées sont transmises à cette fonction sous forme d’objet DRMContentData.

  6. Utilisez l’objet DRMContentData pour obtenir le voucher à l’aide de la méthode DRMManager loadVoucher().

    Si la valeur de la propriété authenticationMethod de l’objet DRMContentData est userNameAndPassword, authentifiez l’utilisateur sur le serveur des droits multimédias avant de charger le voucher. Les propriétés serverURL et domain de l’objet DRMContentData peuvent être transmis à la méthode DRMManager authenticate(), de même que les informations d’identification de l’utilisateur.

  7. La fonction de rappel onPlayStatus() est invoquée lorsque l’analyse du fichier est terminée. Si la fonction onDRMContentData() n’a pas été appelée, le fichier ne contient pas les métadonnées nécessaires à l’obtention d’un voucher. L’absence de cet appel peut également signifier que Flash Access ne protège pas ce fichier.

L’exemple de code pour AIR suivant illustre le préchargement d’un voucher associé à un fichier multimédia local :

package 
{ 
import flash.display.Sprite; 
import flash.events.DRMAuthenticationCompleteEvent; 
import flash.events.DRMAuthenticationErrorEvent; 
import flash.events.DRMErrorEvent;   
import flash.ev ents.DRMStatusEvent; 
import flash.events.NetStatusEvent; 
import flash.net.NetConnection; 
import flash.net.NetStream; 
import flash.net.NetStreamPlayOptions; 
import flash.net.drm.AuthenticationMethod; 
import flash.net.drm.DRMContentData; 
import flash.net.drm.DRMManager; 
import flash.net.drm.LoadVoucherSetting;   
public class DRMPreloader extends Sprite  
{ 
     private var videoURL:String = "app-storage:/video.flv"; 
    private var userName:String = "user"; 
    private var password:String = "password";  
    private var preloadConnection:NetConnection; 
    private var preloadStream:NetStream; 
    private var drmManager:DRMManager = DRMManager.getDRMManager(); 
    private var drmContentData:DRMContentData; 
    public function DRMPreloader():void { 
        drmManager.addEventListener( 
            DRMAuthenticationCompleteEvent.AUTHENTICATION_COMPLETE, 
            onAuthenticationComplete); 
        drmManager.addEventListener(DRMAuthenticationErrorEvent.AUTHENTICATION_ERROR, 
            onAuthenticationError);             
        drmManager.addEventListener(DRMStatusEvent.DRM_STATUS, onDRMStatus); 
        drmManager.addEventListener(DRMErrorEvent.DRM_ERROR, onDRMError); 
        preloadConnection = new NetConnection(); 
        preloadConnection.addEventListener(NetStatusEvent.NET_STATUS, onConnect); 
        preloadConnection.connect(null);            
    } 
 
    private function onConnect( event:NetStatusEvent ):void 
    { 
        preloadMetadata(); 
    } 
    private function preloadMetadata():void 
    { 
        preloadStream = new NetStream( preloadConnection ); 
        preloadStream.client = this; 
        var options:NetStreamPlayOptions = new NetStreamPlayOptions(); 
        options.streamName = videoURL; 
        preloadStream.preloadEmbeddedData( options );                         
    }     
    public function onDRMContentData( drmMetadata:DRMContentData ):void 
    { 
        drmContentData = drmMetadata; 
        if ( drmMetadata.authenticationMethod == AuthenticationMethod.USERNAME_AND_PASSWORD ) 
        { 
            authenticateUser(); 
        } 
        else 
            { 
                getVoucher(); 
            } 
    } 
    private function getVoucher():void 
    { 
        drmManager.loadVoucher( drmContentData, LoadVoucherSetting.ALLOW_SERVER ); 
    } 
 
    private function authenticateUser():void 
    { 
        drmManager.authenticate( drmContentData.serverURL, drmContentData.domain, userName, password ); 
    } 
    private function onAuthenticationError( event:DRMAuthenticationErrorEvent ):void 
    { 
        trace( "Authentication error: " + event.errorID + ", " + event.subErrorID ); 
    } 
 
    private function onAuthenticationComplete( event:DRMAuthenticationCompleteEvent ):void 
    { 
        trace( "Authenticated to: " + event.serverURL + ", domain: " + event.domain ); 
        getVoucher(); 
    } 
    private function onDRMStatus( event:DRMStatusEvent ):void 
    { 
        trace( "DRM Status: " + event.detail); 
        trace("--Voucher allows offline playback = " + event.isAvailableOffline ); 
        trace("--Voucher already cached          = " + event.isLocal ); 
        trace("--Voucher required authentication = " + !event.isAnonymous ); 
    } 
    private function onDRMError( event:DRMErrorEvent ):void 
    { 
        trace( "DRM error event: " + event.errorID + ", " + event.subErrorID + ", " + event.text ); 
    } 
    public function onPlayStatus( info:Object ):void 
    { 
        preloadStream.close(); 
    } 
} 
}