無 Chrome 播放器的 ActionScript 3.0 包裝函式

本文是由外部開發人員撰寫及提交。 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 觀眾保持距離。

ActionScript 3.0 包裝函式螢幕截圖
圖 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:JavaScript 檔案
ActionScript 類別檔案
圖 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 的網址。請注意,我們已將 enablejsapiplayerapiid 參數附加至一般的 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)

Matthew Richmond 擁有 14 年的互動式設計、開發與建築體驗。即使我不在工作室,他也能在視覺藝術學院找到數位教學/攝影技巧,以及先進的 ActionScript。Matthew 是 choppingblock.com 的共同創辦人兼設計師。