قائمة الأجزاء المترجمة من السلسلة:
- الطبخ
- ترجمة باستخدام Emscripten (أنت هنا)
- تحويل افي إلى mp4
بدءًا من هذا الجزء ، ستكون المادة أكثر تعقيدًا ، لذا لا تتردد في google أثناء القراءة ، إذا كنت لا تفهم ما يحدث.
بالإضافة إلى ذلك ، سأحاول توثيق حل المشكلات المحتملة حتى تتمكن من تجميع المكتبة بالإعدادات الخاصة بك.
في هذا الجزء سوف نحلل:
- كيفية إعداد بيئة لـ Emscripten في Docker
- باستخدام emconfigure و emmake
- كيفية حل المشاكل عند تجميع FFmpeg مع Emscripten
كيفية إعداد بيئة لـ Emscripten في Docker
في الجزء الأول ، قمنا بتجميع FFmpeg مع gcc ويمكننا الانتقال إلى استخدام صورة Docker مع emscripten.
سأستخدم إصدار trzeci / emscripten 1.38.45:
$ docker pull trzeci/emscripten:1.38.45
نظرًا لأن الصورة تستغرق حوالي 1 غيغابايت ، فقد تستغرق العملية بعض الوقت.
الآن سنجد التكوين الصحيح لتجميع FFmpeg إلى رموز emscripten بالتجربة والخطأ ، مما سيتطلب المثابرة وقراءة كميات كبيرة من الوثائق. تشغيل الحاوية مع emscripten وقم بتحميل مصادر FFmpeg في الدليل / src .
# , FFmpeg $ docker run -it \ -v $PWD:/src \ trzeci/emscripten:1.38.45 \ /bin/bash
داخل الحاوية ، قم بتنفيذ ls - اللون لرؤية شيء مثل هذا:
باستخدام emconfigure و emmake . كيفية حل مشاكل التجميع
لنبدأ مع التكوين. في الجزء الأول ، أجرينا ./configure - disable-x86asm ، في emscripten يتم تحقيق ذلك باستخدام الأمر emconfigure ./configure --disable-x86asm . (للحصول على تفاصيل حول استخدام emconfigure ، انظر هنا )
$ emconfigure ./configure --disable-x86asm
وبما أننا لم نر أي أخطاء ، يبقى فقط تنفيذ emmake make -j4 والحصول على FFmpeg.js المطلوب؟ لسوء الحظ ، لا. واحدة من أهم مهام emconfigure هي استبدال برنامج التحويل البرمجي لـ gcc بـ emcc (أو g ++ بـ em ++) ، لكن الإخراج من ./configure لا يزال ينتج gcc.
root@57ab95def750:/src# emconfigure ./configure --disable-x86asm emscripten sdl2-config called with /emsdk_portable/emscripten/tag-1.38.45/system/bin/sdl2-config --cflags emscripten sdl2-config called with /emsdk_portable/emscripten/tag-1.38.45/system/bin/sdl2-config --libs install prefix /usr/local source path . C compiler gcc # emcc C library glibc ARCH x86 (generic) big-endian no runtime cpu detection yes standalone assembly no x86 assembler nasm
أي أتمتة لها حدودها ، وفي هذه الحالة ، للأسف ، علينا أن نفعل كل شيء يدويًا. دعونا نرى ما إذا كانت هناك أي حجج لمساعدتنا:
$ ./configure --help
ضمن قسم خيارات Toolchain ، نرى وسيطات للإشارة إلى نوع برنامج التحويل البرمجي.
root@57ab95def750:/src# ./configure --help Usage: configure [options] Options: [defaults in brackets after descriptions]Help options: ... Toolchain options: ... --nm=NM use nm tool NM [nm -g] --ar=AR use archive tool AR [ar] --as=AS use assembler AS [] --ln_s=LN_S use symbolic link tool LN_S [ln -s -f] --strip=STRIP use strip tool STRIP [strip] --windres=WINDRES use windows resource compiler WINDRES [windres] --x86asmexe=EXE use nasm-compatible assembler EXE [nasm] --cc=CC use C compiler CC [gcc] --cxx=CXX use C compiler CXX [g++] --objcc=OCC use ObjC compiler OCC [gcc] --dep-cc=DEPCC use dependency generator DEPCC [gcc] --nvcc=NVCC use Nvidia CUDA compiler NVCC [nvcc] --ld=LD use linker LD [] ...
دعونا نستخدمها في المخطوطات
$ emconfigure ./configure \ --disable-x86asm \ --nm="llvm-nm -g" \ --ar=emar \ --cc=emcc \ --cxx=em++ \ --objcc=emcc \ --dep-cc=emcc
سوف يستغرق التنفيذ الآن ./configure مزيدًا من الوقت ، لكن نتيجة لذلك نحصل على emcc.
root@57ab95def750:/src# emconfigure ... emscripten sdl2-config called with /emsdk_portable/emscripten/tag-1.38.45/system/bin/sdl2-config --cflags emscripten sdl2-config called with /emsdk_portable/emscripten/tag-1.38.45/system/bin/sdl2-config --libs install prefix /usr/local source path . C compiler emcc # emcc C library ARCH x86 (generic) big-endian no runtime cpu detection yes standalone assembly no
دعونا نرى كيف يذهب التجميع.
$ emmake make -j4
وعلى الفور خطأ ...
root@57ab95def750:/src# emmake make -j4 ... ./libavutil/x86/timer.h:39:24: error: invalid output constraint '=a' in asm : "=a" (a), "=d" (d)); ^
تظهر الرسالة أن الخطأ مرتبط بطريقة ما بـ ASM. افتح ./libavutil/x86/timer.h لمعرفة أن المشكلة في x86 مضمّنة المجمّع ، وهو غير متوافق مع WebAssembly ، لذلك أوقف تشغيله.
$ emconfigure ./configure \ --disable-x86asm \ --disable-inline-asm \ # asm --nm="llvm-nm -g" \ --ar=emar \ --cc=emcc \ --cxx=em++ \ --objcc=emcc \ --dep-cc=emcc
دعنا نحاول تجميع مرة أخرى.
$ emmake make -j4
يستمر التجميع حتى الخطأ التالي.
root@57ab95def750:/src# emmake make -j4 ... AR libavdevice/libavdevice.a AR libavfilter/libavfilter.a AR libavformat/libavformat.a AR libavcodec/libavcodec.a AR libswresample/libswresample.a AR libswscale/libswscale.a AR libavutil/libavutil.a HOSTLD doc/print_options GENTEXI doc/avoptions_format.texi /bin/sh: 1: doc/print_options: Exec format error doc/Makefile:59: recipe for target 'doc/avoptions_format.texi' failed make: *** [doc/avoptions_format.texi] Error 2 make: *** Waiting for unfinished jobs....
هناك شيء متعلق بتوليد الوثائق ، والتي لا نحتاج إليها مطلقًا ، لذا قم بإيقاف تشغيلها.
$ emconfigure ./configure \ --disable-x86asm \ --disable-inline-asm \ --disable-doc \ # --nm="llvm-nm -g" \ --ar=emar \ --cc=emcc \ --cxx=em++ \ --objcc=emcc \ --dep-cc=emcc
نحن نفعل ذلك مرة أخرى.
$ emmake make -j4
الآن حدث الخطأ في مرحلة الشريط.
root@57ab95def750:/src# emmake make -j4 ... STRIP ffmpeg STRIP ffprobe strip:ffmpeg_g: File format not recognized strip:ffprobe_g: File format not recognized Makefile:101: recipe for target 'ffmpeg' failed make: *** [ffmpeg] Error 1 make: *** Waiting for unfinished jobs.... Makefile:101: recipe for target 'ffprobe' failed make: *** [ffprobe] Error 1
نظرًا لأن زراعة المحاصيل الأصلية لا تتوافق مع إصدار WebAssembly الخاص بنا ، فسنقوم أيضًا بتعطيله.
$ emconfigure ./configure \ --disable-x86asm \ --disable-inline-asm \ --disable-doc \ --disable-stripping \ # strip --nm="llvm-nm -g" \ --ar=emar \ --cc=emcc \ --cxx=em++ \ --objcc=emcc \ --dep-cc=emcc
المحاولة الرابعة.
$ emmake make -j4
أخيرًا ، انتهت العملية دون أخطاء. ولكن فقط في الإخراج حصلنا على ملف ffmpeg ، الذي لا يبدأ ، وهو ليس ملف js (أو ملف wasm). للحصول على ملف js ، نحتاج إلى إضافة -o ffmpeg.js إلى أمر emcc ، والذي يمكن القيام به بطريقتين:
- تغيير Makefile من FFmpeg نفسها
- إضافة تجميع / ربط إضافية
سنختار الطريقة الثانية ، حيث أنني لا أريد أن أتطرق إلى مصادر FFmpeg بسبب الآثار الجانبية المحتملة. لذلك نجد كيف يتم إنشاء ffmpeg باستخدام make. هذا هو المكان الذي يأتي فيه خيار جعله مفيدًا لتشغيل الجفاف.
$ emmake make -n
نحن نرى فريق الجيل.
root@57ab95def750:/src# emmake make -n ... printf "LD\t%s\n" ffmpeg_g; emcc -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample -Qunused-arguments -o ffmpeg_g fftools/ffmpeg_opt.o fftools/ffmpeg_filter.o fftools/ffmpeg_hw.o fftools/cmdutils.o fftools/ffmpeg.o -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lm -pthread -lm -lm -pthread -lm -lm -lm -pthread -lm printf "CP\t%s\n" ffmpeg; cp -p ffmpeg_g ffmpeg ...
هناك الكثير من الأشياء غير الضرورية ، لذلك دعونا نزيل الوسائط غير المستخدمة (التي ستراها في نهاية المجموعة) ، وقم بتنظيفها قليلاً وإعادة تسمية ffmpeg_g إلى ffmpeg.js .
$ emcc \ -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample \ -Qunused-arguments \ -o ffmpeg.js fftools/ffmpeg_opt.o fftools/ffmpeg_filter.o fftools/ffmpeg_hw.o fftools/cmdutils.o fftools/ffmpeg.o \ -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lm -pthread
كان يجب أن يكون ناجحًا ، لكننا سنواجه مشكلة نقص الذاكرة.
root@57ab95def750:/src# emcc ... shared:ERROR: Memory is not large enough for static data (11794000) plus the stack (5242880), please increase TOTAL_MEMORY (16777216) to at least 17037904
أضف الوسيطة TOTAL_MEMORY لزيادة حجم الذاكرة (33554432 بايت: = 32 ميغابايت).
$ emcc \ -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample \ -Qunused-arguments \ -o ffmpeg.js fftools/ffmpeg_opt.o fftools/ffmpeg_filter.o fftools/ffmpeg_hw.o fftools/cmdutils.o fftools/ffmpeg.o \ -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lm -pthread \ -s TOTAL_MEMORY=33554432
أخيرًا ، حصلنا على ملفات js و wasm
root@57ab95def750:/src# ls ffmpeg* ffmpeg ffmpeg.js ffmpeg.js.mem ffmpeg.wasm ffmpeg.worker.js ffmpeg_g
قم بإنشاء test.html لاختبار FFmpeg.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <script src="./ffmpeg.js"></script> </head> <body> </body> </html>
لنبدأ تشغيل الخادم السهل (عن طريق تنفيذ python2 -m SimpleHTTPServer ) وفتح الصفحة الناتجة ( http: // localhost: 8000 / test.html ) ، ثم افتح Chrome DevTools.
كما ترون ، تعمل FFmpeg إلى النصف بخطيئة ، لذا يمكنك الآن بدء تلميع ffmpeg.js.
يمكن العثور على البرنامج النصي للبناء الكامل في هذا المخزون (build-with-docker.sh و build-js.sh)
.