如下是百度百科对于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视频的解码是一个对性能要求很高的CPU密集任务,Web端脚本语言实现的解码器的性能很难达到要求。基于此,咱们能够经过基于Flash的H.265解码方案,即经过FlasCC[11]编译器把C语言编写的解码器编译成swc库,而后在Flash播放器中用Action Script调用swc库。canvas
另外一种方案是基于HTML5的,即经过WebAssembly技术将金山云自研的高性能解码器编译为wasm库,wasm文件是以二进制形式存在的,其中包含平台无关的虚拟指令(相似汇编指令)。这也是不少移动平台采用的方案。浏览器
下图是播放器内核主要模块与依赖的背景技术。 缓存
提供了实现无插件且基于 Web 的流媒体的功能。使用MSE API(主要包括:Media Source,Source Buffer等),媒体流可以经过 JavaScript 建立,而且能经过HTMLMediaElement元素(包括:video和audio元素)进行播放。IE11(win8+)及其余现代浏览器都支持。bash
标准提供了一套API,来建立和操做流数据,具体地,包括ReadableStream, WritableStream, 以及TransformStream。这容许咱们能够增量地处理数据,而没必要将全部数据缓存到内存中统一处理。咱们能够采用Fetch API获取视频数据,返回的body是一个ReadableStream对象。该对象表明一个数据源,内部维护了一个队列来记录还没有被读取的底层数据源。能够经过ReadableStream的getReader()接口读取内部队列中chunk数据。多线程
让单线程的JavaScript具有了多线程编程的能力,让视频播放器内核能够分离解复用、解码、渲染、UI操做监听等任务到不一样的线程中,并行地处理计算密集型任务和界面显示等。worker间通讯是经过MessageChannel进行。IE10+及其余现代浏览器都支持。架构
是Web端的字节码技术,它定义了一个通用的、体积紧凑、加载迅捷的二进制格式为编译目标,能发挥通用硬件的性能,以更接近原生应用的速度运行。在浏览器中对H.265编码的视频进行软件解码,是一项对性能很是有挑战的任务,JavaScript等脚本语言没法胜任此项工做。所以能够将C/C++语言编写的高性能解码库编译成字节码,再经过JavaScript调用来运行。目前此项技术在Chrome、Firefox、Safari和Edge浏览器的较新版本中均可以使用(如Chrome57+,Firefox 52+)。
关于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%。因为质量控制的测定方法不一样,这个数据也会有相应的变化。
目前,根据苹果官网的资料,对于HEVC的支持状况能够用下面的一句话来讲明: iOS 11 and macOS High Sierra introduced support for these new, industry-standard media formats。 也便是说,下面的设备都是支持的。
目前,浏览器对于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>
复制代码