wrapper ל-ActionScript 3.0 עבור נגן ללא Chrome

המאמר הזה נכתב ונשלח על ידי מפתח חיצוני. צוות הכלים וה-API של YouTube מודה למת'יו ריצ'מונד על הזמן והמומחיות שלו.


מת'יו ריצ'מונד, The Choping Block, Inc.
אוקטובר 2008

מבוא

במאמר זה אציג ואתאר בקצרה את הכלי ActionScript 3.0 Wrapper עבור נגן YouTube ללא Chrome. wrapper משתמש במחלקה ExternalInterface וב-ActionScript של YouTube.

כלי YouTube Player ו-Chromeless Player של Google מאפשרים למעצבים/מפתחים לשלב במהירות ובקלות את היכולות של YouTube בפרויקטים המקוונים שלהם. הגישה הזו מתאימה במיוחד לפרויקטים קטנים בתקציבים קבועים שלא מאפשרים לארח סרטונים, וגם לפרויקטים בקנה מידה גדול ללקוחות שרוצים חוויה מותאמת אישית של משתמש הקצה, בלי להתרחק מהקהל שלהם ב-YouYube.

צילום מסך עוטף של ActionScript 3.0
איור 1: צילום מסך של מעטפת ActionScript 3.0

ממשקי ה-API של Flash והנגנים המוטמעים של YouTube נכתבים ופועלים היטב עם ActionScript 2.0. עם זאת, אם הפרויקט שלך הוא ActionScript 3.0, שילוב חלק הופך למורכב יותר. אמנם ניתן לטעון בקלות את נגני ActionScript 2.0 לתוך Swf של ActionScript 3.0, אך אין לך אפשרות ליצור קשר ישיר או להעביר קריאות פונקציונליות אל הנגן שנטען. שיטה זו מורכבת יותר, מכיוון שקובץ ה-swf שמגיע מהשרתים שלך ב-YourTube טוען סרטון לעצמו. wrapper צריך להיות מודע לעובדה הזו ולהגיב בהתאם. למזלנו, שפת ActionScript מכילה שתי דרכים לעקוף את החלקים המנותקים והמנותקים, מחלקת LocalConnection או מחלקת ממשק ה-ExternalInterface. הדגמה זו תתמקד באחרונה מפני שהממשק החיצוני פועל בצורה חלקה עם ממשק ה-API של JavaScript המתועד היטב, ולכן פועל היטב עם כל דבר אחר בדף ה-XHTML.

מקורות מידע חשובים

לפני שנתחיל, ריכזנו כאן רשימה של מקורות מידע וקבצים שקשורים לנושא. נושאים רבים במאמר זה מפורטים בפירוט בקישורים שבהמשך.

חפירות

סקירה כללית של מעטפת עטיפה

קובצי ClassScript ב-ActionScript
איור 3: קובץ JavaScript
קובצי ClassScript ב-ActionScript
איור 2: קבצים של ActionScript Class

Wrapper של קובץ ActionScript 3.0 מורכב בעיקר משני חלקים המחוברים זה לזה, קובצי המחלקה ActionScript 3.0 הממוקמים ב- src/chopingblock/video/ (איור 2) וקובץ ה-JavaScript 'youTubeLoader.js' הממוקם ב-deploy/_assets/js/ (איור 3). קובץ המקור מסוג Flash/Flex ייצור מופע של המחלקה ActionScripter של ActionScript; דף ה-XHTML שלך מטמיע את קובץ ה-Flash ורשום אותו בפונקציות בתוך קובץ ה-JavaScript של YouTube. חשוב להבין שכל מה ש-YouTubeLoader מבצע בקובץ ה-Flash נשלט על ידי פונקציות ה-JavaScript.

מאחר שכל הפונקציונליות בתוך Flash נשלטת באמצעות ממשק ה-API של JavaScript, לא תוכל לטעון תוכן של YouTube בנגן 'בודק סרטים' של Flash. הוא יפעל רק כאשר הוא מוטמע בדף XHTML ומחובר כראוי לפונקציות JavaScript של YouTube.

