H.265/HEVC在Web视频播放的实践

H.265

如下是百度百科对于H.265的介绍: H.265是ITU-T VCEG继H.264以后所制定的新的视频编码标准。H.265标准围绕着现有的视频编码标准H.264,保留原来的某些技术,同时对一些相关的技术加以改进。新技术使用先进的技术用以改善码流、编码质量、延时和算法复杂度之间的关系,达到最优化设置。具体的研究内容包括:提升压缩效率、提升鲁棒性和错误恢复能力、减小实时的时延、减小信道获取时间和随机接入时延、下降复杂度等。H.264因为算法优化,能够低于1Mbps的速度实现标清(分辨率在1280P720如下)数字图像传送;H.265则能够实现利用1~2Mbps的传输速度传送720P(分辨率1280720)普通高清音视频传送。ios

相比H.264带来了不少质的提高,相关对比能够访问H.265与H.264的差别详解。总之,H.265, HEVC 做为当前很是火的视频压缩方式,相对于你们熟知的 H.264 ,平都可以带来接近于 50% 的宽度节省。 web

在这里插入图片描述

相关知识

视频播放器架构

一个典型的现代播放器能够分为三个部分:UI、多媒体引擎和解码器,架构模型以下图: 算法

在这里插入图片描述

硬解码支持

随着 4K 视频愈来愈流行,Apple公司的最新的操做系统版本(Mac Hight Sierra和iOS 11)迎来了 HEVC (高效视频编码,也称 H.265) 这一新的行业标准[6]。与现行的 H.264 视频压缩标准相比,它的视频压缩率最高可提高 50% 之多。使用H.265,在保持视频画质不变的状况下,视频流媒体传输效果更好。而在相同码率下,能给质量带来近两倍的提高。下图是两张相同码率相同分辨率(400kpbs 1080p)的图片,左边的采用H.265编码,右边的采用H.264编码。 编程

在这里插入图片描述
通常来讲操做系统借助硬件(显卡)进行H.265编码视频的解码工做,其好处是硬解的功耗低,解码速度快。但目前H.265编码在浏览器中的硬件解码支持状况并不普及。经测试只在定制的Chromium[7] 及Edge 14浏览器中支持,能够经过此页面,测试浏览器对H.265编码的点播视频的播放状况。下图是H.265视频在Chromium 64中播放的截图:
在这里插入图片描述
须要注意的是硬件解码须要用户的显卡支持H.265 codec, 目前支持H.265解码的显卡主要包括:Intel HD Graphic 4400/4600/5000/5500/6000/620, Iris Graphics 5100/5200/6100,NVIDIA GeForce GTX 745, GTX 750, GTX 750 Ti, GTX 850M, GTX 860M,GeForce 830M, 840M,GeForce GTX 970, GTX 980, GTX 970M, GTX 980M,GeForce GTX TITAN X, GeForce GTX 980 Ti, GeForce GTX 750 SE, GTX 950, GTX 960, GeForce GTX 1070, GTX 1080, GeForce GTX 1060, NVIDIA TITAN XP, GeForce GTX 1050, GTX 1050 Ti。

Web软解方案

除了硬解码方案以外,软件解码也成为一种有效的选择,因为H.265视频的解码是一个对性能要求很高的CPU密集任务,Web端脚本语言实现的解码器的性能很难达到要求。基于此,咱们能够经过基于Flash的H.265解码方案,即经过FlasCC[11]编译器把C语言编写的解码器编译成swc库,而后在Flash播放器中用Action Script调用swc库。canvas

另外一种方案是基于HTML5的,即经过WebAssembly技术将金山云自研的高性能解码器编译为wasm库,wasm文件是以二进制形式存在的,其中包含平台无关的虚拟指令(相似汇编指令)。这也是不少移动平台采用的方案。浏览器

相关HTML5技术

下图是播放器内核主要模块与依赖的背景技术。 缓存

在这里插入图片描述
其中Audio MSE Controller依赖于Media Source Extension API,Stream Loader依赖于Stream标准,H.265 Decoder依赖于WebAssembly技术,而各个模块被划分在不一样的线程中,依赖于Web Workers。

Media Source Extensions(简称MSE):

提供了实现无插件且基于 Web 的流媒体的功能。使用MSE API(主要包括:Media Source,Source Buffer等),媒体流可以经过 JavaScript 建立,而且能经过HTMLMediaElement元素(包括:video和audio元素)进行播放。IE11(win8+)及其余现代浏览器都支持。bash

Streams

标准提供了一套API,来建立和操做流数据,具体地,包括ReadableStream, WritableStream, 以及TransformStream。这容许咱们能够增量地处理数据,而没必要将全部数据缓存到内存中统一处理。咱们能够采用Fetch API获取视频数据,返回的body是一个ReadableStream对象。该对象表明一个数据源,内部维护了一个队列来记录还没有被读取的底层数据源。能够经过ReadableStream的getReader()接口读取内部队列中chunk数据。多线程

Web Workers

让单线程的JavaScript具有了多线程编程的能力,让视频播放器内核能够分离解复用、解码、渲染、UI操做监听等任务到不一样的线程中,并行地处理计算密集型任务和界面显示等。worker间通讯是经过MessageChannel进行。IE10+及其余现代浏览器都支持。架构

