当前位置: 首页 > 工具软件 > web-flash > 使用案例 >

web-h264流媒体验证方案

南宫喜
2023-12-01

背景:
当下web端流媒体并没有权威的标准方案,在html5之前只能采用flash、vlc等插件方式实现,而此类插件面临跨平台的问题,且出于安全性方面考虑目前各浏览器逐渐放弃对此类插件的支持,html5引入了video标签使浏览器在一定程度上对视频实现原生的支持,但是目前该标签具体支持的媒体类型依赖于浏览器的实现,并且对流媒体的支持只有渐进式下载的hls方式,延迟高。

解决方案:
本方案基本思想是自己一套简单的实时流机制。
流程:
Camera—>gstreamer—>h264—>websocket—>web-javascript(ffmpeg)—>canvas
本方案的关键在于web端js解码h264,利用Emscripten工具把ffmpeg交叉编译为webassemly模块。

具体实现:
1.Websocket server(通过gstreamer实现camera采集并编码h264,通过qt实现websocket服务功能)

Gstreamer 管道:

rkcamsrc device=/dev/video1 ! video/x-raw,format=NV12,width=1920,height=1080, \ framerate=20/1 ! videorate ! mpph264enc ! video/x-h264,stream-format=byte-stream, \ alignment=au ! appsink name=appsink sync=true

QT WebsocketServer:
QT为支持websocket提供了QWebsocketServer和QWebsocket两个类,其使用方法跟QTcpServer/QTcpSocket完全一致,由server类侦听,并使用连接得到的socket类与客户端通信。
具体代码见videoStreamer.tar

2.ffmpeg编译webassembly:

  1. 安装emscripten :
    wget https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz
    tar -xvf emsdk-portable.tar.gz
    cd emsdk-portable

./emsdk update
./emsdk install latest

以下两步每次新进入终端都需要执行:
./emsdk activate latest
source ./emsdk_env.sh

可以通过emcc –v查看是否安装成功。

2)下载最新ffmpeg源码,并通过以下方式编译:
修改configure第5872行 增加以下两行:
disable gethrtime
disable sched_getaffinity

./configure --cc=“emcc” --cxx=“em++” --ar=“emar” --prefix=$(pwd)/…/dist --enable-cross-compile --target-os=none --arch=x86_32 --cpu=generic
–enable-gpl --enable-version3 --disable-avdevice --disable-avformat --disable-postproc --disable-avfilter
–disable-programs --disable-everything --enable-decoder=h264
–disable-ffplay --disable-ffprobe --disable-doc --disable-devices --disable-network
–disable-hwaccels --disable-bsfs --disable-debug --disable-protocols --disable-indevs --disable-outdevs --enable-parser=h264

make
make install

另外可以编译一套pc的版本,以便于在pc端做逻辑验证:
./configure --prefix=$(pwd)/install --disable-x86asm
–enable-gpl --enable-version3 --disable-avdevice --disable-avformat --disable-postproc --disable-avfilter
–disable-programs --enable-decoder=hevc --enable-decoder=h264 \

make
make install

以上ffmpeg库可参见ffmpeg-4.1.tar,其中包含了分别编译成x86和Emscripten的脚本build_xx.sh

编译并生成wasm模块及胶着代码。
emcc ffmpegdecoder.c -o ffmpegdecoder.o -I…/dist/include/ -L…/dist/lib -lavcodec -lswscale -lavutil -lswresample -lm -lpthread
emar rcs libffmpegdecoder.a ffmpegdecoder.o

其中ffmpegdecoder.c是为了方便js调用而包装的一个解码接口,接收h264字节数组,返回rgba字节数组

具体文件见web_ffmpeg.tar,其中包括一个ffmepg_test项目,采用与web一致的方案处理websocket+解码逻辑并绘制qt窗口,可用来验证方案逻辑。

补充: 该压缩包内另含ffmpegutils.c文件用于实现从一张大幅rgba图像中切割并缩放任意矩形rgba数据,可编译成单独的webassebly模块。

目录结构及作用说明:
web_ffmpeg
–ffmpegdecoder.c ffmpeg针对h264的解码封装,包含了yuv转rgb步骤。
–ffmpegutils.c 实现rgba的图像切割+缩放功能。
–build_env.sh 建立emcc环境脚本,需要修改以指定实际的工具路径
–build_ffmpegdecoder.sh 构建ffmpegdecoder.c及ffmpegutils.c的emcc静态库,需要修改指定实际emcc版本的ffmpeg静态库路径。
– build_js.sh 使用ffmpegdecoder.c及ffmpegutils.c的静态库构建相应的wasm及辅助js文件,其中可通过修改-s WASM=1为-s WASM=0控制生成纯js文件。
3.前端
前端封装一个ffmpeg.js接收html的canvas对象,内部对接websocket接收h264流,调用ffmpeg的webassembly模块实现解码,并把解码结果画在canvas上。

另有test_zx.html 演示如果使用该ffmpeg.js

具体文件在web_ffmpeg.tar的static/video、目录下。

附件清单:
web_ffmpeg.tar
ffmpeg-4.1.tar
videoStreamer.tar

方案缺陷:
1.Js软解码h264终究面临性能问题,解码效果与浏览器所在设备性能有直接关系。
2.目前在windows版chrome浏览器发现在vue框架下的两个界面间跳转会有大块内存泄漏风险,在linux版火狐浏览器下暂未发现,但可能由于虚拟机性能原因,在linux版火狐下画面不流畅。(h264流为20帧)。

 类似资料: