Wrapper de ActionScript 3.0 para el reproductor sin bordes

Este artículo fue escrito y enviado por un programador externo. El equipo de las API y las herramientas de YouTube agradece a Matthew Richmond por su tiempo y experiencia.


Matthew Richmond, The Chopping Block, Inc.
Octubre de 2008

Introducción

En este artículo, presentaré y describiré brevemente un wrapper de ActionScript 3.0 confiable para el reproductor de YouTube sin bordes. El wrapper aprovecha la clase ExternalInterface de ActionScript y la API de JavaScript de YouTube.

Con las herramientas del reproductor de YouTube y el reproductor sin bordes de Google, los diseñadores y desarrolladores pueden integrar el poder de YouTube con rapidez y facilidad en sus proyectos en línea. Este enfoque es ideal para proyectos pequeños con presupuestos fijos que no permiten alojar videos, así como para proyectos a gran escala para clientes que desean una experiencia personalizada del usuario final sin distanciarse de su público de YouYube.

Captura de pantalla del wrapper de ActionScript 3.0
Figura 1: Captura de pantalla del wrapper de ActionScript 3.0

La API Flash de YouTube y los reproductores insertados están escritos y funcionan muy bien con ActionScript 2.0. Sin embargo, si tu proyecto es ActionScript 3.0, la integración continua se vuelve un poco más compleja. Si bien es fácil cargar los reproductores ActionScript 2.0 en un swf ActionScript 3.0, no puedes comunicarte directamente ni pasar ninguna llamada funcional al reproductor cargado. Esto es más complicado porque el archivo swf que proviene de los servidores de TuTube está cargando un video en sí mismo. Nuestro wrapper debe estar completamente al tanto de ese hecho y reaccionar en consecuencia. Afortunadamente, el lenguaje ActionScript contiene dos soluciones posibles para volver a conectar estos elementos anidados pero desconectados: la clase LocalConnection o la clase ExternalInterface. Esta demostración se centrará en la segunda, porque ExternalInterface funciona perfectamente con la API de JavaScript bien documentada y, por lo tanto, funciona bien con cualquier otra cosa dentro de la página XHTML.

Recursos importantes

Antes de comenzar, te ofrecemos una lista de recursos y archivos relacionados disponibles. Muchos de los temas que se analizan en este artículo se detallan en los vínculos siguientes.

Información detallada

Descripción general de Wrapper Demo

Archivos de clase de ActionScript
Figura 3: Archivo JavaScript
Archivos de clase de ActionScript
Figura 2: Archivos de clase de ActionScript

El ActionScript 3.0 Wrapper consiste esencialmente en dos partes interconectadas, los archivos de clase ActionScript 3.0 ubicados en src/choppingblock/video/ (Figura 2) y el archivo JavaScript "youTubeLoader.js" ubicado en deploy/_assets/js/ (Figura 3). Tu archivo de origen Flash/Flex creará una instancia de la clase ActionScript de YouTubeLoader. Tu página XHTML incorpora el archivo Flash y lo registra con las funciones dentro del archivo JavaScript YouTubeLoader. Es fundamental comprender que, desde aquí, todo lo que hace YouTubeLoader dentro del archivo Flash se controla mediante las funciones JavaScript.

Debido a que todas las funcionalidades dentro de Flash se controlan a través de JavaScript API, NO podrás cargar ningún contenido de YouTube dentro del reproductor Flash 'Test Movie'. Solo funciona cuando se incorpora a una página XHTML y se conecta correctamente a las funciones JavaScript de YouTube.

Nota: Para probar cualquiera de estas llamadas, debes ejecutar el archivo en un servidor web o modificar la configuración de seguridad de Flash Player, ya que Flash Player restringe las llamadas entre Internet y los archivos locales.

Creación de un objeto YouTubeLoader

Antes de que puedas crear una instancia del objeto YouTubeLoader en tu proyecto Flash/Flex, primero debes asegurarte de que el paquete (la carpeta) de los archivos requeridos se encuentre en el mismo directorio que tu proyecto (consulta la Figura 2), o definido con la ruta de clase de tus proyectos. Luego, puedes importar los archivos de paquete:

import choppingblock.video.*;

