فيديو عبر الإنترنت مع Wowza و Amazon Elastic Transcoder

نشرت: 2022-03-11

يعتمد نجاح أي تطبيق ويب واعتماده اليوم اعتمادًا كبيرًا على أدائه ومرونته وسهولة استخدامه.

خاصة في عالم ADHD اليوم ، سيفقد المستخدمون صبرهم سريعًا مع تطبيق ما إذا استغرق تحميل صفحته وقتًا طويلاً. بالنسبة لتطبيقات الويب التي تحتاج إلى دعم معالجة الفيديو - وهي عملية حسابية بطبيعتها - وكثيفة I / O - فإن هذا التحدي حاد بشكل خاص. ومع ذلك ، يزداد الطلب على المستخدمين ، ويريدون أن تكون مقاطع الفيديو الخاصة بهم عالية الجودة ويتم تحميلها بسرعة ، حتى لو كانت تعمل على هاتف ذكي أو جهاز لوحي.

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

يصف هذا المنشور كيف استفدت بشكل فعال من التقنيات مفتوحة المصدر والخدمات المستندة إلى السحابة لدمج إمكانات الفيديو في تطبيق ويب يستند إلى PHP.

معالجة الفيديو عبر الإنترنت بلغة PHP باستخدام Wowza و Amazon Elastic Transcoder

حالة الاستخدام

كنت جزءًا من فريق يحتاج إلى تطوير موقع ويب يشبه YouTube ، حيث يمكن للمستخدمين المسجلين تحميل ومشاركة مقاطع الفيديو الخاصة بهم.

يحتاج النظام إلى السماح للمستخدمين المسجلين بتحميل مقاطع الفيديو الخاصة بهم في مجموعة متنوعة من التنسيقات المدعومة والتي سيتم تحويلها بعد ذلك إلى تنسيق مشترك (MP4). احتجنا أيضًا إلى إنشاء مجموعة من الصور المصغرة وصورة مجمعة لاستخدامها في مشغل الفيديو لعرض الإطارات على شريط تقدم الفيديو.

ازدادت الأمور تعقيدًا بسبب حقيقة أن متطلبات العميل منعتنا من استخدام أي CDN متاح أو واجهات برمجة تطبيقات ترميزية ، لذلك احتجنا إلى تطوير حلنا من البداية.

تحميل الفيديو

نظرًا لأن عملية التحميل نفسها لم تكن بحاجة إلى أن تكون خاصة بالفيديو (كنا بحاجة فقط إلى إمكانية تحميل ملفات سهلة الاستخدام) ، فمن المنطقي استخدام حل مفتوح المصدر قائم بدلاً من طرح حل خاص بنا. اخترنا jQuery-File-Upload ، ويرجع ذلك أساسًا إلى أنه يدعم ميزتين أساسيتين في حالتنا ؛ بالتحديد ، شريط تقدم التحميل والتحميلات المقسمة.

مكّننا التحميل المقسم من السماح للمستخدم بتحميل ملف فيديو بأي حجم تقريبًا (مهم بشكل خاص لدعم ملفات الفيديو بدقة HD). باستخدام هذا الأسلوب ، يتم تقسيم الملف إلى "أجزاء" متعددة على الواجهة الأمامية والتي تستدعي إجراء التحميل مع كل قطعة بيانات (جنبًا إلى جنب مع البيانات الوصفية لكل جزء ، مثل رقم المقطع وإجمالي حجم الملف). يتم بعد ذلك إعادة تجميع ملف الفيديو الكامل في النهاية الخلفية. بالمناسبة ، ثبت أن تضمين رقم القطعة في البيانات الوصفية مهم بشكل خاص لأن بعض المتصفحات (مثل Mobile Safari) تميل إلى إرسال الأجزاء بترتيب عشوائي.

معالجة الفيديو عبر الإنترنت

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

كانت FFmpeg - مكتبة مفتوحة المصدر وموزعة مجانًا ومستخدمة على نطاق واسع - مفيدة للغاية في تلبية هذه المتطلبات. يوفر FFmpeg حلاً كاملاً عبر الأنظمة الأساسية لتسجيل وتحويل وتدفق ملفات الصوت والفيديو. يمكن استخدامه أيضًا لتحويل مقاطع الفيديو وإجراء تعديلات بسيطة (على سبيل المثال ، التشذيب والقص وإضافة علامة مائية وما إلى ذلك).

