# Web H.265 播放器
随着互联网的快速发展和 5G 的到来,人们对音视频内容的需求也开始飞速增长,追求的质量也越来越高,导致视频在网络上的传输量也越来越大。因此,在提高视频质量的同时,我们还需要考虑随之而来的带宽成本。
同样质量的视频想要拥有更小的体积就需要拥有更高效的编码算法,H.265 正是这样一种高效的视频编码标准。
# H.265
当下 H.264 还是使用最为广泛的视频编码格式,HEVC/H.265 作为新一代的视频编码标准,它的核心目标在 H264/AVC High Profile 的基础上,将编码效率提高一倍,即在保证相同编码质量的前提下,视频码率减少 50%,可支持 4K 清晰度甚至到超高清电视。
视频编码标准 | 较之H.264/MPEG-4 AVC HP减少码率的比例 | ||||
---|---|---|---|---|---|
480p | 720p | 1080p | 4K UHD | ||
HEVC | 52% | 56% | 62% | 64% |
可惜的是由于专利等原因,H.265 编码直到现在在浏览器中的硬件解码支持情况并不理想。
所以,当下想要在浏览器端直接使用原生的 <video />
标签播放 H.265 视频是行不通的,我们需要采取一些方式来实现软解。
# FFmpeg
说到视频编解码,不得不提一个音视频处理程序 - FFmpeg。FFmpeg 可以运行音频和视频多种格式的录影、转换、流功能。其中 libavcodec
——就是被用于多个项目中音频和视频的编解码库。
FFmpeg 源码采用 C 语言书写,提供了丰富而友好的接口支持开发者进行二次开发。作为一个开源的自由软件,它的源码托管在 GitHub 上,现在已经拥有了超过 24k 的 Star。
如此,我们完全可以借助 FFmpeg 来支持对 H.265 视频的解码工作。但是,如何让 C 语言在 Web 端正常运行呢?
# WebAssembly
WebAssembly 是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。它设计的目的不是为了手写代码,而是为诸如 C、C++ 和 Rust 等低级源语言提供一个高效的编译目标。
通过 Emscripten 工具能够将一段 C/C++ 代码,编译出:
- 一个
.wasm
模块; - JavaScript ”胶水“代码;
- 一个用来展示代码运行结果的 HTML 文档;
其中,胶水代码包括了调用 WebAssembly 的 JavaScript API 来获取、加载和运行 .wasm
文件的逻辑,借助我们就可以在 Web 端使用 FFmpeg 来处理音视频内容。
# 基础架构
Web 视频播放器的整个流程主要包括获取流媒体数据、解封转和解码,最后对数据进行渲染四个步骤,所以整体也可以大致分为四层。
对于 H.265 播放而言整体结构与此类似,只不过将流媒体数据的处理工作(包括解封转和编解码)交给了 FFmpeg 来处理。
其中核心包括三个步骤:
- 通过 Media Loader 加载媒体数据;
- 将媒体数据发送给 Web Worker 的 WASM 包进行处理;
- WASM 通过 JavaScript API 传回处理后的数据给 Web Worker,Web Worker 再把数据传给主线程的 Canvas 和 Web audio。
# 开源方案
目前,H.265 播放器已经在许多业务中落地了,业界中也不乏有一些开源的实现。
播放器 | 说明 | GitHub |
---|---|---|
h265player | 完整的 Web 版 H.265 播放器解决方案 | 查看 (opens new window) |
easyplayer | 同时支持多协议、多编码格式的 H5 播放器 | 查看 (opens new window) |
h265web | H.265/Hevc Web 端播放器 | 查看 (opens new window) |
此处仅列举了几个试用过的播放器,感兴趣的同学也可以参照官方文档去尝试。
# 总结
现在浏览器对 H.265 视频的原生支持还不够友好,如果想要播放 H.265 视频可以采用 WebAssembly 技术,将 FFmpeg 编译为 wasm,在收到 H.265 码流时,调用 FFmpeg 进行解码,然后通过 Canvas 来显示视频画面。
其中,从码流中分离出来的音频数据则可以交由 Web Audio API (opens new window) 进行处理,对于主流的音频编码格式各浏览器支持都还不错。
本文主要是针对 Web 端 H.265 视频播放器的实现方式做了一个简单的介绍。目前,H.265 播放器已经在许多业务中落地了,业界中也不乏有一些开源的实现,后续我们也将逐步去了解其中奥妙,奥利给。
# 附录
视频编码:指连续图像的编码,与静态图像编码着眼于消除图像内的冗余信息相对,视频编码主要通过消除连续图像之间的时域冗余信息来压缩视频。
码率:数据传输时单位时间传送的数据位数,一般我们用的单位是 kbps
即千位每秒。通俗一点的理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件。
# 参考
← 浏览器音视频自动播放策略 FFmpeg →