Esto permite que tu archivo ActionScript acceda a las clases "YouTubeLoader.as" y "YouTubeLoaderEvent.as". Ahora estás listo para crear una instancia de la clase YouTubeLoader y los receptores de eventos necesarios:

import choppingblock.video.*;

public class YouTubeDemo extends Sprite {

  private var _youTubeLoader:YouTubeLoader;	
  
  // ------------------------------------
  // CONSTRUCTOR
  // ------------------------------------
  
  public function YouTubeDemo () {
    
    // create YouTubeLoader object
    _youTubeLoader = new YouTubeLoader();
    
    // add event listener to call youTubePlayerLoadedHandler method on load
    _youTubeLoader.addEventListener(YouTubeLoaderEvent.LOADED, youTubePlayerLoadedHandler);
    
    // create the actual loader 
    _youTubeLoader.create();
    
    // add object to the display stack
    addChild(_youTubeLoader);
  };
  
  // ------------------------------------
  // EVENT METHODS
  // ------------------------------------
  
  /**
  Called via player loaded event, lets you know you are all clear to send player commands.
  */
  private function youTubePlayerLoadedHandler (event:YouTubeLoaderEvent):void{
    //trace("YouTubeDemo: youTubePlayerLoadedHandler");
    
    // you are now clear to start making calls to the YouTubeLoader object
  };
};

Ahora, si el archivo JavaScript está configurado y conectado correctamente, se debe llamar correctamente a youTubePlayerLoadedHandler, y estamos listos para comenzar a realizar solicitudes.

Cómo incorporar el swf y conectar el JavaScript de YouTube

No podrás cargar contenido de YouTube correctamente hasta que tu archivo swf esté incorporado en un archivo XHTML y conectado a JavaScript de YouTubeLoader. Recomendamos usar SWFObject para incorporar cualquier reproductor al que se accederá usando la API de JavaScript. Esto te permitirá detectar la versión de Flash Player del usuario final (la JavaScript API requiere Flash Player 8 o una versión posterior), y también eliminarás la casilla "Haz clic para activar este control" cuando uses Internet Explorer para ver el reproductor.

En la parte <head> de tu archivo XHTML, conecta los archivos swfobject y youTubeLoader:

<script type="text/javascript" src="_assets/js/swfobject.js"></script>
<script type="text/javascript" src="_assets/js/youTubeLoader.js"></script>

A continuación, se muestra un ejemplo de cómo usar SWFObject para incorporar su swf ActionScript 3.0 con la API de JavaScript habilitada y luego pasar una referencia a su swf a la API de JavaScript de YouTube.

<script type="text/javascript">

  var flashvars = {};
  var params = {
    menu: "false",
    allowScriptAccess: "always",
    scale: "noscale"
  };
  var attributes = {
    id: "youtubewrapper"
  };

  swfobject.embedSWF("YouTubeIntegrationDemo.swf", "flashcontent", "960", "500", "9.0.0", "_assets/swf/expressInstall.swf", flashvars, params, attributes);
  
  //init the youTubeLoader JavaScript methods
  SWFID = "youtubewrapper"
    
</script>

El parámetro allowScriptAccess del código es necesario para permitir que el SWF del reproductor invoque funciones en la página HTML contenedora, ya que el reproductor sin bordes está alojado en un dominio diferente al de la página XHTML.

El único atributo que se transmite es el ID del objeto insertado; en este caso, youtubewrapper. Este ID es lo que el archivo youTubeLoader.js usará para obtener una referencia al reproductor mediante getElementById().

swfobject.embedSWF cargará el reproductor de YouTube y lo insertará en tu página.

