- Notifications
You must be signed in to change notification settings - Fork0
1008610010/decoder_wasm
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
借助于WebAssembly(简称Wasm)技术,实现在浏览器端调用ffmpeg接口完成H.265码流到YUV数据的解码。
总体流程如下:
按照官网的定义,WebAssembly (wasm) 是一个可移植、体积小、加载快并且兼容 Web 的全新格式。通过wasm,可以在浏览器里执行原生代码(例如C、C++)。
目前,wasm技术已经得到主流浏览器的广泛支持(数据来源Can I Use)。
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。
我们代码里主要使用FFmpeg来做解码(decode)。为了减小体积,最终编译生成的wasm里包含的是裁剪过的FFmpeg,主要包含以下几个库:
- libavcodec: 编解码(最重要的库)
- libavutil: 工具库(大部分库都需要这个库的支持)
- libswscale: 视频像素数据格式转换
编译生成的wasm文件对外提供四个接口:
- openDecoder:初始化解码器;
- decodeData:解码传入的H.265码流数据;
- flushDecoder:清空缓存数据;
- closeDecoder:关闭解码器;
解码过程中使用到的FFmpeg API及解码流程如下图所示:
最终的编译结果是两个文件,一个是包含ffmpeg库的wasm文件,另一个是胶水代码(js文件)。页面里引用js文件时,胶水代码会加载wasm。
Javascript与WASM的数据交互:
// 发送:varcacheBuffer=Module._malloc(data.length);Module.HEAPU8.set(data,cacheBuffer);varret=Module._decodeData(cacheBuffer,data.length,pts);// 接收:varvideoSize=0;varvideoCallback=Module.addFunction(function(addr_y,addr_u,addr_v,stride_y,stride_u,stride_v,width,height,pts){console.log("[%d]In video callback, size = %d * %d, pts = %d",++videoSize,width,height,pts)letout_y=HEAPU8.subarray(addr_y,addr_y+stride_y*height)letout_u=HEAPU8.subarray(addr_u,addr_u+(stride_u*height)/2)letout_v=HEAPU8.subarray(addr_v,addr_v+(stride_v*height)/2)letbuf_y=newUint8Array(out_y)letbuf_u=newUint8Array(out_u)letbuf_v=newUint8Array(out_v)letdata=newUint8Array(buf_y.length+buf_u.length+buf_v.length)data.set(buf_y,0)data.set(buf_u,buf_y.length)data.set(buf_v,buf_y.length+buf_u.length)varobj={data:data, width, height}displayVideoFrame(obj);});varcodecType=1;// 0 - H.264, 1 - H.265varret=Module._openDecoder(codecType,videoCallback,LOG_LEVEL_WASM)// 需要把回调通过openDecoder方法传入C层,在C层调用。
安装步骤可参考其官方文档,目前支持 Windows, MacOS, Linux。
mkdir goldvideocd goldvideogit clone https://git.ffmpeg.org/ffmpeg.gitcd ffmpeggit checkout -b 4.1 origin/release/4.1
这里切到了4.1分支。
保证FFmpeg目录和代码目录平级。
git clone http://github.com/goldvideo/decoder_wasm.gitcd decoder_wasm目录结构:├─goldvideo│ ├─ffmpeg│ ├─decoder_wasm进入代码目录,根据需要,以下命令三选一执行:
./build_decoder_264.sh //支持解码 H.264./build_decoder_265.sh //支持解码 H.265./build_decoder_264_265.sh //支持解码 H.264 和 H.265
H5使用Canvas来绘图,但是默认的2d模式只能绘制RGB格式,使用FFmpeg解码出来的视频数据是YUV格式,想要渲染出来需要进行颜色空间转换,可以使用FFmpeg的libswscale模块进行转换。为了提升性能,这里使用了WebGL来硬件加速,主要参考了这个项目,做了一些修改:https://github.com/p4prasoon/YUV-Webgl-Video-Player
npm installnpm start
http://localhost:3000/test/main.htmlAbout
借助于WebAssembly技术,基于ffmpeg的H.265解码器。
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Languages
- C96.1%
- JavaScript1.8%
- C++1.3%
- Shell0.3%
- Objective-C0.2%
- Makefile0.2%
- HTML0.1%