HLS في MP4 باستخدام ffmpeg في المستعرض

مرحبا! لأكثر من شهرين ، في وقت فراغي ، كنت أشاهد تطبيق ويب لتحويل HLS و DASH إلى MP4 باستخدام emscripten و ffmpeg ، والتي أريد من خلالها مشاركة كيف تمكنت من القيام بذلك.

في هذه المقالة لن أقتبس شفرة المصدر لتحرير وتصحيحات ffmpeg ، كما تم إجراء معظمها على ركبتي ، وأنا لست جيدًا جدًا في C. ولكن الآن هناك ما يكفي من المقالات لمساعدتك.

المقدمة


قبل عامين ، كان لدي هدف الجمع بين مسار الصوت والفيديو معًا في ملف mp4 واحد. ثم انغمست للتو في emscripten وللأساسيات وجدت مستودع ffmpeg.js الذي تعلمت منه الكثير. ثم تمكنت تقريبا لتحقيق هذا الهدف، على الرغم من أنني كان مشروطا جدا المنحى في C.
فهم شفرة المصدر، فإن فمبيج التصحيح للعمل مع نظام الملفات، حيث القراءة من ملف تسبب في وظيفة غير متزامن في شبيبة التي قرأت سائل الملف ونقل العازلة، وعندما كان يسمى الكتابة دالة js التي ترسل بيانات المخزن المؤقت إلى المستودع.

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

بشكل عام ، مع مثل هذه المشاكل ، لا يمكن تسمية هذا بحل عمل ، حيث ظل كل هذا عرضًا صغيرًا.



بعد عام ونصف


بعد مشاهدة تقرير في Google Dev Summit عن الميزات الجديدة في WebAssambly ، ذهبت لمعرفة كيفية عمل emscripten ورأيت رسالة:
Emscripten تنبعث WebAssembly باستخدام الواجهة الخلفية LLVM wasm ، منذ الإصدار 1.39.0 (أكتوبر 2019) ، وتم إيقاف الواجهة الخلفية القديمة fastcomp

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

والآن ، حان الوقت عندما اجتمعت وكسبت! اختفت مشكلة الشفرة غير المتزامنة ، ولم تكن هناك حاجة لتصحيح أي شيء ، فقد عملت كما ينبغي من البداية.

هنا يبدو أنني وصلت إلى هدفي ، ولكن ... ظهر هدف جديد.

إعادة كتابة بروتوكول HTTP


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

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

أسبوعين فقط ، وأخيرًا تمكنت من إجراء التكرار الأول لبروتوكول http العامل ، ويبدو أن هذا هو كل شيء؟

عندما ينتهي الأصعب


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

بشكل أساسي ، تم عمل رمز المستخدم ، والذي كان وكيلًا لطلبات الجلب من ffmpeg لتنزيل البيانات.

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

في Firefox ، كما اتضح ، لا تسمح لك واجهة برمجة التطبيقات الإضافية بإدارة الطاقة ، والتي لا يمكنك من خلالها منع الكمبيوتر من النوم ، للأسف.

يبدو الامتداد كما يلي:



فقط حسّنت الصفحة التي كان فيها الموقع قليلاً ، واجهة مستخدم مادة مخدرة ، وضع اللمسات الأخيرة على جميع الأماكن التي تم جلدها.



بعد اختبار طرق مختلفة لتخزين البيانات ، كشفت عن عدد من المشاكل:

Blob - Chrome يكتبها إلى ذاكرة الوصول العشوائي ويسقط على القرص عند تجاوزها ، ولكن فقط في OSX عندما تفيض الذاكرة ، يترك نظام التشغيل الحساب ويغلق جميع التطبيقات المفتوحة. وعمومًا ، احتفظ فايرفوكس دائمًا بالبيانات في الذاكرة.

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

IndexedDb - يعمل مثل الساعة ، ويعرف كيفية تخزين النقطة ، ويكتب البيانات بدون زخرفة ، ولكن Firefox يحد بشكل صارم من مقدار 2 جيجابايت.

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





والآن ، يمكنك تجربة النتيجة بنفسك هنا

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

شكرا لقرائتك!

إذا كان لديك أسئلة حول ffmpeg و emscripten - اكتب ، سأحاول الإجابة.

All Articles