لأغراضنا ، تمكنا من استخدام FFmpeg لتقسيم الفيديو إلى عشرة أقسام ، ثم التقاط صورة مصغرة لكل قسم لتوفير الوظائف المطلوبة.

لسوء الحظ ، لا توجد روابط لغة PHP لمكتبة FFmpeg. نتيجة لذلك ، فإن الطريقة الوحيدة للاستفادة من FFmpeg من PHP هي استدعاء الثنائي من سطر الأوامر باستخدام أوامر النظام. هناك طريقتان أساسيتان لاستخدام FFmpeg في PHP:

  • ليباف. Libav هو مشروع برمجيات مجاني ، متشعب من FFmpeg في عام 2011 ، ينتج مكتبات وبرامج لمعالجة بيانات الوسائط المتعددة. على Ubuntu ، على سبيل المثال ، يمكن تثبيته باستخدام الأمر sudo apt-get install libav-tools . أوامر libav متوافقة مع FFmpeg و avconv. يحتاج PHP إلى وصول سطر الأوامر إلى ffmpeg/avconv لاستخدام هذا برمجيًا.
  • PHP-FFMpeg. PHP-FFMpeg هو محرك PHP موجه للكائنات للثنائي FFMpeg. يمكن الوصول إليه عن طريق تنفيذ composer update "php-ffmpeg/php-ffmpeg" .

استخدمنا PHP-FFMpeg لأنه يوفر وصولاً سهلاً إلى وظيفة FFmpeg التي كنا مهتمين بها. على سبيل المثال ، تتيح لك فئة FFProbe من هذه الحزمة تلقي معلومات حول برامج الترميز أو طول ملف فيديو معين على النحو التالي:

 $ffprobe = FFMpeg\FFProbe::create(); $ffprobe ->format('/path/to/video/mp4') // extracts file informations ->get('duration');

يسهل FFmpeg أيضًا حفظ أي إطار فيديو:

 $ffmpeg = FFMpeg\FFMpeg::create(); $video = $ffmpeg->open('video.mpg'); $video ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10)) ->save('frame.jpg');

يتوفر المزيد من التعليمات البرمجية التفصيلية هنا.

ملاحظة تحذير واحدة: نظرًا لبعض قوانين براءات الاختراع ، لا يمكن معالجة جميع برامج الترميز بواسطة FFmpeg وبعض التنسيقات غير مدعومة بشكل صحيح (أو بالكامل). أتذكر أنني كنت أعاني منذ عامين ، على سبيل المثال ، مع تنسيق .3gp عندما كان دعم الهواتف المميزة أمرًا ضروريًا.

قائمة الانتظار

بعد الحصول على برامج ترميز الفيديو والبيانات الوصفية الأخرى ، نقوم بدفع الفيديو إلى قائمة انتظار تحويل FIFO (أولاً يصرف أولاً). تم تنفيذ قائمة الانتظار باستخدام برنامج نصي بسيط cron الذي يختار عددًا معينًا من مقاطع الفيديو غير المعالجة في كل مرة يتم تشغيلها ويمررها إلى أداة تحويل (نموذج التعليمات البرمجية متاح هنا).

تستدعي أداة التحويل FFMpeg لإجراء التحويل وتمييز كل فيديو على أنه تمت معالجته.

لقد طورنا أيضًا آلية بسيطة لتقدير وقت الانتظار ، والتي تحسب متوسط ​​الوقت لتحويل دقيقة واحدة من الفيديو. باستخدام هذا المتوسط ​​، يمكننا حساب وقت المعالجة المتبقي المقدر وعرضه للمستخدم بعد انتهاء تحميل الفيديو ، بناءً على عدد دقائق الفيديو المتبقية التي يتعين معالجتها.

تحويل تنسيق الفيديو

ظهرت بعض التنسيقات المعترف بها عالميًا (مثل JPEG و GIF) للصور الثابتة التي تدعمها بشكل أساسي جميع الأجهزة وبرامج معالجة الصور. في حين أن بعض تنسيقات الفيديو أكثر شيوعًا من غيرها ، لم يظهر بعد مثل هذا التنسيق المدعوم عالميًا لمقاطع الفيديو.

في حالتنا ، بالإضافة إلى الحاجة إلى التحويل من مجموعة متنوعة من التنسيقات إلى تنسيق واحد مشترك (MPEG-4) ، كنا بحاجة إلى تحسين مقاطع الفيديو المحولة للتدفق إلى الأجهزة المحمولة.

