基于webassembly的前端视频编辑器(未写完)

基于webassembly的前端视频编辑器

(这是2020年8月5日写好的草稿,2021年9月9日才想起来还有这个草稿没发,今天登上网站才发现有人在2021年6月给我发了私信问assembly相关问题_(:з」∠)_ 现在都过去三个月了,实在抱歉呐没帮上忙。现在我从事的工作与编程不相关,所以现在对webassembly也生疏了,以后可能也帮不上各位后来者什么忙了╮(╯_╰)╭ )

在阅读这篇文章前,建议先看webassembly快速应用入门

我6月初做完了标题所示的毕业设计,特此来分享一下。此前做这个玩意儿是真的头疼,主要原因就是资料的查找。对于刚入门前端以及C++的我来说,看懂这些资料耗时长,但deadline又快到头了,简直绝望。

先说明一下该文章的面向人群:
1、入门webassembly与ffmpeg。
2、不求甚解,希望快速掌握webassemly简单应用。(如果你像我一样deadline到头了)

该项目实现的视频编辑功能:
1、两个编码格式相同的视频合并。
2、从一个视频提取一段视频。(分割)
3、截图。

本文的参考资料
关于web assembly的:
1、李银城.wasm + ffmpeg实现前端截取视频帧功能

(该文章可以帮你入门webassembly以及实现截图功能,但在编译ffmpeg上你可能不能只看这篇文章,我已经做了一个详细的编译ffmpeg的教程总结

2、C/C++面向WebAssembly编程

关于FFmpeg的:
2、雷霄骅.ffmpeg 从内存中读取数据(或将数据输出到内存)

(该篇文章可以教你如何使用ffmpeg处理内存中的视频数据,雷神其他ffmpeg教程也很有价值,如果你有志于学习视频处理开发的话)

分下面几部分讲述:

1、webassembly环境的安装。
2、使用Emscripten编译ffmpeg库
3、编写视频编辑的C代码
4、将C代码和ffmpeg编译为wasm文件。
5、编写JavaScript调用wasm模块。

第一部分:
webassembly环境的安装。
你可以参考安装Emscripten进行安装。

在linux中主要步骤如下:
1、安装并更新git、cmake、GCC、python2.7并确保git、cmake、python2.7可用。
2、安装emsdk:
$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest
$ source ./emsdk_env.sh

执行完以上步骤后,执行emcc -v 查看是否正确反馈。

注意:你新打开的终端窗口是不能执行emcc的,每次需要进行如下命令激活:

cd emsdk
./emsdk activate latest
source ./emsdk_env.sh

下面测试emcc,尝试使用emcc命令编译C代码,并将编译结果在浏览器上运行。

1、新建一个txt。
写入如下

#include <stdio.h>
int main() {
  printf("Hello, world!\n");
}

修改txt后缀为.c,例如:hello.c

2、打开一个终端窗口,激活emcc命令。再从这个终端窗口进入到保存你新建的C文件的文件夹。
在终端中执行如下命令

emcc hello.c -s WASM=1 -o hello.html

成功后你会发现文件夹下多出了三个文件:
hello.wasm、hello.html、hello.js
你可以直接使用edge浏览器打开 hello.html。
若成功,你将看到浏览器页面显示hello。

如果你使用其他浏览器,可能因为同源策略问题而无法显示hello字样。(也就是浏览器获取不到hello.wasm)因此,初学者我建议实用edge浏览器,它比较宽松。

第二部分:
使用Emscripten编译ffmpeg库。
详细教程在下方链接里
Emscripten编译ffmpeg库

第三部分
编写视频编辑的C代码

如果你已经详细阅读了webassembly快速应用入门,那么你应该已经掌握了实现前端视频编辑器最基础最相关的两个问题的解答——

JavaScript如何调用wasm模块中对应的C/C++函数?
①Module对象方法调用
②cwrap
JavaScript与WASM之间如何进行通信?
①cwrap
②内存

接下来以 “视频提取功能”为例

第一步:

规划传递的数据以及数据传递的方式并确定接口函数。

在这里插入图片描述(注:上图只是为了方便初学者学习而画的示意图,真实的结构并不如上图所示)

如上图所示:
1、本地视频通过相关的API保存到JavaScript的数组中,Js再将数组保存到共享内存中。完成视频数据的导入。

2、Js通过Cwrap封装过的函数接口向wasm告知视频数据所在内存位置,wasm读取并处理视频数据。

3、wasm将处理完毕的数据保存到Data文件中暂时保存。

4、从Data文件中读取处理后的视频数据到共享内存。

5、wasm通过函数接口向js传递视频数据在内存的位置。

6、Js根据函数接口返回的内存位置读取输出视频数据,并保存到本地。

第二步:

细化上述过程

先看在js中的数据传递与逻辑:
在这里插入图片描述如上图所示,在Cwrap()左侧全部发生在js内:
1、操作参数(例如视频分割时间点)由用户填写在网页面上,由用户通过输入框选择本地视频文件,两者都会暂时保存在页面节点(标签)上。

2、用户点击按钮,触发加载事件,将会把操作参数从DOM节点中读取到JavaScript中的变量。同时,将视频保存到Arraybuffer中,依照Array buffer的长度申请内存空间,并调用相应的函数将ArrayBuffer 中的视频数据拷贝到共享内存中。以上完成了js中视频处理的前期准备工作。

3、Cwrap函数封装好了wasm中对应的功能调用函数,调用Cwrap封装的函数传递包含操作参数和视频在内存中的位置offset和长度length

4、接收的返回值(保存处理后视频数据的内存offset和length),根据返回的offset和length,从内存中读取数据保存到ArrayBuffer中。

5、调用“下载模块”下载ArrayBuffer中的视频数据到本地。

接着规划好wasm中的数据传递和处理逻辑

在这里插入图片描述(上图的数据处理由C语言编写)

如上图所示,Cwrap()封装的方法进行了如下步骤:
1、获取操作参数与offset、length,传递给对应的视频编辑函数。
2、视频编辑模块根据offset、length从共享内存中读取输入视频数据。
3、将处理好的视频保存到模拟文件系统内
4、调用“结果导出模块”,读取模拟文件系统内的输出视频文件,保存到共享内存,并将该片内存的offset 和length保存到结构体指针中。
5、通过封装的方法返回该结构体指针。

综上,实际上,调用wasm函数时传递的数值只有两个
1、视频数据在内存的位置
2、视频数据的长度

wasm函数返回JavaScript的数据应包含
1、输出视频数据在内存的位置
2、输出视频数据的长度

第三步:

正式编写视频处理函数:

这里只给出大致的处理函数安排。

webassembly快速应用入门中的第三个问题的回答,我们可以知道——

假设wasm中有一名为A的函数,在Javascript中使用cwrap对A进行封装,则可像调用JavaScript定义的函数那样,调用wasm的A函数。
一次函数调用可以传递多个值给wasm的函数,但wasm函数只返回一个值。

那么如何让wasm函数同时返回视频所在内存位置和视频大小呢?

方法:处理后的视频所在的内存位置以及视频大小,两者的数值类型和数值类型的大小是已知的,例如视频内存位置用8比特,而视频大小32比特存储,将二者保存到一片内存中,wasm函数向JavaScript返回这片内存的位置,在JavaScript中,读取该片数据,按顺序,按比特读取出内存位置和视频大小。再按照读出的数据,在内存中读出处理后的视频。

为完成以上数据传递,在C函数中,应设计以下数据结构。

typedef struct{
uint32_t buffLength;
uint8_t *buff;
}Video_Buffer;

Video_Buffer结构中,用4字节保存视频的长度,一字节保存视频所在的位置。

wasm函数向js返回这个结构的内存地址即可。

后面的。。。。写不下去了,我关于这个的论文正文都写了2w字,让我在csdn在重新组织语言写一遍真是太难了。
我把代码共享出来,看你们能不能看懂吧。如果看不明白,可以先看 李银城.wasm + ffmpeg实现前端截取视频帧功能这一篇文章,再看看我写的代码_(:з」∠)_
(https://blog.csdn.net/weixin_42651102/article/details/107823202?utm_source=app&app_version=4.14.0&code=app_1562916241&uLinkId=usr1mkqgl919blen)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值