המאמר הזה נכתב ונשלח על ידי מפתח חיצוני. צוות ממשקי ה-API והכלים של YouTube מודה למתיו ריצ'מונד על הזמן והמומחיות שלו.
מת'יו ריצ'מונד (Matthew Richmond), The Choping Block, Inc.
אוקטובר 2008
מבוא
במאמר הזה אציג עטיפה (wrapper) מהימנה של ActionScript 3.0 לנגן YouTube ללא Chrome, ואסביר עליה בקצרה. המעטפת משתמשת בכיתה ExternalInterface של ActionScript וב-JavaScript API של YouTube.
הכלים של Google Player ל-YouTube והנגן ללא Chrome מאפשרים למעצבים או למפתחים לשלב את היכולות של YouTube בפרויקטים שלהם באינטרנט במהירות ובקלות. הגישה הזו אידיאלית לפרויקטים קטנים בתקציבים קבועים שלא מאפשרים אירוח סרטונים, וכן לפרויקטים בקנה מידה גדול ללקוחות שרוצים חוויית משתמש מותאמת אישית בלי להתרחק מהקהל שלהם ב-YouTube.

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

איור 3: קובץ JavaScript

איור 2: קובצי מחלקה של ActionScript
למעשה, המעטפת של ActionScript 3.0 מורכבת משני חלקים מקושרים: קובצי הכיתה של ActionScript 3.0 שנמצאים בתיקייה src/choppingblock/video/ (איור 2), וקובץ ה-JavaScript 'youTubeLoader.js' שנמצא בתיקייה deploy/_assets/js/ (איור 3). קובץ המקור של Flash/Flex ייצור מופע של המחלקה YouTubeLoader ActionScript; דף ה-XHTML מטמיע את קובץ ה-Flash ורושם אותו עם הפונקציות שבקובץ ה-JavaScript של youTubeLoader. חשוב להבין שמכאן, כל מה ש-YouTubeLoader עושה בקובץ ה-Flash נשלט באמצעות פונקציות ה-JavaScript.
מאחר שכל הפונקציונליות בתוך Flash נשלטת באמצעות ממשק ה-API של JavaScript, לא תוכל לטעון תוכן של YouTube בתוך 'סרט בדיקה' של Flash נגן. הוא יפעל רק כאשר הוא מוטמע בדף XHTML ומחובר כראוי לפונקציות JavaScript של YouTubeLoader.
הערה: כדי לבדוק אחת מהקריאות האלו, הקובץ צריך לפעול בשרת אינטרנט או לשנות את הגדרות האבטחה של ה-Flash Player, מכיוון שנגן ה-Flash מגביל שיחות בין קבצים מקומיים לאינטרנט.
יצירת אובייקט YouTubeLoader
כדי ליצור מופע של האובייקט YouTubeLoader בפרויקט Flash/Flex, קודם צריך לוודא שהחבילה (התיקייה) של הקבצים הנדרשים נמצאת באותה ספרייה שבה נמצא הפרויקט (ראו איור 2), או מוגדרת ב-Classpath של הפרויקט. לאחר מכן אפשר לייבא את קובצי החבילה:
import choppingblock.video.*;
כך לקובץ ActionScript תהיה גישה לכיתות YouTubeLoader.as ו-YouTubeLoaderEvent.as. עכשיו אפשר ליצור מופע של הכיתה YouTubeLoader ואת פונקציות ה-event listener הנדרשות:
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 של YouTube Loader. מומלץ להשתמש ב-SWFObject כדי להטמיע נגנים שהגישה אליהם תתבצע באמצעות JavaScript API. כך תוכל לאתר את גרסת ה-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 כדי להטמיע את ActionScript 3.0 swf שלך כאשר ממשק ה-API של JavaScript מופעל, ולאחר מכן להעביר הפניה ל-swf שלך אל ממשק ה-API של YouTubeLoader JavaScript.
<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 שמכיל אותו, כי הנגן ללא Chrome מתארח בדומיין שונה מדף ה-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 הרגילה של קובץ ה-SWF של YouTube כדי לאפשר קריאות ל-JavaScript API.replaceElemIdStr
- זהו מזהה ה-HTML DIV שיש להחליף בתוכן המוטמע. בדוגמה שלמעלה, הכתובתytapiplayer
.widthStr
– רוחב הנגן.heightStr
– גובה הנגן.swfVersionStr
– הגרסה המינימלית הנדרשת כדי שהמשתמש יוכל לראות את התוכן. במקרה כזה, צריך להשתמש בגרסה 8 ומעלה. אם למשתמש אין גרסה 8 ומעלה, הוא יראה את שורת הטקסט המוגדרת כברירת מחדל ב-HTML DIV.xiSwfUrlStr
- (אופציונלי) מציין את כתובת ה-URL של קובץ ה-SWF להתקנה המהירה. לא בשימוש בדוגמה הזו.flashVarsObj
– (אופציונלי) מציין את FlashVars בזוגות שם/ערך. לא בשימוש בדוגמה הזו.parObj
- (אופציונלי) הפרמטרים של האובייקט המוטמע. במקרה הזה, הגדרנו אתallowScriptAccess
.AttObj
- (אופציונלי) המאפיינים של האובייקט המוטמע. במקרה הזה, הגדרנו את המזהה ל-myytplayer
.
הסבר נוסף זמין במסמכי התיעוד של SWFObject.
SWFID ≡
יאחסן הפניה למזהה של אובייקט ההטמעה ש-JavaScript API ישתמש בו. צריך להשתמש באותו מזהה של אובייקט ההטמעה שהקצית לקובץ ה-SWF.
SWFID ≡ "youtubewrapper"
בשלב הזה אמורה להיות לך אפשרות לבדוק את הפרויקט בהצלחה. האובייקט YouTubeLoader אמור לטעון את הנגן ללא Chrome, ויש להפעיל את פונקציית הטיפול באירוע YouTubeLoaderEvent.LOADED
. עכשיו אנחנו מוכנים לשלוח בקשת סרטון וליצור אינטראקציה עם האובייקט YouTubeLoader.
אינטראקציה עם הנגן
הגישה הזו ליצירת Wrapper של ActionScript 3.0 לנגן ללא Chrome ממנפת את המחלקה ExternalInterface של ActionScript, ולכן עכשיו אנחנו יכולים להשתמש בכל אחת מהפעולות בתוך ממשק ה-API של נגן JavaScript ב-YouTube כדי לשלוט בנגן שנטען. אם תסתכלו בקטע 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 לנגן ללא Chrome היא לספק אינטראקציה חלקה עם YouTube API מתוך פרויקט ActionScript 3.0 Flash/Flex, הוספנו את אותן שיטות ציבוריות לקובץ הכיתה 'YouTubeLoader.as' שנמצא ב-src/choppingblock/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 כדי פשוט לקרוא לפונקציה המתאימה בתוך 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 אפשר פשוט לקרוא ל-methods באמצעות ההפניה לנגן. בהמשך מפורטת רשימה מלאה של השיטות הזמינות.
הרשמה לאירועים
הרשמה לאירועים על ידי הוספת האזנה לאירועים לקובץ העזר של הנגן. לדוגמה, כדי לקבל התראה כשמצב הנגן משתנה, צריך להוסיף האזנה לאירועים עבור 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; };
הפעולות הזמינות
כדי לקרוא ל-methods של ממשק ה-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
- הפונקציה מחזירה את המצב הנוכחי של הסרטון שנמצא כרגע ב-cue או נטען.
player.getBytesLoaded():Number
- הפונקציה מחזירה את הערך של הבייטים הנוכחיים שנטענו מהסרטון הנוכחי שהוכן או נטען.
player.getBytesTotal():Number
- מחזיר את הערך של סך הבייטים שנטענו של הסרטון שסומן/שנטענו כרגע.
player.getCurrentTime():Number
- הפונקציה מחזירה את המיקום הנוכחי בזמן של הסרטון שנטען או הוגדר כרגע.
player.getDuration():Number
- הפונקציה מחזירה את משך הזמן הנוכחי של הסרטון שנמצא כרגע ב-cue או נטען.
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
- מחזירה את כתובת ה-URL הנוכחית של הסרטון ב-YouTube של הסרטון הנוכחי שהוכן או נטען.
אירועים
YouTubeLoaderEvent.LOADED
- האירוע הזה מופעל אחרי שהטעינה של ה-Chromeless Player מסתיימת בהצלחה והוא מוכן לקבל קריאות לפעולות.
YouTubeLoaderEvent.STATE_CHANGE
- האירוע הזה מופעל בכל פעם שהמצב של הנגן משתנה. המחלקה YouTubeLoader מתרגמת את מספרי ה-API של JavaScript לערכי המחרוזת הקשורים אליהם, המחלקה YouTubeLoaderEvent מאחסנת את האירוע הנוכחי במשתנה שנקרא
state
. הערכים האפשריים הם: לא התחיל, הסתיים, מופעל, מושהה, אגירת נתונים, סרטון עם קליפ. כשקובץ ה-SWF נטען בפעם הראשונה, הוא משדר אירוע שלא התחיל. כאשר הסרטון מסומן ומוכן להפעלה, ישודר אירוע סימון כסרטון. YouTubeLoaderEvent.IO_ERROR
- מופעל כשמתרחשת שגיאה בנגן. יש שני קודי שגיאה אפשריים: קוד 100 מופיע כשהסרטון המבוקש לא נמצא. מצב זה מתרחש כאשר סרטון הוסר (מכל סיבה שהיא) או סומן כפרטי. הקוד 101 מועבר כשהסרטון המבוקש לא מאפשר הפעלה בנגנים המוטמעים.
הערות לגבי ההדגמה
למטרות הדגמה רצינו לכלול את שדות הטופס XHTML, הלחצנים וממשק התצוגה מתחת ל-ActionScript 3 Wrapper המוטמע. כדי לעדכן את קובץ ה-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. הקבצים האלה מופצים בתקווה שהם יועילו לכם, אבל ללא אחריות.
סיכום
המאמר הזה, הדמו וקובצי המקור אמורים לספק לכם סקירה כללית טובה של פתרון אחד פשוט יחסית ואמין לשילוב של YouTube API ונגנים מוטמעים בסביבות של ActionScript 3 באמצעות ספריית האריזה שפיתחנו לפרויקטים שלנו. הוספת תגובות לחלק גדול מהקוד, כך שקל מאוד לבדוק את הספריות ולשנות את המטרה שלהן. אין עמידה במגבלות ותמיד יש מקום לשיפור, לארגון מחדש ולשיפור. אם יש לך מחשבות בנושא, אפשר ליצור איתי קשר.
ביוגרפיה של המחבר

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