Wrapper do ActionScript 3.0 para o player sem cromo

Este artigo foi escrito e enviado por um desenvolvedor externo. A equipe de APIs e ferramentas do YouTube agradece Matthew Richmond por seu tempo e conhecimento.


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

Introdução

Neste artigo, vamos apresentar e descrever brevemente um Wrapper do ActionScript 3.0 confiável para o player sem cromo do YouTube. O wrapper utiliza a classe ExternalInterface do ActionScript e a API JavaScript do YouTube.

As ferramentas do YouTube para o YouTube e o Chromeless Player permitiram que os designers/desenvolvedores integrassem com rapidez e facilidade o poder do YouTube aos projetos on-line. Essa abordagem é ideal para projetos pequenos em orçamentos fixos que não permitem hospedar vídeos, além de projetos em grande escala para clientes que querem uma experiência do usuário final personalizada sem se distanciar do público do YouTube.

Captura de tela do wrapper do ActionScript 3.0
Figura 1: captura de tela do wrapper do ActionScript 3.0

A API para Flash e os players incorporados do YouTube são escritos e funcionam bem com o ActionScript 2.0. No entanto, se seu projeto for o ActionScript 3.0, a integração contínua será um pouco mais complexa. Embora seja fácil carregar os jogadores do ActionScript 2.0 em um swf do ActionScript 3.0, não é possível comunicar nem transmitir diretamente chamadas funcionais para o player carregado. Isso é mais complicado porque o arquivo swf proveniente dos servidores do YourTube está carregando um vídeo nele mesmo. Nosso wrapper precisa estar totalmente ciente desse fato e reagir de acordo com ele. Felizmente, a linguagem ActionScript contém duas soluções alternativas plausíveis para reconectar essas partes aninhadas e ainda não conectadas: a classe LocalConnection ou a classe ExternalInterface. Esta demonstração se concentra na última porque a ExternalInterface funciona perfeitamente com a API JavaScript bem documentada e, portanto, funciona bem com qualquer outra coisa na página XHTML.

Recursos importantes

Antes de começarmos, veja uma lista de recursos e arquivos relacionados disponíveis para você. Muitos dos tópicos discutidos neste artigo são detalhados nos links abaixo.

Buscando

Visão geral da demonstração do wrapper

Arquivos de classe do ActionScript
Figura 3: arquivo JavaScript
Arquivos de classe do ActionScript
Figura 2: arquivos de classe do script

O wrapper do ActionScript 3.0 consiste basicamente em duas partes interconectadas, os arquivos de classe do ActionScript 3.0 localizados em src/choppingblock/video/ (Figura 2) e o arquivo JavaScript 'youTubeLoader.js' localizado em deploy/_assets/js/ (Figura 3). Seu arquivo de origem Flash/Flex criará uma instância da classe ActionScript do YouTubeLoader. Sua página XHTML incorpora o arquivo Flash e o registra com as funções no arquivo JavaScript YouTubeLoader. É essencial entender que tudo o que o YouTubeLoader faz no arquivo Flash é controlado pelas funções JavaScript.

Como toda a funcionalidade no Flash é controlada por meio da API do JavaScript, NÃO será possível carregar nenhum conteúdo do YouTube no player de "Teste de filme". Ele só funcionará quando incorporado a uma página XHTML e conectado corretamente às funções JavaScript do YouTube.

Observação: para testar alguma dessas chamadas, é necessário executar o arquivo em um servidor da Web ou modificar as configurações de segurança do Flash Player porque o Flash Player restringe as chamadas entre arquivos locais e a Internet.

Como criar um objeto YouTubeLoader

Antes de criar uma instância do objeto YouTubeLoader no seu projeto Flash/Flex, verifique se o pacote (pasta) dos arquivos necessários está no mesmo diretório do seu projeto (veja a Figura 2) ou definido com o Classpath do seu projeto. Em seguida, importe os arquivos do pacote:

import choppingblock.video.*;

Isso permite que seu arquivo do Kotlin acesse as classes "YouTubeLoader.as" e "YouTubeLoaderEvent.as". Agora está claro que você precisa criar uma instância da classe YouTubeLoader e os listeners de eventos necessários:

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

Agora, se o arquivo JavaScript estiver conectado e conectado corretamente, o youTubePlayerLoadedHandler precisará ser chamado, e vamos começar a fazer solicitações.

Como incorporar o swf e conectar o JavaScript YouTubeLoader

Você só poderá carregar conteúdo do YouTube com êxito depois que o arquivo swf for incorporado a um arquivo XHTML e conectado ao JavaScript do YouTube. Recomendamos o uso do FCMObject para incorporar os players que serão acessados usando a API JavaScript. Isso permite que você detecte a versão do Flash Player do usuário final (a API JavaScript exige o Flash Player 8 ou superior) e também elimina a caixa "Clique para ativar este controle" ao usar o Internet Explorer para visualizar o player.

Na parte <head> do seu arquivo XHTML, você conecta os arquivos swfobject e youTubeLoader:

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

Veja abaixo um exemplo de como usar o FCMObject para incorporar o swf do ActionScript 3.0 com a API JavaScript ativada e, em seguida, passar uma referência para o swf à API JavaScript do 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>

O parâmetro allowScriptAccess no código é necessário para permitir que o SWF do player chame funções na página HTML que o contém, já que o player sem cromo está hospedado em um domínio diferente da página XHTML.

O único atributo que estamos transmitindo é o ID do objeto incorporado (neste caso, o youtubewrapper). Esse ID é o que o arquivo youTubeLoader.js usará para obter uma referência ao player usando getElementById().

swfobject.embedSWF vai carregar o player do YouTube e incorporá-lo à sua página.

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

  • swfUrlStr: é o URL do SWF. Os parâmetros enablejsapi e playerapiid foram anexados ao URL normal do SWF do YouTube para permitir chamadas da API JavaScript.
  • replaceElemIdStr: é o ID do HTML DIV que será substituído pelo conteúdo incorporado. No exemplo acima, é ytapiplayer.
  • widthStr: largura do player.
  • heightStr: altura do player.
  • swfVersionStr: a versão mínima necessária para o usuário ver o conteúdo. Neste caso, a versão 8 ou superior é necessária. Se o usuário não tiver a versão 8 ou superior, verá a linha de texto padrão no elemento HTML DIV.
  • xiSwfUrlStr (opcional): especifica o URL do SWF de instalação expressa. Não é utilizado neste exemplo.
  • flashVarsObj (opcional): especifica seu FlashVars nos pares name:value Não é utilizado neste exemplo.
  • parObj (opcional): os parâmetros do objeto incorporado. Neste caso, definimos allowScriptAccess.
  • AttObj (opcional): os atributos do objeto incorporado. Nesse caso, definimos o ID como myytplayer.

Consulte a documentação do SWFObject para mais detalhes.

SWFID ≡ vai armazenar uma referência ao ID do objeto incorporado para que a API JavaScript use. Você deve usar o mesmo ID do objeto incorporado que forneceu ao swf.

SWFID ≡ "youtubewrapper"

Neste ponto, você deve conseguir testar o projeto. O objeto YouTubeLoader precisa carregar o player sem cromo, e o manipulador de eventos YouTubeLoaderEvent.LOADED precisa ser chamado. Agora estamos prontos para fazer uma solicitação de vídeo e interagir com o objeto YouTubeLoader.

Interação com o jogador

Como essa abordagem para a criação de um wrapper 3.0 do player para o player sem cromo usa a classe ExternalInterface do ActionScript, podemos usar qualquer uma das operações na API do player JavaScript do YouTube para controlar nosso player carregado. Se você observar no arquivo JavaScript "youTubeLoader.js" localizado em deploy/_assets/js/ (Figura 3), verá que ele contém a maioria das funções disponíveis. Cada função de operação verifica primeiro a função checkObj para conferir se a variável SWFID foi definida corretamente antes da execução.

//------------------------------------
// 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...

Considerando que o objetivo final do wrapper 3.0 do player para o player sem cromo é oferecer interação perfeita com a API do YouTube de dentro de um projeto Flash/Flex do ActionScript 3.0, adicionamos os mesmos métodos públicos ao arquivo de classe "YouTubeLoader.as" localizado em src/choppingblock/video/ (Figura 2). Isso significa que você pode chamar exatamente as mesmas operações diretamente no objeto YouTubeLoader em Flash/Flex. No arquivo da turma, você encontra o seguinte:

// ------------------------------------
// 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...

Os métodos do ActionScript usam a classe ExternalInterface para simplesmente chamar a função apropriada na API JavaScript.

Solicitar um vídeo

Agora você pode solicitar um vídeo de dentro do arquivo ActionScript 3.0 chamando funções usando a referência do player. Por exemplo, se você quisesse reproduzir o vídeo quando um usuário clicasse em um botão, você adicionaria um listener de eventos Args.CLICK ao seu botão. Assim:

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

E criar um método de manipulador de eventos para lidar com a solicitação. Assim:

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

Fora do arquivo Flash/Flex, é possível solicitar um vídeo chamando a função JavaScript correspondente diretamente. Assim:

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

Como emitir chamadas adicionais

Chamadas adicionais funcionam exatamente como Solicitar um vídeo. No ActionScript 3, você pode simplesmente chamar métodos usando a referência do player. Veja uma lista completa dos métodos disponíveis neste link.

Inscrever-se em eventos

Inscreva-se nos eventos adicionando uma escuta de evento à referência do player. Por exemplo, para receber uma notificação quando o estado do player mudar, adicione um listener de eventos para YouTubeLoaderEvent.STATE_CHANGE. Assim:

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

E criar um método de manipulador de eventos para lidar com a solicitação. Assim:


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

Operações disponíveis

Para chamar os métodos da API do YouTubePlayer, primeiro você precisa criar uma instância da classe YouTubePlayer no arquivo ActionScript e armazenar uma referência ao objeto YouTubePlayer que quer controlar. Para isso, chame:

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

