音视频编解码对于前端工程师是一个比较少涉足的领域,涉及到流媒体技术中的文本、图形、图像、音频和视频多种理论知识的学习,才能够应用到具体实践中,本团队在多媒体领域深耕两年多,才算是有一定产出,我们自研web播放器并支持h.265解码,在码率优化的大背景下(保持画质不变情况下,应用图像增强、roi区域检测、智能场景分类和h265编解码等多种技术能力,将码流降低50%。达到减少带宽成本,提升视频服务QoE的目的),真正做到了h265解码播放的全域覆盖。
我们播放器整体架构设计如下:
本文主要分享了我们基于WebAssembly实现H.265格式的解封装、解码和播放。
H.265又称HEVC(全称High Efficiency Video Coding,高效率视频编码),是ITU-T H.264/MPEG-4 AVC标准的继任者。相比H.264,H.265拥有更高的压缩率,也就意味着同样码率(又称比特率是指每秒传送的比特(bit)数。单位为bps(Bit Per Second),比特率越高,每秒传送数据就越多,画质就越清晰),H.265的画质会更清晰,更高的压缩率就能使用更低的存储和传输成本。
H.264是当下用的最为广泛的视频编码格式,H.265标准围绕着现有的视频编码标准H.264,保留原来的某些技术,同时对一些相关的技术加以改进。新技术使用先进的技术用以改善码流、编码质量、延时和算法复杂度之间的关系,达到最优化设置。H.265和H.264都是基于块的视频编码技术,主要的差别在于编码单元的大小以及一些编码算法细节,H.265将图像划分为“编码树单元(coding tree Unit, CTU)”,而不是像H.264那样的16×16的宏块。根据不同的编码设置,编码树单元的尺寸可以被设置为64×64或有限的32×32或16×16。一般来说区块尺寸越大,压缩效率就越好。具体的算法及相关细节这里不具体展开了,还有一些其他的压缩算法如因为H.265专利限制而生的开放编码格式如AV1等,读者可以参考其他相关文章。
如下图,可以看到同样主观画面质量,H.265(500K)仅需H.264(800K)一半左右的带宽码率。
如下图,因为H.265专利及硬解支持情况不完善的原因,主流现代浏览器均不兼容H.265编码的视频播放(Edge新版本以插件方式支持),但是因为Apple对H.265的支持(这里作者认为这可能是一个很重要的标志,因为技术的发展很多时候不光是这个技术本身所决定的,而是很多因素共同作用的结果,商业也是其中很重要的一个因素),移动端ios safari在11.0版本以上支持原生播放。
想要在浏览器端播放H.265视频原生的标签没有办法支持,但是因为视频格式本身是连续图像画面和音频的集合,参考了chromium的源码及video标签内部的实现原理,可以通过
+ Web Audio API
的结合来模拟实现一个虚拟的video标签来实现播放器功能。
因为直播流时效性的缘故,发布了一个播放H.265 mp4视频(该视频地址直接在浏览器中播放只有声音而没有画面)的在线demo,读者可以有一个直观感受。
地址:https://g.alicdn.com/videox/mp4-h265/1.0.2/index.html
效果:
因为前端领域对视频领域的涉及场景不多,一个标签就可以满足大部分场景,但是经历了这几年直播和短视频的爆发,视频的需求和功能也变得越来越复杂,开发之前阅读了很多视音频领域相关的书籍和文章,在此先对视音频基础进行一个简单的介绍。
视频中我们通常说的视频的格式,比如 .mp4, .mov, .wmv, .m3u8, .flv 等等被称为container
。在一个视频文件中音频、视频数据是分开存储的,使用的压缩算法也不一样。其中container作为容器主要包含了video数据、audio数据、metadata(用于检索视音频payload格式等信息)。每个格式的封装格式不一样,比如FLV格式的基本单元是Tag,而MP4格式的基本单元是Box,辅助的meta信息用于检索找到对应的原始数据。
而平时听到的H.264, H.265等视频编码标准被称为codec
(COmpress and DECompress )。一个视频格式比如mp4可以使用任何标准化的压缩算法,这些信息都会被包含在一个视频文件的meta信息中来告诉播放器该用什么编解码算法来播放。
一个传统的客户端播放器播放一个视频流经过了如下各个环节:
拉取数据 => 解封装 => 音视频解码 => 采样/像素数据发送到设备进行渲染。
对于流媒体,播放器客户端通过拉流以数据源(音视频流)为中心,进行管道式的传输。在此期间,对视频流的读取,转换,分类,复制等一系列操作处理,以封装的mp4流为例,需要对流进行解封装、解码、渲染等步骤:
在探究的过程中,为了了解主流浏览器不支持H.265视频播放的原因,以及浏览器端实现播放器原理的了解,通过对Chromium浏览器官方文档及video标签实现源码的阅读,整理了一个流程图。
可以看到浏览器内部对视频流播放的实现,在经过了PipelineController等数据传输管道的处理后利用FFmpeg软解或者Gpu硬解之后交给视频设备及音频设备进行同步及渲染。其中H.265的视频因为硬解支持情况不完善,软解可能有性能风险,所以在chrome中被关闭了不支持,在chromium中可以通过参数打开。我们就依照这个思路,利用浏览器提供的接口来实现一个模拟的video标签。
开发思路按照从简单到复杂的过程,对任务进行拆分,来完成H.265视频点播及直播等各个场景的覆盖,以mp4短视频出发完成播放流程,再覆盖直播场景,考虑如网络抖动、内存控制等复杂因素,再针对直播m3u8等回放文件进行播放并开发视频seek、倍速等功能。
mp4播放=>flv播放=>hls播放=>加入seek、倍速等功能
绘制图像,通过
标签播放音频,画面在Macbook Pro上Chrome浏览器下在23fps左右。问题:
解决方案:
解决方案:
方案调整:
codec不支持:FLV官方协议不支持H.265。
解决方案:
方案调整:
通过Emscripten工具可以把C语言编写的FFmpeg库编译成wasm并在浏览器中应用到视音频解码中。
我们的视频解码场景和通常的播放器一样,通过依赖FFmpeg的通用接口来实现解封装和解码的工作。先通过emscripten编译ffmpeg库,再通过静态库的方式依赖到解封装和解码入口程序中。
因为flv直播视频受时效性影响较大,拿720P高清的H.265 mp4视频作为稳定输入测试
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'https://gw.alicdn.com/bao/uploaded/LB1l2iXISzqK1RjSZFjXXblCFXa.mp4?file=LB1l2iXISzqK1RjSZFjXXblCFXa.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : www.aliyun.com - Media Transcoding
Duration: 00:01:00.10, start: 0.000000, bitrate: 907 kb/s
Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709, progressive), 1280x720, 854 kb/s, 25 fps, 25 tbr, 12800 tbn, 25 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 48 kb/s (default)
Metadata:
handler_name : SoundHandler
lenovo ThinkPad T430
MacBook Pro (Retina, 15-inch, Mid 2015)
decoder.wasm大小 | decoder.js大小 | 平均每帧解码时长 | 内存占用 | cpu占用 |
---|---|---|---|---|
1.4M | 168K | 26.79ms | 27M | 17~25% |
设备 | Chrome | Safari | FireFox | Edge | Native |
---|---|---|---|---|---|
MacOS(i7) | 26.79ms | 22.19ms | 24.77ms | - | 5.08ms |
windows(i5) | 33.51ms | - | 36.74ms | 86.72ms | 未测试 |
意味着最高能提供720P高清视频如下帧率视频流畅播放的能力:
设备 | Chrome | Safari | FireFox | Edge | 视频基准 | Native |
---|---|---|---|---|---|---|
MacOS(i7) | 37fps | 45fps | 40fps | - | 25fps | 196fps |
windows(i5) | 30fps | - | 27fps | 12fps | 25fps | 未测试 |
可以看到这两台机器中,在非高速运动等普通的如电商场景25fps帧率的高清720p视频已经能达到生产环境的标准,但是距离原生的速度还有一定距离。
主要用到了WebAssembly及WebWorker的支持,实际测试中主流浏览器Chrome、Safari、Firefox、Edge均能通过兼容性测试。
当前的技术方案已经能在大部分机器的主流浏览器上流畅的播放720P的高清直播流,但是在Edge浏览器及性能稍差的机器上还是存在高清视频解码性能不能满足流畅播放的风险,针对WebAssembly达到native速度的目标还有一定距离,尤其是汇编并行计算的支持,在视音频及大规模数据处理中是很常见的性能优化策略,作者整理了几个优化的方向,在未来还有更多探索的空间:
通过H.265视频播放将开源视音频库FFmpeg的能力及WebAssembly性能的优势在浏览器端视音频处理上有了一次深入的尝试。视频作为一种多媒体形式,相比现有的文字、图像、音频都能有更生动及更丰富信息的表现。尤其经过了直播和短视频的爆发增长后,成为了一种基础的多媒体形式,也是网络及移动端手机性能等技术发展的体现。未来随着5G及更高性能的硬件设备的发展会被更广泛的应用到各个领域。浏览器在这场视频革命中也是不可或缺的一个环节,通过这次的探索,为未来浏览器端扩展视音频处理的通用能力提供了想象的空间,同时也在浏览器端通过WebAssembly向native性能及能力靠近的路上做了一个落地的尝试,虽然从测试情况看现在的表现还不如native,但是随着标准及技术的演进,为未来对性能要求比较高的图形图像及人工智能等相关方向在浏览器端处理一定会渐渐被广泛的应用起来,比如如下几个方向:
本文介绍了我们在Web端H.265播放器上研发的过程和进展,后续还有很多继续优化和深入的点。对相关知识感兴趣的同学欢迎沟通交流,附上我们前端团队的介绍:
淘宝技术部内容与开放平台前端团队是淘系核心的商业变革阵地,相对于横向资源前端团队,我们更深入在内容电商、音视频技术领域,探寻创新商业模式及业界领先技术。
或者直接联系团队负责人: 灵玉 [email protected]