wasm + ffmpeg实现前端截取视频帧功能

有没有那么一种可能,在前端页面处理音视频?例如用户选择一个视频,然后支持他设置视频的任意一帧作为封面,就不用把整一个视频上传到后端处理了。经过笔者的一番摸索,基本实现了这个功能,一个完整的demo:ffmpeg wasm截取视频帧功能

支持mp4/mov/mkv/avi等文件。基本的思想是这样的:

使用一个file input让用户选择一个视频文件,然后读取为ArrayBuffer,传给ffmpeg.wasm处理,处理完之后,输出rgb数据画到canvas上或者是转成base64当做img标签的src属性就形成图片了。(Canvas可以直接把video dom当作drawImage的对象进而得到视频帧,不过video能播放的格式比较少,本文重点讨论ffmpeg方案的实现,因为ffmpeg还可做其它的事情,这只是一个例子。)

这里有一个问题,为什么要借助ffmpeg呢,而不直接用JS写?因为多媒体处理的C库比较成熟,ffmpeg就是其中一个,还是开源的,而wasm刚好可以把它转化格式,在网页上使用,多媒体处理相关的JS库比较少,自己写一个多路解复用(demux)和解码视频的复杂度可想而知,JS直接编解码也会比较耗时。所以有现成的先用现成的。

第1步是编译(如果你对编译过程不感兴趣的话,可以直接跳到第2步)

1. 编译ffmpeg为wasm版本

我一开始以为难度会很大,后来发现并没有那么大,因为有一个videoconverter.js已经转过了(它是一个借助ffmpeg在网页实现音视频转码的),关键在于把一些没用的特性在configure的时候给disable掉,不然编译的时候会报语法错误。这里使用的是emsdk转的wasm,emsdk的安装方法在它的安装教程已经说得很明白,主要是使用脚本判定系统下载不同编译好的文件。下载好之后就会有几个可执行文件,包括emcc、emc++、emar等命令,emcc是C的编译器,emc++是C++的编译器,而emar是用于把不同的.o库文件打包成一个.a文件的。

先要在ffmpeg的官网下载源码。

(1)configure

解压进入目录,然后执行以下命令:

emconfigure ./configure --cc="emcc" --enable-cross-compile --target-os=none --arch=x86_32 --cpu=generic \
    --disable-ffplay --disable-ffprobe --disable-asm --disable-doc --disable-devices --disable-pthreads --disable-w32threads --disable-network \
    --disable-hwaccels --disable-parsers --disable-bsfs --disable-debug --disable-protocols --disable-indevs --disable-outdevs --enable-protocol=file

通常configure的作用是生成Makefile——configure阶段确认一些编译的环境和参数,然后生成编译命令放到Makefile里面。

而前面的emconfigure的主要作用是把编译器指定为emcc,但只是这样是不够的,因为ffmpeg里面有一些子模块,并不能彻底地把所有的编译器都指定为emcc,好在ffmpeg的configure可以通过--cc的参数指定自定义的编译器,在Mac上C编译器一般是使用/usr/bin/clang,这里指定为emcc。

后面的disable是把一

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值