ملف تعريف ActionScript 3.0 للمشغّل الذي يعمل بدون Chrome

كتب هذه المقالة مطوّر خارجي وأرسلها. يشكر فريق YouTube APIs and Tools (أدوات وواجهات برمجة تطبيقات YouTube) "ماتيو ريتشموند" على وقته وخبرته.


Matthew Richmond، The Chopping Block، Inc.
تشرين الأول (أكتوبر) 2008

مقدمة

في هذه المقالة، سأستعرض بإيجاز ملف ActionScript 3.0 موثوقًا به لمشغّل YouTube الذي لا يعمل على Chrome. يستفيد الغلاف من فئة ExternalInterface في ActionScript وJavaScript API في YouTube.

من خلال "أدوات مشغّل YouTube" و"مشغّل Chromeless" من Google، تمكّن المصمّمون والمطوّرون من دمج ميزات YouTube الرائعة في مشاريعهم على الإنترنت بسرعة وسهولة. هذا الأسلوب مثالي للمشاريع الصغيرة ذات الميزانيات الثابتة التي لا تسمح باستضافة الفيديوهات، وكذلك المشاريع الواسعة النطاق للعملاء الذين يريدون تجربة مخصّصة للمستخدم النهائي بدون تباعد عن جمهور YouTube.

لقطة شاشة ملفوف ActionScript 3.0
الشكل 1: لقطة شاشة لـ ActionScript 3.0 Wrapper

تم إنشاء Flash API ومشغّلات الفيديو المضمّنة في YouTube باستخدام لغة ActionScript 2.0، وهي تعمل بشكل جيد مع هذه اللغة. وفي حال كان مشروعك يستخدم لغة ActionScript 3.0، يصبح الدمج السلس أكثر تعقيدًا. على الرغم من سهولة تحميل مشغِّلات ActionScript 2.0 إلى الإصدار swf 3.0 من ActionScript، فإنه لا يمكنك توصيل أي استدعاءات وظيفة إلى المشغّل المحمّل أو تمريره مباشرةً. تزيد هذه المشكلة تعقيدًا لأنّ ملف SWF القادم من خوادم YouTube يحمّل فيديو في نفسه. ويجب أن يكون برنامج التضمين على دراية تامة بهذه الحقيقة وأن يتفاعل وفقًا لذلك. لحسن الحظ، تحتوي لغة ActionScript على حلّين محتمَلَين لإعادة ربط هذه القطع المتداخلة غير المتصلة، وهما فئة LocalConnection أو فئة ExternalInterface. سيركز هذا العرض التوضيحي على الأخير لأن ExternalInterface تعمل بسلاسة مع واجهة برمجة تطبيقات JavaScript الموثقة جيدًا، وبالتالي تعمل بشكل جيد مع أي شيء آخر داخل صفحة XHTML.

Important Resources

قبل أن نبدأ، إليك قائمة بالموارد والملفات ذات الصلة والمتاحة لك. يمكنك الاطّلاع على المزيد من التفاصيل حول العديد من المواضيع التي تمت مناقشتها في هذه المقالة من خلال الروابط أدناه.

الاطّلاع على التفاصيل

نظرة عامة على الإصدار التجريبي من الحزمة

ملفات فئة ActionScript
الشكل 3: ملف JavaScript
ملفات فئات ActionScript
الشكل 2: ملفات فئة ActionScript

يتألّف ActionScript 3.0 Wrapper من جزأين مترابطَين بشكل أساسي، وهما ملفات فئة ActionScript 3.0 المتوفّرة في src/choppingblock/video/‎ (الشكل 2) وملف JavaScript‏ youTubeLoader.js المتوفّر في deploy/_assets/js/‎ (الشكل 3). سيُنشئ ملف المصدر Flash/Flex مثيلًا لفئة YouTubeLoader ActionScript، وتُضمِّن صفحة XHTML ملف Flash وتُسجّله باستخدام الدوالّ ضمن ملف JavaScript الخاص بـ youTubeLoader. من المهم معرفة أنّه من هنا فصاعدًا، يتم التحكّم في كل ما يفعله YouTubeLoader داخل ملف الفلاش من خلال دوال JavaScript.

نظرًا لأنه يتم التحكم في جميع الوظائف داخل Flash عبر واجهة برمجة تطبيقات JavaScript، لن تتمكن من تحميل أي محتوى YouTube في "فيلم الاختبار" الخاص بالفلاش لاعب. ولن تعمل هذه الأداة إلا عند تضمينها في صفحة XHTML ومتصلة بشكل صحيح بوظائف JavaScript youtuLoader.

ملاحظة: لاختبار أيّ من هذه الطلبات، يجب تشغيل ملفك على خادم ويب أو تعديل إعدادات الأمان في Flash Player، لأنّ Flash Player يحظر الطلبات بين الملفات المحلية والإنترنت.

