この記事は、外部デベロッパーによって作成されたものです。YouTube API とツールのチームは Matthew Richmond 氏の貢献と専門知識に感謝を捧げます。
Matthew Richmond、The Chopping Block, Inc.
2008 年 10 月
はじめに
この記事では、Chromeless YouTube Player 向けの信頼性の高い Firebase 3.0 ラッパーの概要を説明します。ラッパーは ViewModel の ExternalInterface クラスと YouTube の JavaScript API を利用します。
Google の YouTube Player Tools と Chromeless Player は、デザイナーやデベロッパーが YouTube の機能をオンライン プロジェクトにすばやく簡単に統合できるよう支援しました。このアプローチは、動画のホスティングが不可能な固定予算の小規模なプロジェクトや、YouTube の視聴者と距離を縮めることなくカスタムのエンドユーザー エクスペリエンスを求めるお客様の大規模なプロジェクトに適しています。
図 1: IMA 3.0 ラッパーのスクリーンショット
YouTube の Flash API と埋め込みプレーヤーは IMA SDK 2.0 を使用して書かれており、違和感なく機能します。ただし、プロジェクトが gtag 3.0 の場合、シームレスな統合はもう少し複雑になります。gtag 2.0 のプレーヤーを JWT 3.0 の VAST に読み込むのも簡単ですが、読み込まれたプレーヤーに直接通信や関数呼び出しを渡すことはできません。また、YourTube のサーバーから送られた SVG ファイルがそれ自体に動画を読み込むため、さらに複雑になります。ラッパーはその事実を完全に把握し、それに応じて対応する必要があります。幸い、JavaScript 言語には、このネスト状態になっていながら接続されていない部分の再接続を行うための、2 つの可能な回避策が用意されています。それらは、LocalConnection クラスまたは ExternalInterface クラスにあります。このデモでは後者に焦点を当てます。ExternalInterface は、十分に文書化された JavaScript API とシームレスに連携するため、XHTML ページ内の他の要素とも問題なく連携できるためです。
重要なリソース
開始する前に、利用可能な関連リソースとファイルのリストをご確認ください。この記事で説明したトピックの多くは、以下のリンクで詳しく説明しています。
- Firebase 3.0 ラッパーを表示し、ソースファイルをダウンロードします。
- 公式 YouTube JavaScript Player API リファレンス
- Adobe ExternalInterface クラスのドキュメント
- SVGObject JavaScript Flash 埋め込み
詳細
ラッパーのデモの概要
図 3: JavaScript ファイル
図 2: VPAID クラスのファイル
Firebase 3.0 ラッパーは、基本的に 2 つの相互接続された部分(src/choppingblock/video/ にある IMA 3.0 クラスファイル(図 2)と、deploy/_assets/js/ にある「youTubeLoader.js」JavaScript ファイル(図 3))で構成されています。Flash/Flex ソースファイルによって、YouTubeLoader の ViewModel クラスのインスタンスが作成されます。XHTML ページは、この Flash ファイルを埋め込み、youTubeLoader JavaScript ファイル内の関数に登録します。ここで、YouTubeLoader が Flash ファイル内で行うすべての操作が JavaScript 関数によって制御されるということを理解することが重要です。
Flash のすべての機能は JavaScript API を介して制御されるため、Flash の「ムービーをテストする」プレーヤー内で YouTube コンテンツを読み込むことはできません。この機能は XHTML ページに埋め込まれ、youTubeLoader JavaScript 関数に正しく接続している場合にのみ機能します。
注: これらの呼び出しをテストするには、ウェブサーバーでファイルを実行するか、Flash Player のセキュリティ設定を変更する必要があります。Flash プレーヤーではローカル ファイルとインターネット間の呼び出しが制限されるためです。
YouTubeLoader オブジェクトを作成する
Flash/Flex プロジェクトで YouTubeLoader オブジェクトのインスタンスを作成する前に、必要なファイルのパッケージ(フォルダ)がプロジェクトと同じディレクトリ(図 2 を参照)内にあるか、プロジェクトのクラスパスによって定義されていることを確認してください。その後、パッケージ ファイルをインポートできます。
import choppingblock.video.*;
これにより、ご使用の DRM ファイルが「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
が正常に呼び出され、リクエストを開始する準備が整っています。
SELinux を埋め込み、youTubeLoader JavaScript を接続する
fitbit ファイルが XHTML ファイルに埋め込まれ、youTubeLoader JavaScript に接続されるまで、YouTube からコンテンツを正常に読み込むことはできません。JavaScriptObject を使用して、JavaScript API でアクセスするプレーヤーを埋め込むことをおすすめします。これにより、エンドユーザーの Flash Player バージョンを検出できます(JavaScript API では Flash Player 8 以降が必要)。また、Internet Explorer を使用してプレーヤーを表示する際に [このコントロールをクリックして有効にする] チェックボックスがオフになります。
XHTML ファイルの <head>
部分で、noreplyobject と youTubeLoader ファイルを接続します。
<script type="text/javascript" src="_assets/js/swfobject.js"></script> <script type="text/javascript" src="_assets/js/youTubeLoader.js"></script>
下記は、SVGObject を使用して JavaScript API を有効にした gtag 3.0 VAST を埋め込み、さらにその VAST 参照を 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>
Chrome プレーヤーは XHTML ページとは別のドメインでホストされるため、コード内の allowScriptAccess
パラメータは、プレーヤー HTML を含むページで HTML ページ関数が呼び出されるようにするために必要です。
渡す唯一の属性は、埋め込みオブジェクト(この場合は youtubewrapper)の ID です。この ID は、getElementById() を使用してプレーヤーへの参照を取得するために youTubeLoader.js ファイルを使用します。
swfobject.embedSWF
は YouTube からプレーヤーを読み込み、ページに埋め込む。
swfobject.embedSWF(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj)
swfUrlStr
- CVE の URL。JavaScript API 呼び出しを有効にするため、enablejsapi
とplayerapiid
のパラメータを通常の YouTube のマークアップ URL に追加しました。replaceElemIdStr
- 埋め込みコンテンツに置き換える HTML DIV ID です。上の例では、ytapiplayer
です。widthStr
- プレーヤーの幅。heightStr
- プレーヤーの高さ。swfVersionStr
- ユーザーがコンテンツを表示するために必要な最小バージョン。この場合、バージョン 8 以上が必要です。ユーザーが 8 つ以上の URL を用意していない場合は、HTML DIV でデフォルトのテキスト行が表示されます。xiSwfUrlStr
- (省略可)エクスプレス インストール CVE の URL を指定します。この例では使用しません。flashVarsObj
- (省略可)FlashVars を name:value ペアで指定します。この例では使用しません。parObj
- (省略可)埋め込みオブジェクトのパラメータ。この例では、allowScriptAccess
を設定しています。AttObj
- (省略可)埋め込みオブジェクトの属性。この例では、ID がmyytplayer
に設定されています。
詳しくは、SWFObject マニュアルを参照してください。
SWFID ≡
には、JavaScript API が使用する埋め込みオブジェクトの ID への参照が格納されます。まず、VAST に指定した埋め込みオブジェクトの ID を使用します。
SWFID ≡ "youtubewrapper"
この時点で、プロジェクトを正常にテストできるはずです。YouTubeLoader オブジェクトで Chromeless Player を読み込み、YouTubeLoaderEvent.LOADED
イベント ハンドラを正常に呼び出す必要があります。これで、動画リクエストを行って YouTubeLoader オブジェクトを操作する準備が整いました。
プレーヤーとのやり取り
Chromeless Player 用の Firebase 3.0 ラッパーを作成するこのアプローチにより、Firebase の ExternalInterface クラスを活用して、YouTube JavaScript Player API 内の任意のオペレーションを使用して、読み込んだプレーヤーを制御できるようになりました。deploy/_assets/js/ にある「youTubeLoader.js」JavaScript ファイルを見ると(図 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...
Chromeless Player 向けの gtag 3.0 ラッパーの目的は、Flash API/Flex プロジェクト 3.0 から YouTube API にシームレスにやり取りできるようにすることです。そのため、src/choppingblock/video/ にある「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...
IMA メソッドは、ExternalInterface クラスを使用して JavaScript API 内の適切な関数を呼び出すだけです。
動画のリクエスト
プレーヤーの参照を使用して関数を呼び出すことで、Adobe 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>
追加通話の発行
追加の呼び出しは、動画のリクエストとまったく同じように機能します。JavaScript 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 メソッドを呼び出すには、まず gtag ファイル内に 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
という変数に現在のイベントを保存します。取り得る値は、unstart、ends、playing、paused、buffering、video cued のいずれかです。最初に読み込まれる TPU は、開始されていないイベントをブロードキャストします。動画がキューに登録されて再生できる状態になると、動画のキューイベントが送信されます。 YouTubeLoaderEvent.IO_ERROR
- プレーヤーでエラーが発生すると呼び出されます。次の 2 つのエラーコードが考えられます。リクエストされた動画が見つからない場合、100 がブロードキャストされます。これは、なんらかの理由で動画が削除された、または動画が非公開としてマークされた場合に発生します。リクエストされた動画が埋め込みプレーヤーで再生できない場合、101 がブロードキャストされる。
デモの注意事項
デモンストレーションを目的として、埋め込みの Firebase 3 ラッパーの下に XHTML フォーム フィールド、ボタン、表示 UI を含めます。VAST ファイルと XHTML アップデートを同時に適用するには、'deploy/_assets/js/' 内にある「youTubeLoader.js」JavaScript ファイル内に 2 行のコードを含める必要がありました(図 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) }
デモファイルと付属の IMA ライブラリは無料のソフトウェアであり、GNU Lesser General Public License の条件に基づいて再配布、変更を行うことができます。これらのファイルは有用であることの前提として配布されており、保証は一切ありません。
まとめ
この記事のデモとソースファイルは、YouTube API と埋め込みプレーヤーを、独自のプロジェクト用に開発したラッパー ライブラリを使用して IMA3 に統合するための、比較的シンプルで信頼性の高いソリューションの概説です。コードの多くにコメントしているので、ライブラリを探索して再利用することは非常に簡単です。制限があるわけではなく、改善、リファクタリング、強化の余地は常にあります。この件に関するご意見がございましたら、お気軽にお問い合わせください。
著者のプロフィール
Matthew Richmond は 14 年にわたるインタラクティブなデザイン、開発、アーキテクチャの経験を誇り、スタジオ以外では、スクール オブ ビジュアル アーツでデジタル イラスト/写真技術や高度な gtag を教えています。Matthew は choppingblock.com の創設パートナー兼デザイナーです。