webassembly介绍
WebAssembly(缩写为 wasm)是一种使用非 JavaScript 代码,并使其在浏览器中运行的方法。这些代码可以是 C、C++ 或 Rust 等。它们会被编译进你的浏览器,在你的 CPU 上以接近原生的速度运行。这些代码的形式是二进制文件,你可以直接在 JavaScript 中将它们当作模块来用。
编译环境安装
windows 安装linux虚拟机
按官网说明结果发现根本找不到emcc命令,不想纠结了,发现官网建议用windows装linux的虚拟机装,遂下载vmware
参考文章
vmware下载 https://www.dandelioncloud.cn/article/details/1025025720092480
ubuntu镜像下载及配置 https://zhuanlan.zhihu.com/p/38797088
我用的是默认的安装,不过启动前需要在虚拟机配置里移除声卡,打印机,不然电脑会蓝屏。另外最好配置加高一点,不然实在慢的不行
启动之后会默认安装系统
之后安装vim,换国内镜像,安装git 此处不赘述
linux/mac 直接安装
然后安装webassembly环境
官网https://emscripten.org/docs/getting_started/downloads.html 不过我先试试中文的教程
$ git clone https://github.com/emscripten-core/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest
$ source ./emsdk_env.sh
emcc -v检查安装是否成功
#Install gcc
sudo apt-get install build-essential
sudo apt-get install cmake
可能需要检查一下其他依赖有没有安装
https://emscripten.org/docs/building_from_source/toolchain_what_is_needed.html#toolchain-test-which-dependencies-are-installed
我好像缺少llvm,后面因为这个报错了才发现。有时候不是结果的错误也需要注意。
mac的llvm需要设置path
export PATH=“
E
M
S
D
K
R
O
O
T
/
u
p
s
t
r
e
a
m
/
b
i
n
:
EMSDK_ROOT/upstream/bin:
EMSDKROOT/upstream/bin:PATH”
ffmpeg编译成wasm
克隆ffmpeg
git clone --depth 1 --branch n4.3.1 git@github.com:FFmpeg/FFmpeg.git
主要的参考资料
https://emscripten.org/docs/building_from_source/toolchain_what_is_needed.html#toolchain-what-you-need
https://jeromewu.github.io/build-ffmpeg-webassembly-version-part-2-compile-with-emscripten/
ffmpeg和emsdk的版本非常重要!!
ffmpeg和emsdk的版本非常重要!!
ffmpeg和emsdk的版本非常重要!!
git clone --branch n4.3.1 git@github.com:FFmpeg/FFmpeg.git
./emsdk install 1.39.18
./emsdk activate 1.39.18
最后折腾了好几天,终于搞出了一个可以正常编译的build脚本。和网上资料唯一的区别就是注释掉的那两行,如果不注释掉会一直卡在configure环节。
还有一个坑就是mac系统需要自己装llvm,并且导入环境变量,不能用emsdk里的llvm,不然好像会报 wasm-ld: error: unable to find library
export PATH="/usr/local/opt/llvm/bin:$PATH"
但是我后面试的时候发现还得
export PATH="/Users/mymac/work/myFfmpeg/emsdk/upstream/bin:$PATH"
#!/bin/bash -x
# verify Emscripten version
emcc -v
# configure FFMpeg with Emscripten
CFLAGS="-s USE_PTHREADS"
LDFLAGS="$CFLAGS -s INITIAL_MEMORY=33554432" # 33554432 bytes = 32 MB
CONFIG_ARGS=(
--target-os=none # use none to prevent any os specific configurations
--arch=x86_32 # use x86_32 to achieve minimal architectural optimization
--enable-cross-compile # enable cross compile
--disable-x86asm # disable x86 asm
--disable-inline-asm # disable inline asm
--disable-stripping # disable stripping
--disable-programs # disable programs build (incl. ffplay, ffprobe & ffmpeg)
--disable-doc # disable doc
--extra-cflags="$CFLAGS"
--extra-cxxflags="$CFLAGS"
--extra-ldflags="$LDFLAGS"
# --nm="llvm-nm -g"
--ar=emar
#--as=llvm-as
--ranlib=llvm-ranlib
--cc=emcc
--cxx=em++
--objcc=emcc
--dep-cc=emcc
)
emconfigure ./configure "${CONFIG_ARGS[@]}"
# build dependencies
emmake make -j4
# build ffmpeg.wasm
mkdir -p wasm/dist
ARGS=(
-I. -I./fftools
-Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample
-Qunused-arguments
-o wasm/dist/ffmpeg.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 -lm
-s TOTAL_MEMORY=33554432
-s ALLOW_MEMORY_GROWTH=1
-s EXTRA_EXPORTED_RUNTIME_METHODS="[FS, cwrap, setValue, writeAsciiToMemory]"
-s EXPORTED_FUNCTIONS="[_main]"
-s USE_SDL=2 # use SDL2
-s USE_PTHREADS=1 # enable pthreads support
-s PROXY_TO_PTHREAD=1 # detach main() from browser/UI main thread
-s INITIAL_MEMORY=33554432 # 33554432 bytes = 32 MB
)
emcc "${ARGS[@]}"
mac设置环境变量可以简单用
echo ‘source “/xxxx/emsdk/emsdk_env.sh”’ >> $HOME/.zprofile
新版本的emcc 2.0.29 线程支持(设置PROXY_TO_PTHREAD)不会生成_proxy_main方法,会报emcc: error: undefined exported symbol: "_proxy_main"错误。但是可以在调用的时候使用emscripten_proxy_main。
上面编译出来的ffmpeg没有x264编码器,所以生成的视频是mpeg4 (Simple Profile)格式,浏览器不能直接放。
所以我们需要把libx264和ffmpeg一起编译。