إنشاء عنصر 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 لتضمين أي مشغّلات سيتم الوصول إليها باستخدام JavaScript API. سيتيح لك هذا اكتشاف إصدار Flash Player للمستخدم النهائي (تتطلّب واجهة برمجة تطبيقات 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 إلى واجهة برمجة التطبيقات JavaScript API في youTubeLoader.

<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 يستضيف على نطاق مختلف عن صفحة 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.
  • 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.

التفاعل مع اللاعب

بما أنّ هذا النهج لإنشاء حزمة ActionScript 3.0 لتطبيق 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...

بما أنّ الهدف النهائي من حزمة ActionScript 3.0 لتطبيق Chromeless Player هو توفير تفاعل سلس مع YouTube API من داخل مشروع Flash/Flex باستخدام ActionScript 3.0، أضفنا الطرق العامة نفسها إلى ملف فئة 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.

طلب فيديو

يمكنك الآن طلب فيديو من داخل ملف ActionScript 3.0 من خلال استدعاء الوظائف باستخدام مرجع المشغّل. على سبيل المثال، إذا أردت تشغيل الفيديو عند نقر أحد المستخدمين على زر ما، يمكنك إضافة أداة استماع حدث MouseEvent.انقر على الزر الذي تستخدمه. مثال:

// 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، يجب أولاً إنشاء مثيل لفئة 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
يعرض رمز تضمين YouTube الحالي للفيديو الذي تم تشغيله أو تحميله حاليًا.
player.getVideoUrl():String
لعرض عنوان URL الحالي لفيديو YouTube الذي تم تشغيله أو تحميله حاليًا.

الفعاليات

YouTubeLoaderEvent.LOADED
يتم تشغيله بعد اكتمال تحميل Chromeless Player بنجاح ويصبح جاهزًا لقبول طلبات العمليات.
YouTubeLoaderEvent.STATE_CHANGE
يتم تشغيله كلما تغيّرت حالة المشغّل. تُحوِّل فئة YouTubeLoader أرقام JavaScript API إلى قيم السلاسل ذات الصلة بها، وتخزِّن فئة YouTubeLoaderEvent الحدث الحالي في متغيّر يُسمى state. القيم المحتملة هي لم تبدأ، ومنتهية، وقيد التشغيل، ومتوقفة مؤقتًا، وتخزينًا مؤقتًا، وتم إشارة الفيديو. عند تحميل ملف SWF لأول مرة، سيتم بث حدث لم يبدأ بعد. عندما يكون الفيديو جاهزًا للتشغيل، سيتم بث حدث "بدء تشغيل الفيديو".
YouTubeLoaderEvent.IO_ERROR
يتم تشغيله عند حدوث خطأ في المشغّل. هناك رمزان خطأ محتملان: يتم بث رمز الخطأ 100 عندما لا يتم العثور على الفيديو المطلوب. يحدث ذلك في حال إزالة فيديو (لأي سبب كان) أو وضع علامة "خاص" عليه. يتم بث الخطأ 101 عندما لا يسمح الفيديو المطلوب بتشغيله في المشغّلات المضمّنة.

ملاحظات حول العرض التوضيحي

لأغراض التوضيح، أردنا تضمين حقول نموذج XHTML والأزرار وواجهة المستخدم المعروضة أسفل ActionScript 3 Wrapper المضمن. لكي يتم تحديث ملف swf وXHTML في الوقت نفسه، كان علينا تضمين سطرين من التعليمة البرمجية في "youYouTubeLoader.js". ملف JavaScript موجود في "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 Lesser Public License. يتم توزيع هذه الملفات على أمل أن تكون مفيدة ولكن بدون أي ضمان.

الخاتمة

من المفترض أن تقدّم لك هذه المقالة والعرض التجريبي والملفات المصدر نظرة عامة قوية على حلّ بسيط وموثوق نسبيًا لدمج YouTube API ومشغّلات الفيديو المضمّنة في بيئات ActionScript 3 باستخدام مكتبة الحِزم التي طوّرناها لمشاريعنا الخاصة. بما أنّني أضفت تعليقات توضيحية على الكثير من الرموز البرمجية، من المفترض أن يكون من السهل استكشاف المكتبات وإعادة استخدامها. ولكنّها ليست خالية من القيود، وهناك دائمًا مجال للتحسين وإعادة التحليل والتطوير. إذا كانت لديك أيّ ملاحظات حول هذا الموضوع، يُرجى التواصل معنا.

السيرة الذاتية للمؤلف


ماثيو ريتشموند

يمتلك "ماتيو ريتشموند" 14 عامًا من الخبرة في التصميم التفاعلي والتطوير والهندسة المعمارية. وعندما لا يتواجد في الاستوديو، يمكن العثور عليه وهو يعلم تقنيات الرسم التوضيحي/التصوير الرقمية وبرنامج ActionScript المتقدم في كلية الفنون البصرية. ماثيو هو شريك مؤسس ومصمّم في choppingblock.com.