如下是百度百科對於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>
複製代碼