بالنسبة لتحويل تنسيق الفيديو (على الأقل لاحتياجاتنا قصيرة المدى) ، كان استخدام Amazon Elastic Transcoder القائم على السحابة هو أفضل خيار متاح. بالإضافة إلى سهولة الاستخدام العامة ، تهتم خدمة محول الشفرة بالتحسين وجميع إعدادات التشفير. لحسن الحظ ، يتوفر AWS SDK لـ PHP ، مما يبسط استدعاء الخدمة من كود PHP الخاص بنا.

ملاحظة: يعد استخدام خدمة قائمة على السحابة مثل Amazon Elastic Transcoder أمرًا رائعًا إذا كنت ترغب في بدء التشغيل بسرعة. ومع ذلك ، ضع في اعتبارك أن هذا الخيار قد يصبح مكلفًا بالنسبة لعميلك ، خاصةً إذا كان من المحتمل أن يتطلب نموذج أعمالهم استخدامًا مكثفًا لمقاطع الفيديو الكبيرة. هناك عامل آخر يجب مراعاته وهو أنه لا يجب بالضرورة افتراض أن مقاطع الفيديو الخاصة بالعميل أو نموذج العمل الخاص بك سيكون متوافقًا مع شروط الخدمة.

تستخدم أمازون عناصر التخزين والحساب الأساسية ، S3 (خدمة التخزين البسيطة) و EC2 (سحابة الحوسبة المرنة) - جنبًا إلى جنب مع التدرج التلقائي و SNS (خدمة الإشعارات البسيطة) - لتوفير القدرة على التوسع والتصغير بشكل فوري تقريبًا.

يعد تثبيت aws-sdk أمرًا بسيطًا ، نظرًا لأن Amazon تحتفظ بإصدار Composer القابل للتثبيت من الحزمة. ما عليك سوى إضافة ”aws/aws-sdk-php": "2.*" إلى ملف composer.json الخاص بك وقم composer update .

من الواضح أن الوصول إلى Amazon Elastic Transcoder يتطلب حساب Amazon ، لذلك ستحتاج أيضًا إلى إعداد ذلك إذا لم يكن لديك (أو لدى عميلك) حساب بالفعل.

استلزم استخدامنا لخدمة Amazon Elastic Transcoder تحميل ملفات الفيديو أولاً إلى حاوية مناسبة على S3. ثم جعلنا وظيفة محول الشفرة مسؤولة عن فك تشفير وإنشاء صورة مصغرة ، وعند الانتهاء ، تنشر طلب HTTP إلى العنوان المحدد. يتطلب هذا بعض التكوين في لوحة AWS ، لكنه بسيط للغاية وتوفر Amazon وثائق جيدة حول كيفية القيام بذلك.

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

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

تدفق

دفق الفيديو هو قدرة تتطلب أداءً عاليًا: توقعات المستخدم للبث غير المنقطع عالية والتسامح مع زمن الوصول منخفض للغاية. غالبًا ما تتفاقم هذا التحدي بسبب الحاجة إلى دفق الفيديو إلى العديد من العملاء في نفس الوقت في الوقت الفعلي.

في حالتنا ، احتجنا إلى دعم قدرة كل مستخدم على إنشاء قناة فيديو خاصة به وبدء البث. يتكون حلنا من ثلاثة مكونات:

  • لوحة القيادة. التطبيق الذي يعمل كلوحة تحكم في البث ، مما يوفر القدرة على خدمة الفيديو.
  • مشاهد. عميل الفيديو الذي يستهلك ويعرض دفق الفيديو.
  • محرك الجري. خدمة دفق الفيديو القائمة على السحابة.

بالإضافة إلى حقيقة أن تقنية الفيديو عند الطلب (VOD) لا تزال تتطور ، كانت هناك مشكلة أخرى واجهناها وهي أن الوصول إلى الكاميرا لم يكن مدعومًا جيدًا ولم يقدم سوى اتصال P2P. كان هدفنا أيضًا هو توفير البث عبر الإنترنت لعدة مستخدمين متزامنين. علاوة على ذلك ، فإن دعم getUserMedia/Stream API (كان يُنظر إليه سابقًا على أنه عنصر <device> ) غير متسق حتى الآن عبر المتصفحات الحديثة. بناءً على هذه العوامل ، قررت استخدام تقنية Flash نظرًا لأنها كانت الخيار المعقول الوحيد حقًا. تم تنفيذ كلا التطبيقين (Dashboard and Viewer) باستخدام Flex و ActionScript .

