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

相關文章
相關標籤/搜索