swfobject.embedSWF(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj)

  • swfUrlStr: Es la URL del SWF. Ten en cuenta que hemos agregado los parámetros enablejsapi y playerapiid a la URL normal SWF de YouTube para habilitar las llamadas a la API de JavaScript.
  • replaceElemIdStr: Es el ID de DIV HTML que se reemplazará por el contenido incorporado. En el ejemplo anterior, es ytapiplayer.
  • widthStr: Ancho del reproductor.
  • heightStr: es la altura del reproductor.
  • swfVersionStr: Es la versión mínima necesaria para que el usuario vea el contenido. En este caso, es necesaria la versión 8 o superior. Si el usuario no tiene la versión 8 como mínimo, verá la línea predeterminada de texto en el DIV HTML.
  • xiSwfUrlStr (opcional): Especifica la URL del SWF de instalación rápida. No se utiliza en este ejemplo.
  • flashVarsObj (opcional): Especifica tu FlashVars en los pares nombre:valor. No se utiliza en este ejemplo.
  • parObj (opcional): Los parámetros del objeto incorporado. En este caso, se estableció allowScriptAccess.
  • AttObj (opcional): Los atributos del objeto insertado. En este caso, el ID se estableció en myytplayer.

Consulta la documentación de SWFObject para obtener una explicación más detallada.

SWFID ≡ almacenará una referencia al ID del objeto de incorporación que la API de JavaScript usará. Debes usar el mismo ID del objeto de incorporación al que le asignaste el swf.

SWFID ≡ "youtubewrapper"

En este punto, deberías poder probar tu proyecto correctamente. El objeto YouTubeLoader debe cargar el reproductor sin bordes y se debe invocar correctamente el controlador de eventos YouTubeLoaderEvent.LOADED. Ya estamos listos para realizar una solicitud de video e interactuar con el objeto YouTubeLoader.

Cómo interactuar con el reproductor

Debido a que este enfoque para crear un wrapper de ActionScript 3.0 para el reproductor sin bordes aprovecha la clase ExternalInterface de ActionScript, ahora podemos utilizar cualquiera de las operaciones dentro de la API del reproductor JavaScript de YouTube para controlar el reproductor cargado. Si observas el archivo JavaScript "youTubeLoader.js" ubicado en deploy/_assets/js/ (Figura 3), notarás que contiene la mayoría de las funciones disponibles. Cada función de operación verifica en primer lugar la función checkObj para verificar que la variable SWFID se haya configurado correctamente antes de ejecutarse.

//------------------------------------
// UTILITY METHODS
//------------------------------------

function checkObj () {
  // alert("youTubeLoader.js : checkObj");
  if (SWFID) {
    createObj();
    return true;
  } else{
    alert("YouTubeLoader: In order to call methods within a swf, you must first set the variable \"SWFID\"!");
    return false;
  };
}
  
//------------------------------------
// YOUTUBE METHODS
//------------------------------------

function loadVideoById(id, startSeconds) {
  // alert("youTubeLoader.js : loadVideoById");
  if (checkObj()) {
    obj.loadVideoById(id,startSeconds);
  };
};

function cueNewVideo(id, startSeconds) {
  // alert("youTubeLoader.js : loadVideoById");
  if (checkObj()) {
    obj.cueVideoById(id, startSeconds);
  }
}

function clearVideo() {
  // alert("youTubeLoader.js : clearVideo");
  if (checkObj()) {
    obj.clearVideo();
  }
}

// plus 17 more...

Dado que el objetivo final de nuestro wrapper de ActionScript 3.0 para el reproductor sin bordes es ofrecer una interacción sin interrupciones con la API de YouTube desde un proyecto Flash/Flex de ActionScript 3.0, agregamos exactamente los mismos métodos públicos al archivo de clase "YouTubeLoader.as" ubicado en src/choppingblock/video/ (Figura 2). Esto significa que puedes invocar las mismas operaciones directamente en el objeto YouTubeLoader mediante Flash o Flex. Si buscas en el archivo de la clase, encontrarás lo siguiente:

// ------------------------------------
// YOUTUBE METHODS
// ------------------------------------

public function loadVideoById (id:String, startSeconds:Number = 0):void{
  //trace("YouTubeLoader: loadVideoById");
  ExternalInterface.call("loadVideoById", id, startSeconds);
};

public function cueNewVideo (id:String, startSeconds:Number = 0):void{
  //trace("YouTubeLoader: cueNewVideo");
  ExternalInterface.call("cueNewVideo", id, startSeconds);
};

public function clearVideo ():void{
  //trace("YouTubeLoader: clearVideo");
  ExternalInterface.call("clearVideo");
};

// plus 17 more...

Los métodos de ActionScript usan la clase ExternalInterface para simplemente llamar a la función apropiada dentro de la JavaScript API.

