本文转载自微信公众号《微信大学前端技术》,作者翁家瑞。转载本文请联系微一大学前端技术公众号。前言前几天偶然看到一篇关于webassembly的文章,对这门技术还是很感兴趣的。在了解一些相关知识的基础上,看能不能稍微实践一下。什么是网络?WebAssembly(wasm)是一种可移植、体积小、加载速度快且与Web兼容的新格式。用C、C++等语言编写的模块,可以通过编译器创建wasm格式的文件。这个模块以二进制形式发送给浏览器,然后js可以通过wasm调用其中的方法函数。WebAssembly的优点网上应该有很多相关介绍。WebAssembly的优点是性能好,运行速度比Js快很多。对于计算量大、性能要求高的应用场景,如图像/视频解码、图像处理、3D/WebVR/AR等,优势明显。我们可以直接将已有的用C、C++等语言编写的库编译成WebAssembly运行在浏览器上,并且可以作为库被JavaScript引用。也就是说我们可以把很多后端的工作转移到前端,减轻服务器的压力。WebAssembly最简单的做法叫我们写最简单的c文件intadd(inta,intb){returna+b;}然后安装Emscripten编译器Emscripten安装指南emcctest.c-Os-sWASM=1-sSIDE_MODULE=1-otest.wasm然后我们就可以在html中引入并使用了结果=>{constadd=results.instance.exports.addconsole.log(add(11,33))});这时我们可以在控制台看到相应的打印日志,成功调用了我们编译的代码。正式开始既然知道了如何快速调用一些成熟的C、C++类库,我们离在线视频剪辑的预期目标又近了一步。最终的demo演示可能会因为录制操作的电脑cpu不够好,所以时间会比较长,不过总体效果还是可以在demo仓库地址看到(https://github.com/Dseekers/clip-video-by-webassembly)FFmpeg在这之前,你得稍微了解一下什么是FFmpeg?以下是基于维基百科目录的解释:FFmpeg是一款开源免费软件,可以运行多种格式音视频的录制、转换、流功能[1],其中包含libavcodec——一个用于音视频编解码库在几个项目中,还有libavformat——一个音频和视频格式转换库。简单来说,这是一款用C语言编写的视频处理软件,使用方法也相当简单。我这次主要是把需要用到的命令调出来。如果您可能会使用其他命令,您可以按照他的说明进行操作。查看官方文档,也可以看看阮一峰的文章(https://www.ruanyifeng.com/blog/2020/01/ffmpeg.html)ffmpeg-ss[start]-i[input]-to[end]-ccopy[output]start是开始时间end是结束时间input是要操作的视频源文件output是输出文件的位置名这行代码是我们需要获取相关的视频编辑命令FFmpegwasm通过Emscripten将ffmpeg编译成wasm环境问题比较多,所以我们直接使用这个成熟的库https://github.com/ffmpegwasm/ffmpeg.wasm直接使用网上编译好的CDN资源为了方便本地调试,我下载了所有相关资源,一共4个资源文件ffmpeg.min.jsffmpeg-core.jsffmpeg-core.wasmffmpeg-core.worker.js我们在使用的时候只需要导入第一个文件即可,其他文件会使用fetch方法调用时拉取资源的最小函数,实现前置函数实现:我们需要imp在本地添加一个node服务,因为如果server端没有设置responseheader,会出现ffmpeg的模块,会报错SharedArrayBufferisnotdefined。这是因为系统中存在安全漏洞。浏览器默认禁用此api。要启用它,您需要在标头上设置Cross-Origin-Opener-Policy:same-originCross-Origin-Embedder-Policy:require-corp我们启动一个简单的节点服务constKoa=require('koa');constpath=require('path')constfs=require('fs')constrouter=require('koa-router')();conststatic=require('koa-static')conststaticPath='./static'constapp=newKoa();app.use(static(path.join(__dirname,staticPath)))//logrequestURL:app.use(async(ctx,next)=>{console.log(`处理${ctx.request.method}${ctx.request.url}...`);ctx.set('Cross-Origin-Opener-Policy','same-origin')ctx.set('Cross-Origin-Embedder-Policy','require-corp')awaitnext();});router.get('/',async(ctx,next)=>{ctx.response.body='