بالنسبة لمحرك البث ، استخدمنا Wowza . على الرغم من وجود حلول أخرى غير تجارية (مثل Red5 ، التي يتم تسويقها على أنها بديل مباشر لـ Wowza) ، في حالتنا ، كان دعم المنتجات التجارية عاملاً مهمًا. أيضًا ، على الأقل في الوقت الذي كنا نبني فيه النظام ، قدم Wowza توثيقًا أفضل كان ميزة إضافية. (لاحظ أنه يمكنك الحصول على إصدار تجريبي من Wowza مجانًا لمدة 30 يومًا ، وهناك أيضًا إصدار تجريبي للمطور يمكنك استخدامه لمدة تصل إلى 180 يومًا. ولكن هناك بعض القيود ؛ يمكن أن يعمل البث المباشر لعميلين فقط وهناك حد على الحد الأقصى لعدد الاتصالات.)

محرك الجري Wowza

استخدمنا تطبيق LiveStream المتوفر مع Wowza. لتكوينه ، اترك applications/app_name فارغًا وفي conf/app_name انسخ ملف Application.xml من كتالوج conf . قم بتحرير الملف لتهيئة قسم <Streams> كما يلي:

 <Streams> <StreamType>live</StreamType> <StorageDir>${com.wowza.wms.context.VHostConfigHome}/content</StorageDir> <KeyDir>${com.wowza.wms.context.VHostConfigHome}/keys</KeyDir> <LiveStreamPacketizers></LiveStreamPacketizers> <Properties></Properties> </Streams>

المعلمة الرئيسية هي <StreamType>live</StreamType> والتي تحدد أن هذا سيكون دفقًا من بث فيديو مباشر (على سبيل المثال ، كاميرا). لاحظ أنه بعد تحرير هذا الملف وحفظه ، ستحتاج إلى إعادة تشغيل Wowza.

تطبيقات الفلاش (فليكس / أكشن سكريبت)

يوفر الفلاش نظامًا متكاملًا تمامًا لتوصيل الكاميرا والميكروفون بخادم بث Wowza. هذا مفيد بشكل خاص إذا كانت تجربتك مع ActionScript محدودة.

يعتمد التطبيق بالكامل بشكل أساسي على التفاعل بين العناصر التالية:

  • نتكونيكشن. تقوم فئة NetConnection بإنشاء اتصال ثنائي الاتجاه بين العميل والخادم. يمكن أن يكون العميل تطبيق Flash Player أو AIR. يمكن أن يكون الخادم خادم ويب أو Flash Media Server أو خادم تطبيق يقوم بتشغيل Flash عن بُعد أو خدمة Adobe Stratus.
  • الة تصوير. تُستخدم فئة الكاميرا لالتقاط الفيديو من نظام العميل أو كاميرا الجهاز.
  • ميكروفون. تُستخدم فئة الميكروفون لمراقبة الصوت أو التقاطه من ميكروفون.
  • نت ستريم. تفتح فئة NetStream قناة دفق أحادية الاتجاه عبر NetConnection.

أولاً ، نقوم بالاتصال بخادم Wowza المتدفق باستخدام مثيل NetConnection ثم نعلق مستمع الحدث الذي سيستمع إلى التغييرات في حالة اتصال الشبكة:

 nc = new NetConnection(); nc.connect(serverAddress:string); nc.addEventListener( NetStatusEvent.NET_STATUS, // event type eNetStatus, // listener function false, // use capture? 0, // priority true // use weak reference? );

فيما يلي مثال بسيط على مستمع حدث يربط الكاميرا والميكروفون بخادم البث:

 private function eNetStatus(e:NetStatusEvent):void { switch (e.info.code) { case "NetConnection.Connect.Success": camera = Camera.getCamera(); mic = Microphone.getMicrophone(); ns = new NetStream(nc); ns.publish(streamName, "live"); ns.attachCamera(camera); ns.attachAudio(mic); break; case "NetConnection.Connect.Closed": // debug trace... display user message break; }

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

 if(event.info.code == "NetConnection.Connect.Success") { ns = new NetStream(nc); ns.client = nsClient; ns.addEventListener(NetStatusEvent.NET_STATUS, nsClient.onNetStatus); ns.play(streamName); video = new Video(); addChild(video); // this will display video video.attachNetStream(ns); // connect NetStream to video }

يتم إحتوائه

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