从0到1实现Web端H.265播放器:视频解码篇

本文介绍了从0到1实现Web端H.265播放器的视频解码过程,包括架构设计、FFmpeg编译成WASM包的步骤、JS如何调用解码方法。通过实例展示了解码1080p H.265视频的内存和CPU占用情况,并探讨了解码器优化的可能性。文章提供了详细的实操指南,帮助读者理解Web端H.265视频解码技术。
摘要由CSDN通过智能技术生成

这篇文章的目的是?

H.265播放器(Videox.js)在淘宝直播落地已经近两年了。之前的架构设计主要针对的是直播的场景,播放m3u8和flv的直播流,由于直播落地的场景是B端主播中控台,使用场景是可以预览画面即可,故而对帧率要求不高。但是今年的短视频业务面向的多是C端用户,需要在Web场景下播放1080P/720P的H.265视频,那么必须满足短视频主流分辨率+码率流畅播放的要求。同时业务上还要支持多视频格式如(mp4/fmp4)的需求,所以综合评估后对原有架构进行了升级。既然有了升级自然就需要沉淀下经验。按照一贯套路我就来水一篇文章了。当然这两年内业界也有大量H.265播放器的实践落地,我写这篇文章也是借这次重构的机会分享自己的一些经验,希望能帮助各位少踩些坑。

视频演示

如下将演示新版播放器播放 1分钟1080p/25fps/H.265 MP4视频,具体视频参数如下:

  1. 预加载1000000帧(即整个视频),完全解码不播放的内存占用、CPU占用、解码间隔时间

因为整个解码过程没有进行播放,所以解码间隔=单帧解码耗时。

从上面视频能看出来,一个几十M的文件完全解码能达到4.6G的内存占用,CPU占用高达300以上(4核)。当然,这是完全不做限制,火力全开解码。但也能得出结论:无干扰情况下平均解码一帧1080p仅需要13ms(基于mbp2015版)。

旧版直播播放器解码720p需要26ms(基于mbp2015版),而新版播放器播1080p目前的13ms还不是极限,后续将继续探索优化空间。

  1. 预加载10帧并解码,后续边播边解的相关数据

演示1太过极端不符合日常使用的场景,但因为极限情况平均解码只需要13ms,而视频帧率是25(即间隔40ms),所以可以隔一段时间喂几帧到解码器,这样平衡了播放和解码的速率之后,CPU占用降到120左右、内存占用降低到了300M。同时还能流畅播放。不过播放策略有很多种,各位有更好的方案也欢迎和我交流。

架构设计

整体架构设计

上图所示为新播放器基本骨架,包含了主要模块。模块间互相独立,各自接收通用协议的参数。比如Loader传递给Demuxer的数据为ArrayBuffer,经Demuxer统一解封装成Packet格式Buffer数据(Annex-B)喂给Renderer。上图用MP4举例(HVCC为H.265码流格式之一),替换成flv、ts格式也是遵循这个流程。Renderer负责decoder调度,音画同步、音视频播放等,可以说是播放器最核心的模块。UI View则主要用来绘制播放器控件UI,如进度条等。本文不打算详细介绍每个功能,仅对decoder做细节解构,其它有关联的模块仅简单说明和实现。

DEMO架构

因为没有Demuxer,所以直接用Loader读取Annex-B码流。

  1. 通过Loader读取到Annex-B码流的Uint8Array数据

  2. 通过postMessge将数据发送给Worker线程的WASM包解码

  3. WASM通过回调函数传回YUV数据给Worker再通过postMessage传给主线程Canvas

实操步骤

如何将 FFmpeg 编译成 WASM 包

接下来就进入正题了,第一步,先编译FFmpeg做精简,为啥呢?因为FFmpeg不光是个C库,还是非常庞大的C库。我们要在Web上使用它就需要移除一些无用的模块,好在FFmpeg提供了相应配置的能力,使用根目录configure文件按如下步骤操作即可。

1. 准备

  • 编译前我们需要去emscripten官网[7]下载最新版emsdk

emsdk就是用来把FFmpeg编译成wasm包的工具

  • 官网FFmpeg[8] 下载源码版的FFmpeg(本文基于4.1)

2. 编译FFmpeg静态库

创建 make_decoder.sh

echo "Beginning Build:"
rm -r ./ffmpeg-lite
mkdir -p ./ffmpeg-lite # dist目录
cd ../ffmpeg  # src目录,ffmpeg源码
make clean
emconfigure ./configure --cc="emcc" --cxx="em++" --ar="emar" --ranlib="emranlib" --prefix=$(pwd)/../ffmpeg-wasm/ffmpeg-lite --enable-cross-compile --target-os=none --arch=x86_32 --cpu=generic \
    --enable-gpl --enable-version3 \
    --disable-swresample --disable-postproc --disable-logging --disable-everything \
    --disable-programs --disable-asm --disable-doc --disable-netwo
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值