クロムレス プレーヤー用 UDF 3.0 ラッパー

この記事は外部のデベロッパーによって作成、送信されました。 YouTube API とツールのチームは、Matthew Richmond 氏に貴重な時間と専門知識をご提供いただき、感謝しています。


Matthew Richmond、The Chopping Block, Inc.
2008 年 10 月

はじめに

この記事では、クロムレス YouTube プレーヤー用の信頼性の高い CTA 3.0 ラッパーの概要を説明します。ラッパーは、JavaScript の ExternalInterface クラスと YouTube の JavaScript API を利用します。

Google の YouTube プレーヤー ツールと Chromeless Player により、デザイナーやデベロッパーは YouTube の機能をオンライン プロジェクトに迅速かつ簡単に統合できるようになりました。このアプローチは、動画をホストできない固定予算の小規模なプロジェクトや、YouTube の視聴者から離れずにカスタマイズされたエンドユーザー エクスペリエンスを望むクライアントの大規模なプロジェクトに最適です。

ActionScript 3.0 ラッパーのスクリーンショット
図 1: CTA 3.0 ラッパーのスクリーンショット

YouTube の Flash API と埋め込みプレーヤーは、JavaScript 2.0 で記述されており、適切に機能します。ただし、プロジェクトが UDF 3.0 の場合、シームレスな統合はやや複雑になります。ActionScript 2.0 プレーヤーを ActionScript 3.0 swf に簡単に読み込むことはできますが、読み込まれたプレーヤーに直接通信したり、関数呼び出しを渡したりすることはできません。さらに、YourTube のサーバーから送信された swf ファイルが動画を読み込むため、状況は複雑になります。ラッパーは、その事実を十分に認識し、それに応じて対応する必要があります。幸い、ActionScript 言語には、ネストされたが切断されたこれらの部分を再接続するための 2 つの回避策(LocalConnection クラスと ExternalInterface クラス)が用意されています。このデモでは後者について説明します。ExternalInterface は、よく文書化された JavaScript API とシームレスに動作するため、XHTML ページ内の他の要素とも連携できます。

重要なリソース

始める前に、こちらに利用可能な関連リソースとファイルのリストがあります。この記事で説明するトピックの多くは、以下のリンクで詳しく説明しています。

深く掘り下げる

ラッパーデモの概要

ActionScript クラス ファイル
図 3: JavaScript ファイル
ActionScript クラス ファイル
図 2: CTA クラスファイル

ActionScript 3.0 ラッパーは、基本的に 2 つの相互接続された部分で構成されています。src/choppingblock/video/ にある ActionScript 3.0 クラスファイル(図 2)と、deploy/_assets/js/ にある「youTubeLoader.js」JavaScript ファイル(図 3)です。Flash/Flex ソースファイルによって、YouTubeLoader CTA クラスのインスタンスを作成します。XHTML ページに Flash ファイルが埋め込まれ、youTubeLoader JavaScript ファイル内の関数に登録されます。以降、YouTubeLoader がフラッシュ ファイル内で行うすべての処理は、JavaScript 関数を介して制御されます。

Flash 内のすべての機能は JavaScript API を介して制御されるため、Flash の「テスト動画」プレーヤー内に YouTube コンテンツを読み込むことはできません。XHTML ページに埋め込まれ、youTubeLoader JavaScript 関数に適切に接続されている場合にのみ機能します。

: これらの呼び出しをテストするには、ファイルをウェブサーバーで実行するか、Flash Player のセキュリティ設定を変更する必要があります。Flash Player は、ローカル ファイルとインターネット間の呼び出しを制限しているためです。

YouTubeLoader オブジェクトを作成する

Flash/Flex プロジェクトで YouTubeLoader オブジェクトのインスタンスを作成するには、まず、必要なファイルのパッケージ(フォルダ)がプロジェクトと同じディレクトリにあるか(図 2 を参照)、プロジェクトのクラスパスで定義されていることを確認する必要があります。次に、パッケージ ファイルをインポートします。

import choppingblock.video.*;

これにより、お使いの CTA ファイルが「YouTubeLoader.as」および「YouTubeLoaderEvent.as」クラスです。YouTubeLoader クラスのインスタンスと必要なイベント リスナーを作成することができました。

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

JavaScript ファイルが配置され、適切に接続されている場合、youTubePlayerLoadedHandler が正常に呼び出され、リクエストを開始できるようになります。

swf の埋め込みと youTubeLoader JavaScript の接続

swf ファイルを XHTML ファイルに埋め込んで、youTubeLoader JavaScript に接続するまで、YouTube からコンテンツを正常に読み込むことはできません。JavaScript API を使用してアクセスするプレーヤーを埋め込む場合は、SWFObject の使用を推奨します。これにより、エンドユーザーの Flash Player のバージョンを検出できます(JavaScript API では Flash Player 8 以降が必要です)。また、Internet Explorer を使用してプレーヤーを表示する際に「このコントロールを有効にするにはクリックしてください」というボックスが表示されなくなります。

XHTML ファイルの <head> 部分で、swfobject と youTubeLoader ファイルを接続します。

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

