本文由外部開發人員撰寫及提交。YouTube API 和工具團隊感謝 Matthew Richmond 貢獻寶貴的時間與專業知識。
Matthew Richmond,The Chopping Block, Inc.
2008 年 10 月
簡介
在本文中,我將簡單介紹適用於無邊框 YouTube 播放器的可靠 ActionScript 3.0 包裝函式。這個包裝函式會利用 ActionScript 的 ExternalInterface 類別以及 YouTube 的 JavaScript API。
Google 的 YouTube 播放器工具和無 Chrome 播放器可讓設計人員/開發人員輕鬆快速地將 YouTube 的強大功能與線上專案整合。這種方法非常適合用於預算固定且無法代管影片的小型專案。此外,如果大規模專案想要自訂使用者體驗,但又不離 YouTube 目標對象,也可以採用這種做法。

圖 1:ActionScript 3.0 包裝函式螢幕截圖
YouTube Flash API 和內嵌播放器是以 ActionScript 2.0 編寫而成,而且能完美搭配 ActionScript 2.0;如果您的專案是 ActionScript 3.0,則緊密整合就會變得更加複雜。雖然在 ActionScript 3.0 swf 中載入 ActionScript 2.0 播放器很簡單,但您無法直接進行通訊或傳遞任何功能呼叫到載入的播放器。這項問題更為複雜,因為來自 YouTube 伺服器的 swf 檔案會將影片載入自身。我們的包裝函式需要充分瞭解,並據此做出反應。幸運的是,ActionScript 語言包含兩個可行的解決方法,來重新連結這些巢狀但中斷連線的部分:LocalConnection 類別或 ExternalInterface 類別。此示範將著重於後者,因為 ExternalInterface 可與詳細記錄的 JavaScript API 完美搭配運作,因此能完美搭配 XHTML 網頁中的其他內容。
重要資源
開始之前,請先參閱下列相關資源和檔案。本文討論的許多主題,在下方連結中都有更詳細的說明。
- 查看 ActionScript 3.0 包裝函式,並下載來源檔案
- 官方 YouTube JavaScript Player API 參考資料
- Adobe ExternalInterface 類別說明文件
- SWFObject JavaScript Flash 嵌入
深入探究
包裝函式示範總覽

圖 3:JavaScript 檔案

