# Web H.265 播放器

H265

随着互联网的快速发展和 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 编码直到现在在浏览器中的硬件解码支持情况并不理想。

caniuseh265

所以,当下想要在浏览器端直接使用原生的 <video /> 标签播放 H.265 视频是行不通的,我们需要采取一些方式来实现软解。

# FFmpeg

说到视频编解码,不得不提一个音视频处理程序 - FFmpeg。FFmpeg 可以运行音频和视频多种格式的录影、转换、流功能。其中 libavcodec——就是被用于多个项目中音频和视频的编解码库。

ffmpeg-process

FFmpeg 源码采用 C 语言书写,提供了丰富而友好的接口支持开发者进行二次开发。作为一个开源的自由软件,它的源码托管在 GitHub 上,现在已经拥有了超过 24k 的 Star。

如此,我们完全可以借助 FFmpeg 来支持对 H.265 视频的解码工作。但是,如何让 C 语言在 Web 端正常运行呢?

# WebAssembly

WebAssembly 是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。它设计的目的不是为了手写代码,而是为诸如 C、C++ 和 Rust 等低级源语言提供一个高效的编译目标。

WebAssembly

通过 Emscripten 工具能够将一段 C/C++ 代码,编译出:

  • 一个 .wasm 模块;
  • JavaScript ”胶水“代码;
  • 一个用来展示代码运行结果的 HTML 文档;
wasm-process

其中,胶水代码包括了调用 WebAssembly 的 JavaScript API 来获取、加载和运行 .wasm 文件的逻辑,借助我们就可以在 Web 端使用 FFmpeg 来处理音视频内容。

# 基础架构

Web 视频播放器的整个流程主要包括获取流媒体数据、解封转和解码,最后对数据进行渲染四个步骤,所以整体也可以大致分为四层。

Web Player

对于 H.265 播放而言整体结构与此类似,只不过将流媒体数据的处理工作(包括解封转和编解码)交给了 FFmpeg 来处理。

process

其中核心包括三个步骤:

  1. 通过 Media Loader 加载媒体数据;
  2. 将媒体数据发送给 Web Worker 的 WASM 包进行处理;
  3. 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 即千位每秒。通俗一点的理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件。

# 参考