Solicitar un video

Ahora puedes solicitar un video desde tu archivo ActionScript 3.0 llamando a funciones con la referencia del reproductor. Por ejemplo, si deseas reproducir el video cuando un usuario hace clic en un botón, debes agregar el objeto de escucha de eventos MouseEvent.CLICK a tu botón. Para ello, puedes escribir lo siguiente:

// assuming your button was called 'myButton'
myButton.addEventListener(MouseEvent.CLICK, youtubeLoadVideoHandler);

Y crear un método de controlador de eventos para manejar la solicitud. Para ello, puedes escribir lo siguiente:

private function youtubeLoadVideoHandler (event:MouseEvent):void{
  
  // assuming that '_youTubeLoader' is a reference to your YouTubeLoader object
  _youTubeLoader.loadVideoById( "u1zgFlCw8Aw" );
};

Fuera de tu archivo Flash/Flex, tienes la opción de solicitar un video llamando directamente a la función JavaScript correspondiente. Para ello, puedes escribir lo siguiente:

 <a href="javascript:loadVideoById('u1zgFlCw8Aw')">Play</a> 

Emisión de llamadas adicionales

Las llamadas adicionales funcionan exactamente igual que la solicitud de un video. Desde ActionScript 3, simplemente puedes llamar a los métodos utilizando la referencia del reproductor. Puedes encontrar una lista completa de los métodos disponibles a continuación.

Suscripción a eventos

Puedes suscribirte a eventos agregando un objeto de escucha de eventos a la referencia del reproductor. Por ejemplo, para recibir una notificación cuando cambie el estado del reproductor, agrega un objeto de escucha de eventos de YouTubeLoaderEvent.STATE_CHANGE. Para ello, puedes escribir lo siguiente:

// assuming that '_youTubeLoader' is a reference to your YouTubeLoader object
_youTubeLoader.addEventListener(YouTubeLoaderEvent.STATE_CHANGE, youTubePlayerStateChangeHandler);

Y crear un método de controlador de eventos para manejar la solicitud. Para ello, puedes escribir lo siguiente:


private function youTubePlayerStateChangeHandler (event:YouTubeLoaderEvent):void{
  //trace("YouTubeIntegrationDemo: youTubePlayerStateChangeHandler");
  
  _stateField.text = event.state;
};

Operaciones disponibles

Para invocar los métodos de la API del reproductor de YouTube, primero debes crear una instancia de la clase de YouTubePlayer en tu archivo ActionScript y almacenar una referencia al objeto YouTubePlayer que deseas controlar. Para ello, llama a:

var _youTubeLoader:YouTubeLoader;
_youTubeLoader = new YouTubeLoader();

Métodos públicos

player.loadVideoById(id:String, startSeconds:Number = 0):void
Carga y reproduce el video en función del ID especificado.
player.cueNewVideo(id:String, startSeconds:Number = 0):void
Carga, pero no reproduce automáticamente el video en función del ID especificado.
player.clearVideo():void
Borra el video en fila o cargado actualmente.
player.setSize(w:Number, h:Number):void
Configura el tamaño de la instancia de YouTubePlayer.
player.play():void
Reproduce el video en fila o cargado actualmente.
player.pause():void
Pausa el video actualmente en fila o cargado
player.stop():void
Detiene el video actualmente en fila o cargado.
player.seekTo(seconds:Number):void
Busca un tiempo especificado en el video cargado o en fila.
player.getPlayerState():String
Muestra el estado actual del video actualmente en fila o cargado
player.getBytesLoaded():Number
Muestra el valor de los bytes cargados actuales del video cargado o señalado actualmente.
player.getBytesTotal():Number
Muestra el valor de la cantidad total de bytes cargados del video actualmente en fila o cargado.
player.getCurrentTime():Number
Muestra la posición actual en el tiempo del video actualmente en fila o cargado.
player.getDuration():Number
Muestra la duración actual del video actualmente en fila o cargado
player.getStartBytes():Number
Muestra los bytes de inicio del video cargado o en fila actualmente.
player.setVolume(newVolume:Number):void
Establece el volumen del video actualmente en fila o cargado
player.getVolume():Number
Muestra el volumen actual del video cargado o en fila actualmente.
player.mute():void
Almacena el volumen actual y cambia el volumen del video cargado o en fila a 0.
player.unmute():void
Muestra el volumen del video actualmente en fila o cargado al último valor almacenado cuando se silencia.
player.getEmbedCode():String
Muestra el código de YouTube actual del video cargado o en fila actual.
player.getVideoUrl():String
Muestra la URL del video de YouTube actual del video cargado o en fila actual.