SWFObject を使用して JavaScript API を有効にした ActionScript 3.0 swf を埋め込み、swf への参照を youTubeLoader JavaScript API に渡す例については、以下をご覧ください。

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

Chromeless Player は XHTML ページとは異なるドメインでホストされているため、プレーヤー SWF がその HTML ページの関数を呼び出すには、コードの allowScriptAccess パラメータが必要です。

渡している唯一の属性は、埋め込みオブジェクトの ID です(この場合は youtubewrapper)。この ID は、youTubeLoader.js ファイルが getElementById() を使用してプレーヤーへの参照を取得するために使用します。

swfobject.embedSWF は、YouTube からプレーヤーを読み込んでページに埋め込みます。

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

  • swfUrlStr - SWF の URL です。enablejsapi パラメータと playerapiid パラメータを通常の YouTube SWF URL に追加して、JavaScript API 呼び出しを有効にしています。
  • replaceElemIdStr - 埋め込みコンテンツで置き換えられる HTML DIV ID です。上記の例では、ytapiplayer です。
  • widthStr - プレーヤーの幅。
  • heightStr - プレーヤーの高さ。
  • swfVersionStr - ユーザーがコンテンツを表示するために必要な最小バージョン。この場合、バージョン 8 以上が必要です。8 歳未満のユーザーには、HTML DIV にデフォルトのテキスト行が表示されます。
  • xiSwfUrlStr - (省略可)エクスプレス インストール SWF の URL を指定します。この例では使用されていません。
  • flashVarsObj - (省略可)名前と値のペアで FlashVars を指定します。この例では使用されていません。
  • parObj -(省略可)埋め込みオブジェクトのパラメータ。この例では、allowScriptAccess を設定しています。
  • AttObj - (省略可)埋め込みオブジェクトの属性。この例では、ID を myytplayer に設定しています。

詳しくは、SWFObject マニュアルを参照してください。

SWFID ≡ には、JavaScript API が使用する埋め込みオブジェクトの ID への参照が格納されます。swf に指定したのと同じ埋め込みオブジェクトの ID を使用する必要があります。

SWFID ≡ "youtubewrapper"

この時点で、プロジェクトを正常にテストできるはずです。YouTubeLoader オブジェクトが Chromeless Player を読み込み、YouTubeLoaderEvent.LOADED イベント ハンドラが正常に呼び出されるはずです。これで、動画リクエストを行い、YouTubeLoader オブジェクトを操作する準備が整いました。

プレーヤーの操作

Chromeless Player 用の ActionScript 3.0 ラッパーを作成するこのアプローチでは ActionScript の ExternalInterface クラスを利用しているため、YouTube JavaScript Player API 内の任意のオペレーションを使用して、読み込まれたプレーヤーを制御できます。deploy/_assets/js/ にある JavaScript ファイル「youTubeLoader.js」(図 3)を見ると、利用可能な関数のほとんどが含まれていることがわかります。各オペレーション関数は、まず checkObj 関数をチェックし、実行前に SWFID 変数が正しく設定されていることを確認します。

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

クロムレス プレーヤー向けの UDF 3.0 ラッパーの最終目標は、JavaScript 3.0 Flash/Flex プロジェクト内から YouTube API とシームレスにやり取りできるようにすることなので、まったく同じパブリック メソッドを「YouTubeLoader.as」に追加しました。(図 2 を参照)つまり、Flash / Flex 内の YouTubeLoader オブジェクトに対して、まったく同じオペレーションを直接呼び出すことができます。クラスファイル内を見ると、次のようになっています。

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

アクション アクションは、ExternalInterface クラスを使用して JavaScript API 内で適切な関数を呼び出すだけです。

動画のリクエスト

これで、プレーヤー参照を使用して関数を呼び出すことで、JavaScript 3.0 ファイル内から動画をリクエストできるようになりました。たとえば、ユーザーがボタンをクリックしたときに動画を再生するには、MouseEvent.CLICK イベント リスナーをボタンに追加します。この場合、次のように指定します。

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

次に、リクエストを処理するイベント ハンドラ メソッドを作成します。この場合、次のように指定します。

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

Flash/Flex ファイルの外部で、対応する JavaScript 関数を直接呼び出して、オプションで動画をリクエストできます。この場合、次のように指定します。

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

追加のコールの発行

追加の呼び出しは、動画のリクエストとまったく同じように機能します。ActionScript 3 内から、プレーヤー参照を使用してメソッドを呼び出すだけです。使用可能なメソッドの一覧はこちらをご覧ください。

イベントへの登録

イベントへ登録するには、プレーヤー参照にイベント リスナーを追加します。たとえば、プレーヤーの状態が変化したときに通知を受け取るには、YouTubeLoaderEvent.STATE_CHANGE のイベント リスナーを追加します。この場合、次のように指定します。

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

リクエストを処理するイベント ハンドラ メソッドを作成します。この場合、次のように指定します。


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

使用可能なオペレーション

YouTubePlayer API メソッドを呼び出すには、まず UDF ファイル内に YouTubePlayer クラスのインスタンスを作成し、制御する YouTubePlayer オブジェクトへの参照を格納する必要があります。これを行うには、次の呼び出しを行います。

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

