浏览器前端转码实验


WebAssembly 看起来很美,号称可以达到 native code 一半的运行效率。但是在目前的测试下来看,想在浏览器前端转码还是一个遥远的梦想。

前段时间因为入职哔哩哔哩,奉命开发基于 electron 的上传客户端(后来被产品砍了),研究了一下各种切图方案的优缺点。因为 electron 基于 nodejs 运行,要达到这个需求只需要用对应平台编译好的 ffmpeg 二进制文件即可。不过为了 portability,还是研究了一下在浏览器内通过 WebAssembly, aka wasm 跑编译的 ffmpeg 的运行情况。

将 C/C++ 代码编译到 wasm 需要使用到 emscripten,然而使用普通版本的 ffmpeg 会毫不意外地出错。现有的将 ffmpeg port 到 emscripten 的项目有两个,其中一个是 ffmpeg.js,但是这个项目是为了 asm.js 设计的(也是一个在浏览器里执行类汇编代码的项目,理论上比 wasm 要慢),无法直接编译到 wasm。因此使用这个 fork: https://github.com/picitujeromanov/ffmpeg.js

编译过程差不多就是先用 clang 编译到 LLVM byte code,再通过 emscripten 编译到 WebAssembly 二进制文件,作为静态资源给浏览器 js 调用。如果懒得编译,这里也有一个现成的。调用方式就和普通的 Worker 一样,不再赘述。

这里是一个关于 asm.jswasm 执行效率的对比(这仅仅是切图,左 asm.js,右 wasm):

结论:浏览器内转码可以实现,但是受限于性能,无法达到正常使用的程度。