本文是由外部開發人員撰寫及提交。 YouTube API 與工具團隊也感謝 Matthew Richmond 提供的時間和專業。
Matthew Richmond,The Chopping Block, Inc.
2008 年 10 月
簡介
本文將介紹無 Chrome YouTube 播放器適用的可靠 ActionScript 3.0 包裝函式,並簡要說明這項功能。包裝函式會使用 ActionScript 的 ExternalInterface 類別以及 YouTube 的 JavaScript API。
Google 的 YouTube Player 工具和 Chromeless Player 讓設計人員/開發人員能夠輕鬆快速地將 YouTube 的強大功能整合至他們的線上專案中。這種方法非常適合不符合固定預算的小額專案,也適合想要自訂使用者體驗,且沒有將自己與 YouTube You 觀眾保持距離。
圖 1: ActionScript 3.0 包裝函式螢幕截圖
YouTube 的 Flash API 和嵌入式播放器皆經過編寫,而且可與 ActionScript 2.0 搭配使用;如果您的專案使用 ActionScript 3.0,流暢的整合方式會更加複雜。雖然您可以輕鬆將 ActionScript 2.0 播放器載入 ActionScript 3.0 SWF 檔案,但無法直接將任何通訊呼叫或傳遞至已載入的播放器。但這個情況更為複雜,因為從 YourTube 伺服器的 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 Wrapper 主要由兩個互連的部件、位居 src/choppingblock/video/ 中的 ActionScript 3.0 類別文件(圖 2)以及位為 Deployment/_assets/js/ 中的“youTubeLoader.js' JavaScript 文件( 3)。Flash/Flex 來源檔案會建立 YouTubeLoader ActionScript 類別的例項;您的 XHTML 網頁會嵌入 Flash 檔案,並在 YouTubeLoader JavaScript 檔案中,使用該函式註冊該檔案。請注意,在此之前,YouTube 載入器在 Flash 檔案中執行的一切動作,都是透過 JavaScript 函式來控制。
Flash 中的所有功能都是透過 JavaScript API 控制,因此「無法」在 Flash 的「測試電影」播放器中載入任何 YouTube 內容。這個外掛程式只有在嵌入 XHTML 網頁,並且正確連結至 YouTubeLoader JavaScript 函式時才能正常運作。
注意:如要測試上述任何呼叫,您必須在檔案網路伺服器上執行檔案,或是修改 Flash Player 安全性設定,因為 Flash 播放器會限製本機檔案和網際網路之間的呼叫。
建立 YouTubeLoader 物件
在 Flash/Flex 專案中建立 YouTubeLoader Object 的實例之前,您必須先確認所需檔案的套件 (資料夾) 與專案位於同一個目錄中 (請參閱圖 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>
allowScriptAccess
我們唯一傳遞的屬性是嵌入物件的 ID,在此案例中即為 youtubewrapper。您的 IDTbebeLoader.js 檔案將會使用這個 ID 取得 getElementById() 播放器的參照。
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:value 組合中指定 Flash 變數。本範例中未使用。parObj- (選用) 內嵌物件的參數。在這個範例中,我們設定了allowScriptAccess。AttObj- (選用) 內嵌物件的屬性。在這個範例中,我們將 ID 設為myytplayer。
如需詳細說明,請參閱 SWFObject 說明文件。
SWFID ≡ 會儲存內嵌物件的參照,以供使用的 JavaScript API 使用。您必須使用提供 SWF 的內嵌物件 ID。
SWFID ≡ "youtubewrapper"
此時,您應該可以成功測試專案了。YouTubeLoader 物件應載入無 Chrome 播放器,且應成功呼叫 YouTubeLoaderEvent.LOADED 事件處理常式。我們現在可以提出影片請求,並與 YouTubeLoader 物件互動。
與玩家互動
由於這個做法可為無 Chrome 播放器建立 ActionScript 3.0 包裝函式,利用 ActionScript 的 ExternalInterface 類別,因此現在可以利用 YouTube JavaScript Player API 中的任何作業來控制載入的播放器。如果您查看部署作業/_assets/js/ 中的「youTubeLoader.js」JavaScript 檔案 (圖 3),會發現其中含有大部分的可用函式。每個運算函式會先檢查 checkObj 函式,並在執行 SWFID 變數前確認已正確設定 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...
由於 Chrome 播放器的 ActionScript 3.0 包裝函式,最終目標是在 ActionScript 3.0 Flash/Flex 專案中提供與 YouTube API 的順暢互動,因此我們在 src/choppingblock/video/ 中的「YouTubeLoader.as」類別檔案中加入了相同的公開方法 (圖 2)。這表示您可以在 Flash/Flex 中直接呼叫完全相同的 YouTube 載入器物件。如果您查看課程檔案,將會找到:
// ------------------------------------
// 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>
發出其他呼叫
其他呼叫的運作方式與「要求影片」類似;在 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 方法,您必須先在 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- 在 Chromeless Player 完成載入並準備接受作業呼叫後,即會啟用這項功能。
YouTubeLoaderEvent.STATE_CHANGE- 在玩家的狀態變更時觸發。YouTubeLoader 類別會將 JavaScript API 號碼轉譯成相關的字串值,YouTubeLoaderEvent 類別會將目前的事件儲存在名為
state的變數中。可能的值包括尚未開始、結束、播放、暫停、緩衝處理、影片提示。系統第一次載入 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 Lower Public Public of License 的條款重新發布和/或修改檔案。希望透過發布檔案的方式提供實用檔案,但不提供任何保證。
結語
本文、試用版和來源檔案將提供一個簡單且可靠的總覽,說明使用我們為專案開發的包裝函式程式庫,將 YouTube API 和嵌入式播放器整合到 ActionScript 3 環境中。我對大部分程式碼進行註解,因此最好能夠探索並重複使用程式庫。這項技術無所不包,並且始終有改進、重構及增強的進步。如果您對此有任何想法,歡迎與我聯絡。
作者簡介
Matthew Richmond 擁有 14 年的互動式設計、開發與建築體驗。即使我不在工作室,他也能在視覺藝術學院找到數位教學/攝影技巧,以及先進的 ActionScript。Matthew 是 choppingblock.com 的共同創辦人兼設計師。