パブリック メソッド

player.loadVideoById(id:String, startSeconds:Number = 0):void
指定された ID に基づいて動画を読み込んで再生します。
player.cueNewVideo(id:String, startSeconds:Number = 0):void
指定された ID に基づいて動画が読み込まれますが、自動的に再生されません。
player.clearVideo():void
現在キューに登録されている動画 / 読み込まれている動画を消去します。
player.setSize(w:Number, h:Number):void
YouTubePlayer インスタンスのサイズを設定します。
player.play():void
現在キューに登録されている動画または読み込まれている動画を再生します。
player.pause():void
現在キューに登録されている動画 / 読み込まれている動画を一時停止します。
player.stop():void
現在キューに登録されている / 読み込まれている動画を停止します。
player.seekTo(seconds:Number):void
キューに入れられている/読み込まれている動画内の指定された時間までシークします。
player.getPlayerState():String
現在キューに登録されている / 読み込まれている動画の現在の状態を返します。
player.getBytesLoaded():Number
現在キューに登録されている / 読み込まれている動画の、現在読み込まれているバイト数を返します。
player.getBytesTotal():Number
現在キューに登録されている / 読み込まれている動画の読み込まれた合計バイト数を返します。
player.getCurrentTime():Number
現在キューに登録されている動画または読み込まれている動画の現在の時間位置を返します。
player.getDuration():Number
キューに入れられている/読み込まれている動画の現在の再生時間を返します。
player.getStartBytes():Number
現在キューに格納されている動画の開始バイトを返します。
player.setVolume(newVolume:Number):void
現在キューに登録されている / 読み込まれている動画の音量を設定します。
player.getVolume():Number
現在キューに登録されている / 読み込まれている動画の現在の音量を返します。
player.mute():void
現在の音量を保存し、キューに追加または読み込み中の動画の音量を 0 に変更します。
player.unmute():void
ミュートされたとき、キューに追加または読み込まれている動画の音量を、最後に保存された値に戻します。
player.getEmbedCode():String
現在キューに登録されている動画または読み込まれている動画の現在の YouTube 埋め込みコードを返します。
player.getVideoUrl():String
現在キューに登録されている / 読み込まれている動画の現在の YouTube 動画 URL を返します。

イベント

YouTubeLoaderEvent.LOADED
Chromeless Player の読み込みが正常に完了し、オペレーション呼び出しを受け入れられる状態になったときに発生します。
YouTubeLoaderEvent.STATE_CHANGE
プレーヤーの状態が変化したときに発行されます。YouTubeLoader クラスは JavaScript API 番号を関連する文字列値に変換します。YouTubeLoaderEvent クラスは、現在のイベントを state という変数に格納します。有効な値は、unstarted、Ended、Playback、pause、buffering、video cued です。SWF が最初に読み込まれると、開始前イベントがブロードキャストされます。動画がキューに入れられて再生の準備が整ったら、キュー済みイベントがブロードキャストされます。
YouTubeLoaderEvent.IO_ERROR
プレーヤーでエラーが発生したときに発生します。エラーコードは 2 つあります。100 は、リクエストされた動画が見つからない場合にブロードキャストされます。これは、なんらかの理由で動画が削除されたか、非公開としてマークされている場合に発生します。101 は、リクエストされた動画が埋め込みプレーヤーでの再生を許可していない場合にブロードキャストされます。

デモに関する注意事項

ここではデモを目的として、埋め込みの UDF 3 ラッパーの下に XHTML フォーム フィールド、ボタン、表示 UI を組み込みました。SWF ファイルと XHTML を同時に更新するには、「youTubeLoader.js」というファイルに 2 行のコードを含める必要がありました。「deploy/_assets/js/」にある JavaScript ファイル(図 3)。このファイルをプロジェクトに統合するときに、次の 2 行 [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)
}

デモファイルと付属の UDF ライブラリはフリー ソフトウェアです。GNU Lesser General Public License の条項に基づいて再配布や変更を行うことができます。これらのファイルは有用であることを期して配布されていますが、いかなる保証も行いません。

まとめ

この記事、デモソースファイルでは、YouTube API と埋め込みプレーヤーを ActionScript 3 環境に統合するための比較的シンプルで信頼性の高いソリューションの概要を説明します。このソリューションでは、YouTube のプロジェクト用に開発したラッパー ライブラリを使用します。コードの大部分にコメントを追加しているため、ライブラリを探索して再利用するのは比較的簡単です。ただし、制限事項があり、改善、リファクタリング、拡張の余地は常にあります。ご意見やご感想がございましたら、お気軽にお問い合わせください。

著者のプロフィール


マシュー・リッチモンド

Matthew Richmond は、インタラクティブ デザイン、開発、アーキテクチャの分野で 14 年以上の経験を持ち、スタジオに所属していないときは、ビジュアル アート スクールでデジタル イラスト/写真撮影のテクニックや高度な CTA について教えています。Matthew は choppingblock.com の創立パートナー兼デザイナーです。