التفاف ActionScript 3.0 لمشغل Chromeless

تمت كتابة هذه المقالة وإرسالها بواسطة مطوّر برامج خارجي. يتوجّه فريق الأدوات وواجهات برمجة التطبيقات في YouTube بالشكر إلى ماثيو ريتشموند على وقته وخبرته.


ماثيو ريتشموند، شركة The Chopping Block, Inc.
تشرين الأول (أكتوبر) 2008

المقدمة

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

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

لقطة شاشة ملف التفاف ActionScript 3.0
الشكل 1: لقطة شاشة مغلّفة في ActionScript 3.0

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

موارد مهمة

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

التعمّق في البيانات

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

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

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

نظرًا لأن جميع وظائف Flash يتم التحكم فيها عبر واجهة برمجة تطبيقات جافا سكريبت، فلن تتمكن من تحميل أي محتوى YouTube في مشغل "اختبار الأفلام" لبرنامج Flash. ولن تعمل إلا عند تضمينها في صفحة XHTML وربطها بشكل صحيح بوظائف جافا سكريبت على 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 وربط جافا سكريبت youTubeLoader

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

SWFID ≡ "youtubewrapper"

من المفترض أن تتمكن في هذه المرحلة من اختبار مشروعك بنجاح. يجب على كائن YouTubeLoader تحميل المشغّل بدون Chrome ويجب استدعاء معالج الحدث YouTubeLoaderEvent.LOADED بنجاح. أصبحنا الآن مستعدين لإرسال طلب فيديو والتفاعل مع عنصر YouTubeLoader.

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

نظرًا لأن هذا المنهج لإنشاء التفاف ActionScript 3.0 للمشغل الذي بدون Chrome يستفيد من فئة ActionScript الخارجية، فيمكننا الآن استخدام أي من العمليات داخل واجهة برمجة تطبيقات مشغل جافا سكريبت في YouTube للتحكم في المشغل الذي تم تحميله. إذا ألقيت نظرة على ملف جافا سكريبت "youTubeLoader.js" في موقع النشر/_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 من داخل مشروع 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 لاستدعاء الوظيفة المناسبة ضمن واجهة برمجة تطبيقات جافا سكريبت.

طلب فيديو

يمكنك الآن طلب فيديو من داخل ملف 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" );
};

خارج ملف فلاش/مرن، يمكنك اختياريًا طلب فيديو عن طريق استدعاء وظيفة جافا سكريبت المقابلة مباشرة. مثال:

 <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
يتم تنشيطها بعد اكتمال تحميل مشغل بدون Chrome وجاهزية لقبول استدعاءات العمليات.
YouTubeLoaderEvent.STATE_CHANGE
يتم الإطلاق عندما تتغير حالة اللاعب. تترجم فئة YouTubeLoader أرقام واجهة برمجة التطبيقات لجافا سكريبت إلى قيم السلاسل ذات الصلة، وتخزّن فئة YouTubeLoaderEvent الحدث الحالي في متغير يسمى state. القيم المحتملة هي لم يتم بدؤها أو إنهائها أو تشغيلها أو إيقافها مؤقتًا أو تخزينها مؤقتًا أو عرضها. عند تحميل ملف SWF لأول مرة، سيتم بث حدث لم يبدأ. عندما يتم تشغيل تلميح الفيديو ويكون جاهزًا للتشغيل، فإنه سيبث حدثًا مكتوبًا على الفيديو.
YouTubeLoaderEvent.IO_ERROR
يتم تنشيطها عند حدوث خطأ في المشغل. هناك رمزان من رموز الخطأ المحتملة: يتم إعلان الخطأ 100 عند عدم العثور على الفيديو المطلوب. يحدث ذلك عندما تتم إزالة فيديو (لأي سبب من الأسباب)، أو عند وضع علامة عليه كخاص. يتم بث 101 عندما لا يسمح الفيديو المطلوب بتشغيله في المشغلات المضمنة.

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

لأغراض التوضيح، أردنا تضمين حقول نموذج XHTML والأزرار وواجهة مستخدم العرض أسفل التفاف ActionScript 3 المضمّن. ولكي يكون لدينا ملف Swf وتحديث XHTML في نفس الوقت، كان علينا تضمين سطرين من الشفرة في ملف جافا سكريبت "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 والمشغلات المضمّنة في بيئات ActionScript 3 باستخدام مكتبة برنامج التضمين التي تم تطويرها من أجل مشروعاتنا. وبما أنني علقت على جزء كبير من الشفرة، فسيكون من الأفضل إلى حد ما استكشاف المكتبات وإعادة توظيفها. الأمر لا يخلو من القيود، وثمة دائمًا فرصة للتحسين وإعادة التدخل والتحسين. إذا كان لديك أي أفكار حول هذا الموضوع، لا تتردد في التواصل معي.

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


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

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