Chrome & Firefox很久以前就不在支持安装插件,这篇文章就是为了解决不装插件也能播放视频的难题。
大概的流程:利用websocket传输未解码数据,送入ffmpeg库解码,回调至上层利用canvas出图。
【一】websocket usage
封装一个websocket对象,方便调用。
that.wsUrl 例如 “ws://localhost:8080”;(根据个人情况自行创建)
【二】FFmpeg解码库
(1)安装tools : emscripten (Linux 系统安装Emscripten)
emscripten 的安装可以根据官方文档(Download and install
但由于依赖较多,安装起来比较麻烦,更方便的方法是安装 SDK。
按照下面的步骤操作。
注意:如果Linux系统是32位,对应的emscripten也需要装32位,如果系统是64位则对应要装64位
安装过程可能会遇到很多问题,需要耐心解决。
安装完成后,运行emcc -v,会提示版本信息等,例如下图,无误之后,也编译测试
1、可进入emscripten/incoming/执行
生成hello_world.js即安装成功
2、或在当前目录下创建一个hello.cc
执行emcc http://hello.cc -o hello.js 生成hello.js ,在浏览器上运行,打印Hello World!,即为安装成功。
(2)编译ffmpeg静态库
emscripten安装成之后,生成交叉编译器emcc,即可编译ffmpeg静态库
下载ffmpeg源码,例如:
配置与编译:(仅保留需要用到的功能模块,其余屏蔽)
我当前采用ffmpeg-4.0.2,其余版本配置有问题可以使用 ./configure --help查看配置帮助。
编译成功后,会在当前目录的dist目录生成lib,lib下生成libavcodec.a,libavutil.a,libswscale.a即为我们需要用到的ffmpeg静态库。
(3)编译ffmpeg.js+ffmpeg.wasm库
配置:
其中一下几个API ,是FFMpegContext.c中定义的函数,为ffmpeg初始化&销毁,解码函数,音频函数等
配置之后可进行编译:
编译成功后,生成ffmpeg.js ffmpeg.wasm ffmpeg.js.mem三个文件,只要在html文件中包含ffmpeg.js就可以正常调用API
library.js 的作用:调用ffmpeg静态库中的函数,(C语言调用JS中的函数)例如:
在C文件中,调用avcodec_register_all_js即可正常调用ffmpeg静态解码库中的avcodec_register_all函数
(4)js调用ffmpeg.js中的函数(JS中调用C语言中的函数)
使用Module.cwrap,将API导出,让C语言中的函数可以在JS中调用,此时FFMpegContextCreate 等均可在js文件中调用,上面讲到websocket接收到未解码数据后,触发onmessage函数,connect_http_read,调用Decode,数据解码后,返回解码数据,回调到上传出图。
(5)canvas出图
解码数据回调,一般是传递数据首地址,可读取。
例如(rgb出图)
imgData即为解码之后的rgb数据,将数据传到canvas显示即为一帧的图像。
至此,无插件解码H264&H265播放视频的流程基本讲完了,每个人写的框架不同,但是使用的技术大多相同,websocket ,emscripten,JS与C语言中的API相互调用等,希望可以对同样在研究这项技术的研发人员有所帮助。
瓶颈:ffmpeg编译成js(wasm二进制库)之后,H265的解码效率是远不如C的,能解码720P*每秒25帧*比特率4096已经非常勉强了。如有人攻破这个瓶颈,欢迎交流。
Best wishes. |