WebAssembly

是Web端的字节码技术,它定义了一个通用的、体积紧凑、加载迅捷的二进制格式为编译目标,能发挥通用硬件的性能,以更接近原生应用的速度运行。在浏览器中对H.265编码的视频进行软件解码,是一项对性能很是有挑战的任务,JavaScript等脚本语言没法胜任此项工做。所以能够将C/C++语言编写的高性能解码库编译成字节码,再经过JavaScript调用来运行。目前此项技术在Chrome、Firefox、Safari和Edge浏览器的较新版本中均可以使用(如Chrome57+,Firefox 52+)。

H.265 Vs H.264

关于H.265 与 H.264更详细的差别,能够访问H.265与H.264的差别详解

H.265/HEVC的编码架构大体上和H.264/AVC的架构类似,主要也包含:帧内预测(intra prediction)、帧间预测(inter prediction)、转换(transform)、量化(quantization)、去区块滤波器(deblocking filter)、熵编码(entropy coding)等模块。

在这里插入图片描述

在HEVC编码架构中,总体被分为了三个基本单位,分别是编码单位(coding unit, CU)、预测单位(predict unit, PU)和转换单位(transform unit, TU)。比起H.264/AVC,H.265/HEVC提供了更多不一样的工具来下降码率,以编码单位来讲,H.264中每一个宏块(macroblock/MB)大小都是固定的16x16像素,而H.265的编码单位能够选择从最小的8x8到最大的64x64。

同时,H.265的帧内预测模式支持33种方向(H.264只支持8种),而且提供了更好的运动补偿处理和矢量预测方法。 反复的质量比较测试已经代表,在相同的图象质量下,相比于H.264,经过H.265编码的视频大小将减小大约39-44%。因为质量控制的测定方法不一样,这个数据也会有相应的变化。

支持状况

ios

目前,根据苹果官网的资料,对于HEVC的支持状况能够用下面的一句话来讲明: iOS 11 and macOS High Sierra introduced support for these new, industry-standard media formats。 也便是说,下面的设备都是支持的。

  • iPhone 7 or iPhone 7 Plus or later
  • iPad (6th generation)
  • iPad Pro (10.5 inch)
  • iPad Pro 12.9-inch (2nd generation)

Android

在这里插入图片描述

浏览器

目前,浏览器对于H.265支持的并非很友好:

在这里插入图片描述

实战

目前,HEVC 的普及速度尚未那么快,不过咱们仍是能够尝试在 Web 中优雅的播放 H265 视频。

判断是否支持播放

要判断平台是否支持H.265格式的视频,能够经过H265 的 mimetype 值来判断:type="video/mp4; codecs=hevc"。例如:

var supportHEVC = function(video) {  
    if (typeof video.canPlayType == ‘ function’) {
        var playable = elem.canPlayType('video/mp4; codecs="hevc"');
        if ((playable.toLowerCase() == 'maybe') || (playable.toLowerCase() == 'probably')) {
            return true;
        }
    }
    return false;
};
复制代码

若是,使用H.265没法播放视频,则使用H.264进行播放,因此咱们能够经过 source 设置多种格式:

<video controls autoplay>  
    <source src="your_video.mp4" type="video/mp4; codecs=hevc">
    <source src="your_video.webm" type="video/webm; codecs=vp9">
    <source src="your_video.mp4" type="video/mp4; codecs=avc1">
</video>  
复制代码

对于web平台来讲,咱们用到的是libde265.js,它是一个经过 JS 来解码 H.265 视频的库,它经过将 视频的 frame data 转化为 rgba 像素,而后绘制到 Canvas 上。下面是使用示例:

<canvas id="canvas"></canvas>

<script src="./libde265.min.j"></script>  
<script>  
var VIDEO_URL = 'h265-test-640.mp4'  
var video = document.getElementById('canvas')  
 // var fpsWrap = document.querySelector('.hevc-fps')
  var status = document.querySelector('.hevc-status')
  var playback = function (event) {
    // event.preventDefault()
    if (player) {
      player.stop()
    }

    player = new libde265.RawPlayer(video)
    player.set_status_callback(function (msg, fps) {
      player.disable_filters(true)
      console.log(msg);
      switch (msg) {
        case 'loading':
          status.innerHTML = 'Loading movie...'
          break
        case 'initializing':
          status.innerHTML = 'Initializing...'
          break
        case 'playing':
          status.innerHTML = 'Playing...'
          break
        case 'stopped':
          status.innerHTML = 'stopped'
          break
        case 'fps':
          // fpsWrap.innerHTML = Number(fps).toFixed(2) + ' fps'
          break
        default:
          status.innerHTML = msg
      }
    })
    player.playback(VIDEO_URL)
  }
  playback()
</script>  
复制代码

测试地址:events.jackpu.com/h265。

在这里插入图片描述
能够发现,canvas 绘制和 video 原生解码差距仍是很大,可是咱们能够看到 Video 的大小相比原有的缩小了 31% ,所以 H265 的前景值得期待的。

参考:H.265 / HEVC WiKi H.265 Vs H.264

相关文章
相关标签/搜索