Importante
: Flash Player 11.5 y versiones posteriores integra el módulo Adobe Access, por lo que el paso de actualización (llamar a
SystemUpdater.update(SystemUpdaterType.DRM)
) no es necesario. Esto incluye los siguientes navegadores y plataformas:
-
Control ActiveX para Flash Player 11.5, para todas las plataforma excepto Internet Explorer en Windows 8 en procesadores Intel
-
Plug-in de Flash Player 11.5, para todos los navegadores
-
Adobe AIR (escritorio y móvil)
Esto significa que el paso de actualización
sigue siendo necesario
en los casos siguientes:
-
Internet Explorer en Windows 8 en procesadores Intel
-
Flash Player 11.4 y versiones anteriores, excepto en Google Chrome 22 y versiones posteriores (todas las plataformas) o 21 y versiones posteriores (Windows)
Nota:
sigue siendo seguro llamar a
SystemUpdater.update(SystemUpdaterType.DRM)
en un sistema con Flash Player 11.5 o versión posterior, pero no se descargará nada.
El siguiente flujo de trabajo de alto nivel muestra cómo una aplicación puede recuperar y reproducir contenido protegido. El flujo de trabajo asume que la aplicación está diseñada específicamente para reproducir contenido protegido con Adobe Access:
-
Obtenga los metadatos del contenido.
-
Gestione las actualizaciones a Flash Player, si es necesario.
-
Compruebe si hay una licencia disponible localmente. Si es así, cárguela y vaya al paso 7. Si no, vaya al paso 4.
-
Compruebe si es necesario autenticarse. Si no lo es, vaya al paso 7.
-
Si se requiere autenticación, obtenga las credenciales para el usuario y envíelas al servidor de licencias.
-
Si se precisa registrar el dominio, únase a él (AIR 3.0 y posterior).
-
Una vez completada la autenticación, descargue la licencia del servidor.
-
Reproduzca el contenido.
Si no se produce ningún error y se autoriza correctamente al usuario a ver el contenido, el objeto NetStream distribuye un objeto DRMStatusEvent. La aplicación comienza a reproducirse después. El objeto DRMStatusEvent contiene la información de la licencia asociada, que identifica la póliza del usuario y sus permisos. Por ejemplo, contiene información relacionada con si el contenido puede verse sin conexión o cuándo caduca la licencia. La aplicación puede aprovechar estos datos para informar al usuario del estado de su póliza. Por ejemplo: la aplicación puede mostrar en una barra de estado el número de días restantes para que el usuario pueda ver el contenido.
Si el usuario tiene permiso para acceder sin conexión, la licencia se guarda en caché y el contenido cifrado se descarga en el equipo del usuario. El contenido está accesible en la duración definida en la caché de la licencia. La propiedad
detail
del evento contiene
"DRM.voucherObtained"
. La aplicación decide dónde guardar el contenido en el equipo para tenerlo a disposición fuera de línea. También se puede realizar la carga previa de licencias mediante la clase DRMManager.
Nota:
el almacenamiento en caché y la precarga de licencias se admite tanto en AIR como en Flash Player. Sin embargo, la descarga y el almacenamiento del contenido cifrado solo se admite en AIR.
Es responsabilidad de la aplicación gestionar de forma explícita los eventos de error. Estos eventos incluyen casos en que el usuario introduce credenciales válidas pero la licencia que protege el contenido cifrado limita el acceso al contenido. Por ejemplo, un usuario autenticado no puede acceder al contenido si no ha pagado por los derechos. Este caso también puede darse si dos miembros registrados del mismo editor intentan compartir contenido por el que solo uno de ellos ha pagado. La aplicación debe informar al usuario sobre el error y ofrecer una sugerencia como alternativa. Una alternativa habitual es ofrecer instrucciones para registrarse y pagar por los derechos de visionado.
Flujo de trabajo detallado de la API
Este flujo de trabajo ofrece una vista más detallada del flujo de trabajo de contenido protegido. Este flujo de trabajo describe las API específicas utilizadas para reproducir contenido protegido con Adobe Access.
-
Con ayuda de un objeto URLLoader, cargue los bytes del archivo de metadatos del contenido protegido. Defina este objeto como una variable, por ejemplo,
metadata_bytes
.
Todo el contenido controlador por Adobe Access tiene metadatos de Adobe Access. Cuando se empaqueta el contenido, estos metadatos se pueden guardar como un archivo de metadatos independiente (.metadata) junto con el contenido. Para obtener más información, consulte la documentación de Adobe Access.
-
Cree una instancia de DRMContentData. Coloque este código en un bloque try-catch:
new DRMContentData(
metadata_bytes
)
donde
metadata_bytes
es el objeto URLLoader obtenido en el paso 1.
-
(Solo Flash Player) El motor de ejecución busca el módulo Adobe Access. Si no se encuentra, se emite un error IllegalOperationError con código de error DRMErrorEvent 3344 o DRMErrorEvent 3343.
Para gestionar este error, descargue el módulo Adobe Access con la API SystemUpdater. Una vez descargado el módulo, el objeto SystemUpdater distribuye un evento COMPLETE. Incluya un detector de eventos para este evento que vuelve al paso 2 cuando se distribuye. El siguiente código demuestra estos pasos:
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 se debe actualizar el propio reproductor, se distribuye un evento status. Para obtener más información sobre la gestión de este evento, consulte
Detección de un evento update
.
Nota:
en aplicaciones de AIR, el archivo de instalación de AIR gestiona la actualización del módulo Adobe Access y las posibles actualizaciones necesarias del motor de ejecución.
-
Cree detectores para detectar los eventos DRMStatusEvent y DRMErrorEvent del objeto DRMManager:
DRMManager.addEventListener(DRMStatusEvent.DRM_STATUS, onDRMStatus);
DRMManager.addEventListener(DRMErrorEvent.DRM_ERROR, onDRMError);
En el detector de DRMStatusEvent, confirme que la licencia es válida (no null). En el detector de DRMErrorEvent, gestione eventos DRMErrorEvent. Consulte
Uso de la clase DRMStatusEvent
y
Uso de la clase DRMErrorEvent
.
-
Cargue la licencia necesaria para poder reproducir el contenido.
Primero, intente cargar la licencia guardada localmente para reproducir el contenido:
DRMManager.loadvoucher(drmContentData, LoadVoucherSetting.LOCAL_ONLY)
Una vez completada la carga, el objeto DRMManager distribuye un evento
DRMStatusEvent.DRM_Status
.
-
Si el objeto DRMVoucher no es null, la licencia es válida. Vaya directamente al paso 13.
-
Si el objeto DRMVoucher es null, compruebe el método de autenticación requerido por la póliza para este contenido. Utilice la propiedad
DRMContentData.authenticationMethod
.
-
Si el método de autenticación es
ANONYMOUS
, vaya al paso 13.
-
Si el método de autenticación es
USERNAME_AND_PASSWORD
, su aplicación debe contar con un mecanismo para que el usuario pueda introducir sus credenciales. Envíe estas credenciales al servidor de licencias para autenticar al usuario:
DRMManager.authenticate(metadata.serverURL, metadata.domain, username, password)
DRMManager distribuye un evento
DRMAuthenticationErrorEvent
si falla la autenticación y un evento
DRMAuthenticationCompleteEvent
si la autenticación se produce correctamente. Cree detectores para estos eventos.
-
Si el método de autenticación es
UNKNOWN
, se debe usar un método de autenticación personalizado. En este caso, el proveedor de contenido ha preparado la autenticación fuera de banda, sin usar las API de ActionScript 3.0. El procedimiento de autenticación personalizado debe generar un símbolo de autenticación que pueda transferirse al método
DRMManager.setAuthenticationToken()
.
-
Si la autenticación falla, la aplicación debe volver al paso 9. Asegúrese de que la aplicación cuenta con un mecanismo para gestionar y limitar el número de fallos de autenticación repetidos. Por ejemplo, tras tres intentos, muestre un mensaje al usuario indicando que la autenticación ha fallado y que no es posible visualizar el contenido.
-
Para usar el símbolo almacenado y evitar tener que pedir al usuario que introduzca sus credenciales, establezca el símbolo con el método
DRMManager.setAuthenticationToken()
. Seguidamente, descargue la licencia del servidor de licencias y reproduzca el contenido como en el paso 8.
-
(opcional) Si la autenticación se realiza correctamente, puede capturar el símbolo de autenticación (un conjunto de bytes que se almacena en memoria). Obtenga este símbolo con la propiedad
DRMAuthenticationCompleteEvent.token
. Puede almacenar y usar el símbolo de autenticación para que el usuario no tenga que introducir sus credenciales cada vez que quiera ver este contenido. El servidor de licencias determina el periodo de validez del símbolo de autenticación.
-
Si la autenticación se produce correctamente, descargue la licencia del servidor de licencias:
DRMManager.loadvoucher(drmContentData, LoadVoucherSetting.FORCE_REFRESH)
Una vez completada la carga, el objeto DRMManager distribuye un evento DRMStatusEvent.DRM_STATUS. Detecte este evento y, cuando se distribuya, podrá reproducir el contenido.
-
Reproduzca el vídeo creando un objeto NetStream y llamando a su método
play()
después:
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);
DRMContentData y objetos de sesión
Cuando se crea
DRMContentData
, se utilizará como un objeto de sesión que haga referencia al módulo DRM de Flash Player. Todas las API
DRMManager
que reciban este
DRMContentData
usarán dicho módulo DRM en particular. No obstante, hay dos API
DRMManager
que no utilizan
DRMContentData
. Son:
-
authenticate()
-
setAuthenticationToken()
Dado que no hay ningún
DRMContentData
asociado, al invocar estas API
DRMManager
se recurrirá al último módulo DRM del disco. Esto puede convertirse en un problema si se produce una actualización del módulo DRM en mitad del flujo de trabajo DRM de la aplicación. Imaginemos el siguiente contexto:
-
La aplicación crea un objeto
DRMContentData
contentData1
, que utiliza
AdobeCP1
como módulo DRM.
-
La aplicación invoca el método
DRMManager.authenticate(contentData1.serverURL,...)
.
-
La aplicación invoca el método
DRMManager.loadVoucher(contentData1, ...)
.
Si se produce una actualización del módulo DRM antes de que la aplicación llegue al paso 2, el método
DRMManager.authenticate()
dejará de autenticar con
AdobeCP2
como módulo DRM. El método
loadVoucher()
del paso 3 fallará, ya que sigue usando
AdobeCP1
como módulo DRM. La actualización puede haberse producido por la invocación de la actualización del módulo DRM por parte de otra aplicación. Esto se puede evitar invocando la actualización del módulo DRM en el inicio de la aplicación.
Eventos relacionados con DRM
El motor de ejecución distribuye varios eventos cuando una aplicación intenta reproducir contenido protegido:
-
DRMDeviceGroupErrorEvent (solo AIR), distribuido por DRMManager
-
DRMAuthenticateEvent (solo AIR), distribuido por NetStream
-
DRMAuthenticationCompleteEvent, distribuido por DRMManager
-
DRMAuthenticationErrorEvent, distribuido por DRMManager
-
DRMErrorEvent, distribuido por NetStream y por DRMManager
-
DRMStatusEvent, distribuido por NetStream y por DRMManager
-
StatusEvent
-
NetStatusEvent. Consulte
Detección de un evento update
Para admitir contenido protegido con Adobe Access, añada detectores de eventos para controlar los eventos DRM.
Precarga de licencias para reproducción sin conexión
Puede precargar las licencias necesarias para reproducir contenido protegido con Adobe Access. Las licencias precargadas permiten a los usuarios ver el contenido tengan o no una conexión a Internet. (El propio proceso de carga previa requiere una conexión a Internet.) Puede utilizar el método
preloadEmbeddedMetadata()
de la clase NetStream y la clase DRMManager para precargar licencias. En AIR 2.0 y posterior, puede utilizar un objeto DRMContentData para precargar licencias directamente. Es preferible usar esta técnica, ya que permite actualizar el objeto DRMContentData independientemente del contenido. (El método
preloadEmbeddedData()
obtiene un objeto DRMContentData del contenido.)
Uso de DRMContentData
En los siguientes pasos se describe el flujo de trabajo para precargar la licencia de un archivo multimedia protegido mediante un objeto DRMContentData.
-
Obtenga los metadatos binarios del contenido empaquetado. Si utiliza Adobe Access Java Reference Packager, este archivo de metadatos se genera automáticamente con la extensión
.metadata
. Puede, por ejemplo, descargar estos metadatos mediante la clase URLLoader.
-
Cree un objeto DRMContentData pasando los metadatos a la función constructora:
var drmData:DRMContentData = new DRMContentData( metadata );
-
El resto de los pasos son idénticos a los del flujo de trabajo descrito en
Aspectos básicos del flujo de trabajo de contenido protegido
.
Uso de preloadEmbeddedMetadata()
Los siguientes pasos describen el flujo de trabajo para precargar la licencia para un archivo multimedia protegido por DRM usando
preloadEmbeddedMetadata()
:
-
Descargue y almacene el archivo. (Los metadatos DRM solo se pueden precargar desde archivos almacenados localmente.)
-
Cree los objetos NetConnection y NetStream, proporcionando implementaciones para las funciones callback
onDRMContentData()
y
onPlayStatus()
del objeto cliente NetStream.
-
Cree un objeto NetStreamPlayOptions y establezca la propiedad
stream
en la URL del archivo de medios local.
-
Llame al método
preloadEmbeddedMetadata()
de NetStream, transmitiendo el objeto NetStreamPlayOptions e identificando el archivo de medios para analizar.
-
Si el archivo contiene metadatos DRM, se invoca la función callback
onDRMContentData()
. Los metadatos se transmiten a esta función como un objeto DRMContentData.
-
Utilice el objeto DRMContentData para obtener la licencia utilizando el método
loadVoucher()
de DRMManager.
Si el valor de la propiedad
authenticationMethod
del objeto
DRMContentData
es
flash.net.drm.AuthenticationMethod.USERNAME_AND_PASSWORD
, debe autenticar al usuario en el servidor de derechos multimedia antes de cargar la licencia. Las propiedades
serverURL
y
domain
del objeto DRMContentData se pueden transmitir al método
authenticate()
, junto con las credenciales del usuario.
-
La función
onPlayStatus()
se invoca cuando el análisis del archivo ha finalizado. Si la función
onDRMContentData()
no se ha llamado, el archivo no contiene los metadatos necesarios para obtener una licencia. La ausencia de esta llamada también puede querer decir que Adobe Access no protege este archivo.
El siguiente ejemplo de código para AIR muestra cómo precargar una licencia para un archivo multimedia 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();
}
}
}
|
|
|