圖 2:ActionScript 類別檔案
ActionScript 3.0 包裝函式基本上包含兩個相互連結的部分,包括位於 src/chopingblock/video/ 的 ActionScript 3.0 類別檔案 (圖 2),以及「youTubeLoader.js」JavaScript 檔案位於 deploy/_assets/js/ (圖 3)。Flash/Flex 來源檔案會建立 YouTubeLoader ActionScript 類別的例項;XHTML 頁面會嵌入 Flash 檔案,並將其註冊至 youTubeLoader JavaScript 檔案中的函式。請務必瞭解,從這裡開始,YouTubeLoader 在 Flash 檔案中執行的所有操作,都是透過 JavaScript 函式控制。
由於 Flash 的所有功能是透過 JavaScript API 控制,因此您無法在 Flash 的「測試影片」中載入任何 YouTube 內容廣告。只有在嵌入 XHTML 網頁,並正確連線至 YouTubeLoader JavaScript 函式時,才有作用。
注意:如要測試這些呼叫,您必須在網路伺服器上執行檔案,或修改 Flash Player 的安全性設定,因為 Flash Player 會限製本機檔案和網際網路之間的呼叫。
建立 YouTubeLoader 物件
在 Flash/Flex 專案中建立 YouTubeLoader 物件的例項之前,請先確認必要檔案的套件 (資料夾) 與專案位於相同目錄 (請參閱圖 2),或已透過專案的 Classpath 定義。接著,您可以匯入套件檔案:
import choppingblock.video.*;
這樣您的 ActionScript 檔案才能存取 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 內容。建議您使用 SWFObject 嵌入任何會使用 JavaScript API 存取的播放器。這可讓您偵測使用者的 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 頁面以外的網域上,因此程式碼中的 allowScriptAccess
參數必須允許播放器 SWF 在包含 HTML 頁面的網頁上呼叫函式。
我們傳入的唯一屬性是嵌入物物件的 ID,在本例中為 youtubewrapper。這個 ID 是 youTubeLoader.js 檔案會使用 getElementById() 取得玩家參照時所用的 ID。
swfobject.embedSWF
會從 YouTube 載入播放器,並將其嵌入網頁。
swfobject.embedSWF(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj)
swfUrlStr
:這是 SWF 的網址。請注意,我們已將enablejsapi
和playerapiid
參數附加至一般 YouTube SWF 網址,以便啟用 JavaScript API 呼叫。replaceElemIdStr
:這是 HTML DIV ID,用於取代嵌入內容。在上述範例中為ytapiplayer
。widthStr
- 播放器的寬度。heightStr
- 玩家的高度。swfVersionStr
- 使用者查看內容所需的最低版本。在此情況下,你需要安裝 8 以上版本。如果使用者沒有 8 或以上,他們會在 HTML DIV 中看到預設的文字行。xiSwfUrlStr
- (選用) 指定快速安裝 SWF 的網址。這個範例中並未使用。flashVarsObj
- (選用) 以 name:值組合指定 Flash 變數。這個範例中並未使用。parObj
- (選用) 嵌入物件參數。在本例中,我們設定了allowScriptAccess
。AttObj
- (選用) 嵌入物件屬性。在這個範例中,我們已將 ID 設為myytplayer
。
如需進一步說明,請參閱 SWFObject 說明文件。
SWFID ≡
會儲存嵌入物件 ID 的參照,以供 JavaScript API 使用。您必須針對 swf 提供的嵌入物件使用相同的 ID。
SWFID ≡ "youtubewrapper"
現在,您應該能夠成功測試專案。YouTubeLoader 物件應載入 Chromeless Player,且 YouTubeLoaderEvent.LOADED
事件處理常式應成功呼叫。現在我們準備提出影片要求,並與 YouTubeLoader 物件互動。
與播放器互動
由於這個建立無 Chrome 播放器專用的 ActionScript 3.0 包裝函式的方法,就是利用 ActionScript 的 ExternalInterface 類別,因此現在可以使用 YouTube JavaScript Player API 中的任何作業來控制載入的播放器。如果您查看「youTubeLoader.js」您的 JavaScript 檔案位於 deploy/_assets/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...
有鑑於「無邊框播放器」 ActionScript 3.0 包裝函式的目標,是為了透過 ActionScript 3.0 Flash/Flex 專案提供與 YouTube API 流暢的互動,我們在「YouTubeLoader.as」中新增了完全相同的公開方法。位於 src/choppingblock/video/ 中的類別檔案 (圖 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...
ActionScript 方法會使用 ExternalInterface 類別,只在 JavaScript API 中呼叫適當的函式。
要求影片
您現在可以使用播放器參照來呼叫函式,在 ActionScript 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>
發出其他來電
額外呼叫的運作方式與「要求視訊」完全相同;,您可以直接使用播放器參照來呼叫方法。如需可用方法的完整清單,請參閱下方內容。
訂閱事件
將事件監聽器新增至播放器參照,即可訂閱事件。舉例來說,如要在玩家狀態變更時收到通知,請為 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 方法,您必須先在 ActionScript 檔案中建立 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 影片網址。
活動
YouTubeLoaderEvent.LOADED
- 在「無邊框播放器」成功載入並準備好接受作業呼叫時觸發。
YouTubeLoaderEvent.STATE_CHANGE
- 每當玩家狀態變更時就會觸發。YouTubeLoader 類別會將 JavaScript API 號碼轉譯成相關的字串值,YouTubeLoaderEvent 類別會將目前事件儲存在名為
state
的變數中。可能的值包括未開始、已結束、正在播放、已暫停、正在緩衝、影片已cue。當 SWF 首次載入時,會廣播未啟動的事件。影片獲收錄並準備好播放時,就會播送影片自動提醒事件。 YouTubeLoaderEvent.IO_ERROR
- 在播放器發生錯誤時觸發。可能會出現兩個錯誤代碼:如果找不到要求的影片,系統會廣播 100。如果影片是因故遭移除,或是已標示為私人影片,就會出現這種情況。如果所要求的影片不允許在嵌入式播放器中播放,則會播放 101。
示範中的注意事項
為了示範,我們想在內嵌的 ActionScript 3 包裝函式下方加入 XHTML 表單欄位、按鈕和顯示 UI。為了讓 SWF 檔案和 XHTML 同時更新,我們必須在位於「deploy/_assets/js/」的「youTubeLoader.js」JavaScript 檔案中加入兩行程式碼 (圖 3)。將這個檔案整合至專案時,建議您移除以下兩行 [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) }
示範檔案和內含的 ActionScript 程式庫都是免費軟體:您可以根據《GNU 較小的一般公共授權》條款,重新發布和/或修改該檔案。我們發布這些檔案是希望能對您有所幫助,但不提供任何保證。
結論
本文、示範和來源檔案應可提供相對簡單且可靠的解決方案概要,讓您瞭解如何使用我們為自有專案開發的包裝函式庫,將 YouTube API 和嵌入式播放器整合至 ActionScript 3 環境。由於我曾評論過許多程式碼,在理想情況下,探索程式庫和重新利用這些程式碼會相當簡單。它並沒有限制,而且總有進步、重構和強化。如有任何想法,歡迎與我聯絡。
作者簡介

Matthew Richmond 有 14 年的互動式設計、開發和建築經驗。在工作室以外的時間,他會在視覺藝術學校教授數位插圖/攝影技巧和進階 ActionScript。Matthew 是 choppingblock.com 的創辦人與設計人員,