本文由外部開發人員撰寫及提交。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 的創辦人與設計人員,