应该首先从官方网站获取知识
webassembly知识储备或许会涵盖“编译原理”,Rust,v8开发,
WebAssembly或称wasm是一个实验性的低端编程语言,应用于浏览器内的客户端。WebAssembly是便携式的抽象语法树,被设计来提供比JavaScript更快速的编译及运行。WebAssembly将让开发者能运用自己熟悉的编程语言编译,再藉虚拟机引擎在浏览器内运行。 —-维基百科
曾几何时,有“一切可以由js实现的,终将用js实现”,而webassembly技术为编译型语言(c/c++,jave,c#等)抢夺浏览器战场打开了传送门。
优势:
- 运行效率高 如应用于文件上传中的扫描注1
- 保密性好 见Google reCAPTCHA 另航妹博客:浅谈前端代码加密
为什么wasm效率比js高?因为wasm是二进制指令格式,比执行js代码天然地节省解释和JIT的开销,但效率提高多少要看计算的复杂程度,简单场景或不相上下
课外:为了提高浏览器性能,曾出现过从 NaCl、PNaCl 到 ASM.js,这些技术作为wasm的前辈,有以下特点————(于航《WebAssembly入门》)
- 源码中都使用了类型明确的变量;
- 应用都拥有独立的运行时环境,并且与原有的 JavaScript 运行时环境分离;
- 支持将原有的 C/C++ 应用通过某种方式转换到基于这些技术的实现,并可以直接运行在 Web 浏览器中。
现状是,四大厂(Mozilla,Google,Microsoft,Apple)共同倾力开发, WebAssembly 技术已成为 W3C 的标准, 其MVP版本(Minimum Viable Product)被主流浏览器支持
工具链Emscripten,Rust, AssemblyScript
In case of conflict, consider users over authors over implementors over specifiers over theoretical purity.
helloworld.wasm
准备一个新的开发环境:
启动一个ubuntu的docker
1 | docker pull ubuntu |
上面的语句映射的是docker中的/var/labdocker_home和宿主的/var/lib/docker/volumes/labdocker_home/_data wtf???
给‘空’的ubuntu安装必要工具
1 | apt-get update |
编译工具链依赖
1 | apt-get install -y cmake python3.8 |
安装emsdk
1 | git clone https://github.com/emscripten-core/emsdk.git |
You always have to source ./emsdk_env.sh first in a new terminal session
输入emcc -v查看信息
看起来比较正常,说明工具安装成功

另,其实安装emsdk不是必须的,docker hub中有现成的
1 | docker pull emscripten/emsdk |
创建一个c项目
1 | mkdir /home/Workspace/hello |
回忆起c的hello world
1 | #include<stdio.h> |
走你
1 | emcc hello.c -s WASM=1 -o hello.html |
- 参数-s WASM=1 要求生成.wasm否则编译成asm.js
- -o hello.html Emscripten 生成一个我们所写程序的HTML页面,并带有 wasm 和 JavaScript 文件
编译生成hello.wasm hello.js hello.html 可以用emrun运行这个html(直接用浏览器打开会认为读取file://文件违反policy) 因为docker没有映射端口,拷出来用http-server运行,是这样婶的:
FFmpeg.js 的实现
原文:Build FFmpeg WebAssembly version (= ffmpeg.wasm) 此链接国内网络或无法访问,可参考国内博客的类似文章,keyword:”webassemby” + “ffmpeg”
关于ffmpeg,video和视频流那篇曾用其进行视频的转码和输出流。
FFmpeg 是一个开放源代码的自由软件,可以运行音频和视频多种格式的录影、转换、流功能,包含了libavcodec(用于多个项目中音频和视频的解码器库),以及libavformat(音频与视频格式转换库)。————维基百科
clone FFmpeg 源码
1 | git clone https://github.com/FFmpeg/FFmpeg |
源码根路径INSTALL.md为构建/安装说明
1 | ./configure |
在windows上开发使用cygwin集成linux开发环境(本不应绕此远路),运行cygwin.setup安装程序安装以下库
1 | gcc-core |
执行configure加以下参数
1 | bash ./configure --enable-cross-compile --disable-x86asm |
configure大约需要执行十几分钟(或更久,取决于cpu加网速)
make issue: ./libavutil/mem.h:342:1: warning: ‘alloc_size’ attribute ignored on a function returning ‘int’ [-Wattributes]
342 | av_alloc_size(2, 3) int av_reallocp_array(void ptr, size_t nmemb, size_t size);
| ^~~~~
make: ** [ffbuild/common.mak:60: libavformat/mov_esds.o] Interrupt
旧版本函数参数不一致导致的问题,已被修复,见[FFmpeg-devel] avutil/mem: Fix invalid use of av_alloc_size
——————two weeks later————————
1 | git clone https://github.com/FFmpeg/FFmpeg |
测试FFmpeg可以尝试在终端使用媒体编辑功能
1 | ffmpeg --help |
我们目的是要生成.wasm放到浏览器中,这里用到Emscripten
Emscripten compiles C and C++ to WebAssembly using LLVM and Binaryen. Emscripten output can run on the Web, in Node.js, and in wasm runtimes. ——— 《Emscripten ReadMe》
回到make这步的输出项中:
这个泛着绿光的ffmpeg就是Binaryen(二进制文件)
LLVM(low level virtual machine)不限于字面意思的编译环境
关于emcc
- Emcc 使用 Clang 和 LLVM 编译生成 Wasm或者asm.js
- Emscripten SDK (emsdk) 配置 .emscriten, 用于管理多份SDK和工具,指定当前正在使用的编译代码(Active Tool/SDK)。
工具链依赖
1 | apt-get install -y cmake python3.8 |
安装emsdk
1 | git clone https://github.com/emscripten-core/emsdk.git |
You always have to source ./emsdk_env.sh first in a new terminal session
输入emcc -v查看信息
看起来比较正常,说明工具安装成功

另,其实安装emsdk不是必须的,docker hub中有现成的
1 | docker pull emscripten/emsdk |
将FFmpeg源码编译成LLVM二进制码, 相比之前的configure && make这里不仅要使用emconfigure 命令,而且要设置下述的若干参数,于是做一个build .sh:
1 | #!/bin/bash -x |
EMCC_DEBUG
设置EMCC_DEBUG变量使用调试模式编译wasm
1 | EMCC_DEBUG=1 emcc dip.cc |
issues expected magic word 00 61 73 6d, found
获取的wasm模块的MIME type不是application/wasm
关于wasm的调用
WebAssembly还没有和 \
