Open gogoend opened 4 years ago
自从上次写了尝试写一个 Web Assembly - HelloWorld示例程序(C语言)一文,并试着搞出一个HelloWorld后,笔者突然在想一个问题,既然WASM这么有意思,那是不是也可以将一些使用C语言编写的工具也编译到WASM,来使其可以在浏览器上运行?在此随便试试。 因此,笔者各种百度了一下,想试试看能否将FFMPEG移植到浏览器上跑起来。
wasm-ld: error: initial memory too small, 19408960 bytes needed
Ubuntu 18.04(WSL 2) Emscripten 1.39.20(e7e39da9c81faecd9ecf44065cee864d76e4e34d)
Emscripten编译环境的搭建过程见”尝试写一个 Web Assembly - HelloWorld示例程序(C语言)“。
emconfigure ./configure --cc="emcc" --cxx="em++" --ar="emar" \ --ranlib=emranlib --prefix=$(pwd)/dist --enable-cross-compile --target-os=none \ --arch=x86_64 --cpu=generic --disable-ffplay --disable-ffprobe --disable-asm \ --disable-doc --disable-devices --disable-indevs --disable-outdevs --disable-network \ --disable-w32threads --disable-pthreads --enable-ffmpeg --enable-static --disable-shared \ --enable-decoder=pcm_mulaw --enable-decoder=pcm_alaw --enable-decoder=adpcm_ima_smjpeg \ --enable-decoder=aac --enable-decoder=hevc --enable-decoder=h264 --enable-protocol=file \ --disable-stripping
emmake make -j 8
emcc \ -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample \ -Qunused-arguments -Oz \ -o javascript/ffmpeg-core.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 \ -s MODULARIZE=1 \ -s EXPORTED_FUNCTIONS="[_ffmpeg]" \ -s EXTRA_EXPORTED_RUNTIME_METHODS="[cwrap, FS, getValue, setValue]" \ -s TOTAL_MEMORY=33554432 \ -s ALLOW_MEMORY_GROWTH=1
这里最终产生的文件将会存为javascript/ffmpeg-core.js,在ffmpeg-core.js旁边的还有ffmpeg-core.wasm。事实上,ffmpeg-core.js是由Emscripten自动生成的文件,该文件包含了一些Polyfill,以及各类工具、API,用于辅助ffmpeg-core.wasm运行。例如文件系统API,可以在浏览器环境下模拟出一个虚拟文件系统,从而对文件进行存取。 这一步过后,可以新建一个HTML文件,将ffmpeg-core.js进行引入。 此时若执行代码中暴露的_ffmpeg()方法,将可以得到如下输出:
javascript/ffmpeg-core.js
ffmpeg-core.js
ffmpeg-core.wasm
_ffmpeg()
#!/bin/bash -x set -e -o pipefail BUILD_DIR=$PWD/build # build_x264() { # cd third_party/x264 # emconfigure ./configure \ # --prefix=$BUILD_DIR \ # --enable-static \ # --disable-cli \ # --disable-asm # emmake make install-lib-static # cd - # } FFMPEG_CONFIG_FLAGS_BASE=( --arch=x86_64 --enable-gpl --enable-cross-compile --disable-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --extra-cflags="-I$BUILD_DIR/include" --extra-cxxflags="-I$BUILD_DIR/include" --extra-ldflags="-L$BUILD_DIR/lib" --pkg-config-flags="--static" --nm="llvm-nm" --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc # 解码器 --enable-decoder=pcm_mulaw --enable-decoder=pcm_alaw --enable-decoder=adpcm_ima_smjpeg --enable-decoder=aac --enable-decoder=hevc --enable-decoder=h264 --enable-protocol=file # 其他禁用项目 --disable-devices --disable-indevs --disable-outdevs --disable-network --disable-w32threads --disable-pthreads ) configure_ffmpeg() { emconfigure ./configure "${FFMPEG_CONFIG_FLAGS_BASE[@]}" } make_ffmpeg() { NPROC=$(grep -c ^processor /proc/cpuinfo) emmake make -j${NPROC} } build_ffmpegjs() { emcc \ -I. -I./fftools -I$BUILD_DIR/include \ -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Llibpostproc -L${BUILD_DIR}/lib \ -Qunused-arguments -Oz \ -o dist/ffmpeg-core.js fftools/ffmpeg_opt.c fftools/ffmpeg_filter.c fftools/ffmpeg_hw.c fftools/cmdutils.c fftools/ffmpeg.c \ -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lpostproc -lm \ --closure 1 \ -s USE_SDL=2 \ -s MODULARIZE=1 \ -s SINGLE_FILE=1 \ -s EXTRA_EXPORTED_RUNTIME_METHODS="[cwrap, FS, getValue, setValue]" \ -s EXPORTED_FUNCTIONS="[_ffmpeg]" \ -s TOTAL_MEMORY=33554432 \ -s ALLOW_MEMORY_GROWTH=1 } main() { # build_x264 configure_ffmpeg make_ffmpeg build_ffmpegjs } main "$@"
有windows编译的嘛
Windows下我没编成功,可能是我比较菜
但上面这个脚本执行在Windows的Linux子系统下是编成功的,用 Win10 或许可以装WSL
编译出来的版本因为是单线程,会阻塞页面渲染,有木有考虑用web worker加载运行ffmpeg呢?
web worker
@seminelee 咋说呢,这个有考虑,不过我可能还没找到相关资料;其实我目前工作不涉及这个,很想挤出时间来看看,但就是想做的事情太多,有点点难挤
嗯
自从上次写了尝试写一个 Web Assembly - HelloWorld示例程序(C语言)一文,并试着搞出一个HelloWorld后,笔者突然在想一个问题,既然WASM这么有意思,那是不是也可以将一些使用C语言编写的工具也编译到WASM,来使其可以在浏览器上运行?在此随便试试。 因此,笔者各种百度了一下,想试试看能否将FFMPEG移植到浏览器上跑起来。
参考资料
wasm-ld: error: initial memory too small, 19408960 bytes needed
的错误。编译环境
Ubuntu 18.04(WSL 2) Emscripten 1.39.20(e7e39da9c81faecd9ecf44065cee864d76e4e34d)
Emscripten编译环境的搭建过程见”尝试写一个 Web Assembly - HelloWorld示例程序(C语言)“。
编译步骤
这里最终产生的文件将会存为
javascript/ffmpeg-core.js
,在ffmpeg-core.js
旁边的还有ffmpeg-core.wasm
。事实上,ffmpeg-core.js
是由Emscripten自动生成的文件,该文件包含了一些Polyfill,以及各类工具、API,用于辅助ffmpeg-core.wasm
运行。例如文件系统API,可以在浏览器环境下模拟出一个虚拟文件系统,从而对文件进行存取。 这一步过后,可以新建一个HTML文件,将ffmpeg-core.js
进行引入。 此时若执行代码中暴露的_ffmpeg()
方法,将可以得到如下输出:一个可用的编译脚本