הערה: כדי לבדוק כל אחת מהקריאות האלה, הקובץ צריך להיות מופעל בשרת אינטרנט או לשנות את הגדרות האבטחה של ה-Flash Player, משום שנגן ה-Flash מגביל את הקריאות בין קבצים מקומיים לאינטרנט.

יצירת אובייקט ב-YouTubeLoader

לפני שתוכל ליצור מופע של אובייקט YouTubeLoader בפרויקט Flash/Flex שלך, עליך לוודא שהחבילה (התיקייה) של הקבצים הנדרשים נמצאת באותה ספרייה כמו הפרויקט שלך (ראה איור 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 וחיבור JavaScript של YouTubeLoader

לא תוכל לטעון בהצלחה תוכן מ-YouTube עד שקובץ ה-swf יוטמע בקובץ XHTML ויקושר ל-JavaScript של YouTubeLoader. מומלץ להשתמש ב-SWFObject כדי להטמיע נגנים שניגשים אליהם באמצעות ממשק API של JavaScript. כך תוכל לזהות את גרסת Flash Player של משתמש הקצה (ממשק ה-API של JavaScript מחייב Flash Player 8 או גרסה מתקדמת יותר), וכן לבטל את סימון התיבה 'לחץ כדי להפעיל פקד זה' בעת השימוש ב-Internet Explorer להצגת הנגן.

בתוך החלק <head> של קובץ ה-XHTML, מחברים את קובצי ה-swfobject ו-YouTubeLoader:

<script type="text/javascript" src="_assets/js/swfobject.js"></script>
<script type="text/javascript" src="_assets/js/youTubeLoader.js"></script>

בהמשך תוכלו לראות דוגמה לשימוש ב-SWFObject כדי להטמיע את קובץ ה-swf של ActionScript 3.0 עם JavaScript API מופעל, ולאחר מכן להעביר קובץ swf אל ממשק ה-API של JavaScript של YouTube.

<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 בקוד נדרש כדי לאפשר ל-SWF של הנגן לקרוא לפונקציות בדף ה-HTML שמכיל, מכיוון שה-Chromeless Player מתארח בדומיין שונה מדף ה-XHTML.

המאפיין היחיד שאנחנו מעבירים הוא המזהה של אובייקט ההטמעה – במקרה הזה, youtubewrapper. המזהה הזה ישמש את הקובץ youTubeLoader.js כדי לקבל הפניה לנגן באמצעות getElementById().

swfobject.embedSWF יטען את הנגן מ-YouTube ויטמיע אותו בדף שלך.

swfobject.embedSWF(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj)

  • swfUrlStr – זוהי כתובת ה-URL של קובץ ה-SWF. לידיעתכם, הוספנו את הפרמטרים enablejsapi ו-playerapiid לכתובת ה-URL הרגילה של YouTube SWF, כדי לאפשר קריאות ל-JavaScript API.
  • replaceElemIdStr – זהו מזהה ה-HTML DIV שיש להחליף בתוכן ההטמעה. בדוגמה שלמעלה, הערך הוא ytapiplayer.
  • widthStr – רוחב הנגן.
  • heightStr – גובה השחקן.
  • swfVersionStr – הגרסה המינימלית הנדרשת כדי שהמשתמש יראה את התוכן. במקרה זה, יש צורך בגרסה 8 ואילך. אם למשתמש אין 8 או יותר, הוא יראה את שורת הטקסט המוגדרת כברירת מחדל ב-HTML DIV.
  • xiSwfUrlStr - (אופציונלי) מציין את כתובת האתר של ה-SWF של ההתקנה האקספרס. לא בשימוש בדוגמה זו.
  • flashVarsObj - (אופציונלי) מציין את משתני FlashV בזוגות של שם:ערך. לא בשימוש בדוגמה זו.
  • parObj – (אופציונלי) הפרמטרים לאובייקט ההטמעה. במקרה הזה, הגדרנו את allowScriptAccess.
  • AttObj – (אופציונלי) המאפיינים של אובייקט ההטמעה. במקרה הזה, הגדרנו את המזהה כ-myytplayer.

לקבלת מידע נוסף, ניתן לעיין בתיעוד של SWFObject.

SWFID ≡ תשמור הפניה למזהה של אובייקט ההטמעה לצורך שימוש ב-JavaScript API. עליך להשתמש באותו מזהה של אובייקט ההטמעה שסיפקת ב-swf.

SWFID ≡ "youtubewrapper"

בשלב הזה אתם אמורים להיות מסוגלים לבדוק את הפרויקט שלכם. על האובייקט של YouTubeLoader לטעון את נגן Chromeless ולהפעיל את ה-handler של אירועים מסוג YouTubeLoaderEvent.LOADED. עכשיו אנחנו מוכנים לשלוח בקשת וידאו ולקיים אינטראקציה עם האובייקט של YouTubeLoader.

אינטראקציה עם השחקן

הגישה הזו ליצירת מעטפת 3.0 של ActionScript ל-Chromeless Player מבוססת על הסיווג ExternalInterface של ActionScript, ולכן אנו יכולים להשתמש כעת בכל אחת מהפעולות ב-YouTube JavaScript Player API כדי לשלוט בנגן שנטענו. אם תעיינו בקובץ ה-JavaScript 'youTubeLoader.js' שנמצא ב-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...

מאחר שהמטרה הסופית של Wrapper של ActionScript 3.0 עבור ה-Chromeless Player היא להציע אינטראקציה חלקה עם ממשק ה-API של YouTube מתוך פרויקט Flash/Flex של ActionScript 3.0, הוספנו את אותן שיטות ציבוריות בדיוק לקובץ המחלקה 'YouTubeLoader.as' הממוקם ב- src/choppblock/video/ (איור 2). המשמעות היא שניתן לקרוא בדיוק את אותן פעולות ישירות לאובייקט YouTubeLoader ב-Flash/Flex. אם תסתכלו על הקובץ של הכיתה, תראו:

// ------------------------------------
// 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 כדי לקרוא לפונקציה המתאימה בתוך ממשק ה-API של JavaScript.

בקשת סרטון

עכשיו אפשר לבקש סרטון מתוך קובץ ה-ActionScript 3.0 שלך על ידי קריאה לפונקציות באמצעות ההפניה לשחקן. לדוגמה, אם ברצונך להפעיל את הסרטון כאשר משתמש לוחץ על לחצן, עליך להוסיף ללחצן 'EventEvent.Click' האזנה לאירוע. תוכל לעשות זאת כך:

// assuming your button was called 'myButton'
myButton.addEventListener(MouseEvent.CLICK, youtubeLoadVideoHandler);

וליצור שיטת handler של אירועים שתטפל בבקשה. תוכל לעשות זאת כך:

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 ניתן פשוט לקרוא לשיטות באמצעות הפניה של הנגן. כאן מופיעה רשימה מלאה של השיטות הזמינות.

הרשמה לאירועים

נרשמים לאירועים על ידי הוספת event listener לקובץ העזר של הנגן. לדוגמה, כדי לקבל הודעה כשהמצב של השחקן משתנה, יש להוסיף event listener של YouTubeLoaderEvent.STATE_CHANGE. תוכל לעשות זאת כך:

// assuming that '_youTubeLoader' is a reference to your YouTubeLoader object
_youTubeLoader.addEventListener(YouTubeLoaderEvent.STATE_CHANGE, youTubePlayerStateChangeHandler);

וליצור שיטת handler של אירועים שתטפל בבקשה. תוכל לעשות זאת כך:


private function youTubePlayerStateChangeHandler (event:YouTubeLoaderEvent):void{
  //trace("YouTubeIntegrationDemo: youTubePlayerStateChangeHandler");
  
  _stateField.text = event.state;
};

פעולות זמינות

כדי להפעיל את שיטות ה-API של YouTubePlayer, קודם צריך ליצור מופע של המחלקה YouTubePlayer בקובץ ה-ActionScript ולשמור את ההפניה לאובייקט YouTubePlayer שבו רוצים לשלוט. ניתן לעשות זאת על ידי התקשרות אל:

var _youTubeLoader:YouTubeLoader;
_youTubeLoader = new YouTubeLoader();

שיטות ציבוריות

player.loadVideoById(id:String, startSeconds:Number = 0):void
הדף נטען ומופעל על סמך מזהה שצוין.
player.cueNewVideo(id:String, startSeconds:Number = 0):void
הדף נטען, אבל הסרטון לא מופעל באופן אוטומטי לפי המזהה שצוין.
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
מחזיר את קוד ההטמעה הנוכחי של הסרטון הנוכחי שנטען או שנטענה.
player.getVideoUrl():String
מחזיר את כתובת ה-URL הנוכחית של הסרטון ב-YouTube של הסרטון שנלווה/נטען כרגע.

אירועים

YouTubeLoaderEvent.LOADED
הפעלה ברגע שהטעינה של הנגן ללא Chrome הושלמה, והיא מוכנה לקבל שיחות תפעול.
YouTubeLoaderEvent.STATE_CHANGE
מופעל בכל פעם שמצב הנגן משתנה. מחלקה של YouTubeLoader מתרגמת את המספרים ב-JavaScript API לערכי המחרוזת הקשורים אליהם, במחלקה YouTubeLoaderEvent מאוחסן האירוע הנוכחי במשתנה שנקרא state. ערכים אפשריים לא התחילו, הסתיימו, הופעלו, הושהו, בתהליך אגירת נתונים, הסרטון הופעל. בפעם הראשונה טעינת ה-SWF תשודר, אירוע שלא התחיל. כאשר סרטון נדלק ומוכן להפעלה, הוא ישודר אירוע.
YouTubeLoaderEvent.IO_ERROR
מופעל כשמתרחשת שגיאה בנגן. קיימים שני קודי שגיאה אפשריים: 100 משודרת כאשר הסרטון המבוקש לא נמצא. דבר זה קורה כאשר סרטון הוסר (מכל סיבה שהיא), או שהוא סומן כפרטי. 101 משודר כאשר הסרטון המבוקש אינו מאפשר הפעלה בנגנים המוטמעים.

הערות להדגמה

למטרות הדגמה, רצינו לכלול את השדות, הלחצנים וממשק המשתמש של תצוגת XHTML מתחת ל-wrapScript המוטמע של ActionScript 3. על מנת שקובץ ה-swf וגם עדכון ה-XHTML יופיעו בו-זמנית, היה עלינו לכלול שתי שורות קוד בקובץ ה-JavaScript 'youTubeLoader.js', הממוקם ב-'deploy/_assets/js/' (איור 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. קבצים אלה מופצים בתקווה שהם יהיו שימושיים, ללא כל התחייבות.

סיכום

המאמר הזה מספק סקירה וקובצי מקור עם סקירה מקיפה של פתרון פשוט ואמין יחסית, לשילוב ממשק ה-API של YouTube ונגנים מוטמעים בסביבות ActionScript 3, באמצעות ספריית wrapper שפיתחנו לפרויקטים שלנו. מכיוון שהוספתי חלק גדול מהקוד, באופן אידיאלי יהיה די ברור לסייר בספריות ולשנות את הייעוד שלהן. היא אינה מוגבלת ותמיד יש מקום לשיפור, להטמעה מחדש ולשיפור. אם יש לך רעיונות בנושא הזה, אפשר ליצור איתי קשר.

ביוגרפיה של המחבר


מתיו ריצ&#39;מונד

למתיו ריצ'מונד יש 14 שנות ניסיון בעיצוב, בארכיטקטורה ובפיתוח אינטראקטיביים. כשהוא לא נמצא בסטודיו, הוא יכול ללמוד טכניקות של איור/צילום דיגיטלי ו-ActionScript מתקדם בבית הספר לאמנויות חזותיות. מת'יו הוא מייסד שותף ומעצב בכתובת chopingblock.com.