Eventos

YouTubeLoaderEvent.LOADED
Se activa una vez que se completa la carga del reproductor sin bordes y está listo para aceptar llamadas de operaciones.
YouTubeLoaderEvent.STATE_CHANGE
Se activa cada vez que cambia el estado del reproductor. La clase YouTubeLoader traduce los números de la API de JavaScript a sus valores de string relacionados; la clase YouTubeLoaderEvent almacena el evento actual en una variable llamada state. Los valores posibles son no iniciado, finalizado, en reproducción, pausado, almacenamiento en búfer, video en fila. Cuando se cargue por primera vez el SWF, se transmitirá un evento no iniciado. Cuando el video está en fila y listo para reproducirse, transmitirá un evento que recibirá una señal de video.
YouTubeLoaderEvent.IO_ERROR
Se activa cuando se produce un error en el reproductor. Existen dos códigos de error posibles: 100 se emite cuando no se encuentra el video solicitado. Esto ocurre cuando se elimina un video (por cualquier motivo) o se marca como privado. Los 101 se emiten cuando el video solicitado no permite la reproducción en los reproductores insertados.

Notas sobre la demostración

A modo de demostración, quisimos incluir los campos del formulario de XHTML, los botones y la IU de visualización debajo del ActionScript 3 Wrapper incorporado. Para que el archivo swf Y la actualización de XHTML fuera simultáneamente, tuvimos que incluir dos líneas de código dentro del archivo JavaScript 'youTubeLoader.js' ubicado en 'deploy/_assets/js/' (Figura 3). Cuando integres este archivo en tu proyecto, deberás quitar las siguientes dos líneas [69, 79]:

//------------------------------------
// SPECIAL YOUTUBE EVENT METHODS
//------------------------------------

function onYouTubePlayerReady(playerId) {

  if (checkObj()) {	
    obj.addEventListener("onStateChange", "onytplayerStateChange");
  };

  // PLEASE NOTE: For the purpose of this demo:
  // This calls a secondary method located in the index.html file allowing the html display to update.
  // You will most likely not need this, it's gross, remove this when you implement this code.
  secondaryOnYouTubePlayerReady(playerId);
}

function onytplayerStateChange(newState) {
    //alert("Player's new state: " + newState);
  obj.playerStateUpdateHandler(newState);

  // PLEASE NOTE: For the purpose of this demo:
  // This calls a secondary method located in the index.html file allowing the html display to update.
  // You will most likely not need this, it's gross, remove this when you implement this code.
  secondaryOnytplayerStateChange(newState)
}

El archivo de demostración y las bibliotecas de ActionScript incluidas son software gratuito: puedes redistribuirlo o modificarlo de acuerdo con los términos de la Licencia Pública General Menor de GNU. Estos archivos están distribuidos con la esperanza de que sean útiles, pero sin ninguna garantía.

Conclusión

En este artículo, se proporcionan los archivos de demostración y archivos de origen que ofrecen una descripción general sólida de una solución relativamente simple y confiable para integrar la API de YouTube y los reproductores incorporados en entornos de ActionScript 3 con la biblioteca de wrapper que desarrollamos para nuestros propios proyectos. Como he comentado gran parte del código, lo ideal sería que sea bastante sencillo explorar y reutilizar las bibliotecas. No siempre se limita, y siempre se puede mejorar, refactorizar y mejorar. Si tienes ideas sobre este tema, comunícate con nosotros.

Biografía del autor


Matthew Richmond

Matthew Richmond tiene 14 años de experiencia interactiva en diseño, desarrollo y arquitectura. Cuando no se encuentra en el estudio, puede enseñar técnicas digitales de fotografía o fotografía, y ActionScript avanzado en la Escuela de Artes Visuales. Matthew es un socio fundador y diseñadora en choppingblock.com.