Métodos públicos

player.loadVideoById(id:String, startSeconds:Number = 0):void
Carrega e reproduz o vídeo com base no ID especificado.
player.cueNewVideo(id:String, startSeconds:Number = 0):void
Carrega, mas não reproduz automaticamente o vídeo com base no ID especificado.
player.clearVideo():void
Limpa o vídeo indicado/carregado.
player.setSize(w:Number, h:Number):void
Define o tamanho da instância do YouTubePlayer.
player.play():void
Reproduz o vídeo atualmente indicado/carregado.
player.pause():void
Pausa o vídeo indicado/carregado no momento.
player.stop():void
Para o vídeo indicado/carregado no momento.
player.seekTo(seconds:Number):void
Procura o tempo especificado no vídeo indicado/carregado.
player.getPlayerState():String
Retorna o estado atual do vídeo indicado/carregado.
player.getBytesLoaded():Number
Retorna o valor dos bytes atuais carregados do vídeo indicado/carregado no momento.
player.getBytesTotal():Number
Retorna o valor do total de bytes carregados do vídeo atualmente indicado/carregado.
player.getCurrentTime():Number
Retorna a posição atual no tempo do vídeo indicado ou carregado no momento.
player.getDuration():Number
Retorna a duração atual do vídeo indicado/carregado.
player.getStartBytes():Number
Retorna os bytes iniciais do vídeo indicado/carregado.
player.setVolume(newVolume:Number):void
Define o volume do vídeo indicado/carregado.
player.getVolume():Number
Retorna o volume atual do vídeo indicado/carregado.
player.mute():void
Armazena o volume atual e muda o volume do vídeo indicado/carregado no momento para 0.
player.unmute():void
Retorna o volume do vídeo indicado/carregado no momento para o último valor armazenado quando desativado.
player.getEmbedCode():String
Retorna o código de incorporação atual do YouTube do vídeo atualmente indicado/carregado.
player.getVideoUrl():String
Retorna o URL do vídeo atual do YouTube do vídeo indicado/carregado.

Eventos

YouTubeLoaderEvent.LOADED
Acionado quando o player sem cromo terminar de carregar e estiver pronto para aceitar chamadas de operações.
YouTubeLoaderEvent.STATE_CHANGE
Acionado sempre que o estado do jogador muda. A classe YouTubeLoader converte os números da API JavaScript nos valores de string relacionados, e a classe YouTubeLoaderEvent armazena o evento atual em uma variável chamada state. Os valores possíveis são: não iniciado, encerrado, reproduzido, pausado, buffer, vídeo indicado. Quando o SWF é carregado pela primeira vez, ele transmite um evento não iniciado. Quando o vídeo estiver indicado e pronto para ser reproduzido, ele transmitirá um evento de vídeo indicado.
YouTubeLoaderEvent.IO_ERROR
Acionado quando ocorre um erro no player. Há dois códigos de erro possíveis: 100 é transmitido quando o vídeo solicitado não é encontrado. Isso ocorrerá quando um vídeo tiver sido removido (por qualquer motivo) ou se tiver sido marcado como privado. O 101 é transmitido quando o vídeo solicitado não permite a reprodução nos players incorporados.

Observações sobre a demonstração

Para fins de demonstração, queremos incluir os campos, botões e IU de exibição do XHTML abaixo do wrapper incorporado do ActionScript 3. Para ter o arquivo swf E a atualização em XHTML ao mesmo tempo, tivemos que incluir duas linhas de código no arquivo JavaScript 'youTubeLoader.js' localizado em 'deploy/_assets/js/' (Figura 3). Convém remover as duas linhas a seguir [69, 79] ao integrar esse arquivo ao seu projeto:

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

O arquivo de demonstração e as bibliotecas do ActionScript incluídas são softwares sem custo financeiro: é possível redistribuir e/ou modificá-lo de acordo com os termos da Licença Pública Geral GNU Lesser. Esses arquivos são distribuídos na esperança de que sejam úteis, mas sem garantia alguma.

Conclusão

Este artigo (demonstração e arquivos de origem deve fornecer uma visão geral sólida sobre uma solução relativamente simples e confiável para integrar a API do YouTube e players incorporados em ambientes do ActionScript 3 usando a biblioteca de wrapper que desenvolvemos para nossos próprios projetos. Como eu comentei muito do código, o ideal é que seja bem simples explorar e reaproveitar as bibliotecas. Isso não é ilimitado e sempre há espaço para melhorias, refatorações e melhorias. Se você tiver alguma ideia sobre isso, entre em contato comigo.

Biografia do autor


Matthew richmond

Matthew Richmond oferece 14 anos de experiência em design interativo, desenvolvimento e arquitetura. Quando não está no estúdio, ele pode ser ensinado a ensinar técnicas de fotografia/ilustração digital e usar o TensorFlow avançado na Escola de Artes Visuais. Matthew é um dos fundadores e designers em choppingblock.com.