「視頻直播技術詳解」系列之六:現代播放器原理

​關於直播的技術文章很多,成體系的很少。咱們將用七篇文章,更系統化地介紹當下大熱的視頻直播各環節的關鍵技術,幫助視頻直播創業者們更全面、深刻地瞭解視頻直播技術,更好地技術選型。html

本系列文章大綱以下:前端

(一)採集git

(二)處理github

(三)編碼和封裝算法

(四)推流和傳輸瀏覽器

(五)延遲優化緩存

(六)現代播放器原理安全

(七)SDK 性能測試模型服務器

在上一篇延遲優化中,咱們分享了很多簡單實用的調優技巧。本篇是《視頻直播技術詳解》系列之六:現代播放器原理。網絡


 

近年來,多平臺適配需求的增加致使了流媒體自適應碼率播放的興起,這迫使 Web 和移動開發者們必須從新思考視頻技術的相關邏輯。首先,巨頭們分分發布了 HLS、HDS 和 Smooth Streaming 等協議,把全部相關細節都隱藏在它們專供的 SDK 中。開發者們無法自由的修改播放器中的多媒體引擎等邏輯:你無法修改自適應碼率的規則和緩存大小,甚至是你切片的長度。這些播放器可能用起來簡單,可是你沒有太多去定製它的選擇,即使是糟糕的功能也只能忍受。

可是隨着不一樣應用場景的增長,可定製化功能的需求愈來愈強。僅僅是直播和點播之間,就存在不一樣的 buffer 管理、ABR 策略和緩存策略等方面的差異。這些需求催生了一系列更爲底層關於多媒體操做 API 的誕生:Flash 上面的 Netstream,HTML5 上的 Media Source Extensions,以及 Android 上的 Media Codec,同時業界又出現了一個基於 HTTP 的標準流格式 MPEG-DASH。這些更高級的能力爲開發者提供了更好的靈活性,讓他們能夠構建適合本身業務需求的播放器和多媒體引擎。

今天咱們來分享一下如何構建一個現代播放器,以及構建這樣一個播放器須要哪些關鍵組件。一般來講,一個典型的播放器能夠分解成三部分:UI、 多媒體引擎和解碼器,如圖 1 所示:

圖 1. 現代播放器架構

用戶界面(UI):這是播放器最上層的部分。它經過三部分不一樣的功能特性定義了終端用戶的觀看體驗:皮膚(播放器的外觀設計)、UI(全部可自定義的特性如播放列表和社交分享等)以及業務邏輯部分(特定的業務邏輯特性如廣告、設備兼容性邏輯以及認證管理等)。

多媒體引擎:這裏處理全部播放控制相關的邏輯,如描述文件的解析,視頻片斷的拉取,以及自適應碼率規則的設定和切換等等,咱們將在下文中詳細講解這部份內容。因爲這些引擎通常和平臺綁定的比較緊,所以可能須要使用多種不一樣的引擎才能覆蓋全部平臺。

解碼器和 DRM 管理器:播放器最底層的部分是解碼器和 DRM 管理器,這層的功能直接調用操做系統暴露出來的 API。解碼器的主要功能在於解碼並渲染視頻內容,而 DRM 管理器則經過解密過程來控制是否有權播放。

接下來咱們將使用例子來介紹各層所扮演的不一樣角色。

1、用戶界面(UI)

UI 層是播放器的最上層,它控制了你用戶所能看到和交互的東西,同時也可使用你本身的品牌來將其定製,爲你的用戶提供獨特的用戶體驗。這一層最接近於咱們說的前端開發部分。在 UI 內部,咱們也包含了業務邏輯組件,這些組件構成了你播放體驗的獨特性,雖然終端用戶無法直接和這部分功能進行交互。

UI 部分主要包含三大組件:

1. 皮膚

皮膚是對播放器視覺相關部分的統稱:進度控制條、按鈕和動畫圖標等等,如圖 2 所示。和大部分設計類的組件同樣,這部分組件也是使用 CSS 來實現的,設計師或者開發者能夠很方便的拿來集成(即使你使用的是 JW Player 和 Bitdash 這種整套解決方案)。

圖 2. 播放器皮膚

2. UI 邏輯

UI 邏輯部分定義了播放過程當中和用戶交互方面全部可見的交互:播放列表、縮略圖、播放頻道的選擇以及社交媒體分享等。基於你預期達到的播放體驗,還能夠往這部分中加入不少其它的功能特性,其中有不少以插件的形式存在了,或許能夠從中找到一些靈感:Plugins · videojs/video.js Wiki · GitHub 邏輯部分包含的功能較多,咱們不一一詳細介紹,直接以 Eurosport 播放器的 UI 來做爲例子直觀感覺一下這些功能。

圖 3. Eurosport 播放器的用戶界面


從圖 3 能夠看出,除了傳統的 UI 元素以外,還有一個很是有趣的特性,在用戶觀看 DVR 流媒體的時候,直播以小視窗的形式展現,觀衆能夠經過這個小窗口隨時回到直播中。因爲佈局或者 UI 和多媒體引擎徹底獨立,這些特性在 HTML5 中使用 dash.js 只須要幾行代碼就能實現。對於 UI 部分來講,最好的實現方式是讓各類特性都以插件/模塊的形式添加到 UI 核心模塊中。

3. 業務邏輯

除了上面兩部分「可見」的功能特性以外,還有一個不可見的部分,這部分構成了你業務的獨特性:認證和支付、頻道和播放列表的獲取,以及廣告等。這裏也包含一些技術相關的東西,好比用於 A/B 測試模塊,以及和設備相關的配置,這些配置用於在多種不一樣類型的設備之間選擇多個不一樣的媒體引擎。

爲了揭開底層隱藏的複雜性,咱們在這裏更詳細的講解一下這些模塊:

設備檢測與配置邏輯:這是最重要的特性之一,由於它將播放和渲染剝離開來了。例如,基於你瀏覽器的不一樣版本,播放器可能會自動爲你選擇一個基於 HTML5 MSE 的多媒體引擎 hls.js,或者爲你選擇一個基於 flash 的播放引擎 FlasHls 來播放 HLS 視頻流。這部分的最大特色在於,不管你使用什麼樣的底層引擎,在上層均可以使用相同的 JavaScript 或者 CSS 來定製你的 UI 或者業務邏輯。

可以檢測用戶設備的能力容許你按需配置終端用戶的體驗:若是是在移動設備而非 4K 屏幕設備上播放,你可能須要從一個較低的碼率開始。

A/B 測試邏輯:A/B 測試是爲了可以在生產環節中灰度部分用戶。例如,你可能會給部分 Chrome 用戶提供一個新的按鈕或者新的多媒體引擎,而且還能保證它全部的工做都正常如期進行。

廣告(可選):在客戶端處理廣告是最複雜的業務邏輯之一。如 videojs-contrib-ads 這個插件模塊的流程圖給出同樣,插入廣告的流程中包含多個步驟。對於 HTTP 視頻流來講,你或多或少會用到一些已有的格式如 VAST、VPAID 或者 Google IMA,它們可以幫你從廣告服務器中拉取視頻廣告(一般是過期的非自適應格式),放在視頻的前期、中期和後期進行播放,且不可跳過。

總結:

針對你的定製化需求,你可能選擇使用包含全部經典功能的 JW Player 來播放(它也容許你定製部分功能),或者基於 Videojs 這樣的開源播放器來定製你本身的功能特性。甚至爲了在瀏覽器和原生播放器之間統一用戶體驗,你也能夠考慮使用 React Native 來進行 UI 或者皮膚的開發,使用 Haxe 來進行業務邏輯的開發,這些優秀的庫均可以在多種不一樣類型的設備之間共用同一套代碼庫。

圖 4. 業務邏輯流程圖

2、多媒體引擎

近年來,多媒體引擎更是以一種全新獨立的組件出如今播放器架構中。在 MP4 時代,平臺處理了全部播放相關的邏輯,而只將一部分多媒體處理相關的特性(僅僅是播放、暫停、拖拽和全屏模式等功能)開放給開發者。

然而,新的基於 HTTP 的流媒體格式須要一種全新的組件來處理和控制新的複雜性:解析聲明文件、下載視頻片斷、自適應碼率監控以及決策指定等等甚至更多。起初,ABR 的複雜性被平臺或者設備提供商處理了。然而,隨着主播控制和定製播放器需求的遞增,一些新的播放器中慢慢也開放了一些更爲底層的 API(如 Web 上的 Media Source Extensons,Flash 上的 Netstream 以及 Android 平臺的 Media Codec),並迅速吸引來了不少基於這些底層 API 的強大而健壯的多媒體引擎。

圖 5. Google 提供的多媒體處理引擎 Shakaplayer 的數據流程圖


接下來咱們將詳細講解現代多媒體處理引擎中各組件的細節:

1. 聲明文件解釋和解析器

在基於 HTTP 的視頻流中,一切都是以一個描述文件開始。該聲明文件包含了媒體服務器所需理解的元信息:有多少種不一樣類型的視頻質量、語言以及字母等,它們分別是什麼。解析器從 XML 文件(對於 HLS 來講則是一種特殊的 m3u8 文件)中取得描述信息,而後從這些信息中取得正確的視頻信息。固然,媒體服務器的類型不少,並非全部都正確的實現了規範,所以解析器可能須要處理一些額外的實現錯誤。

一旦提取了視頻信息,解析器則會從中解析出數據,用於構建流式的視覺圖像,同時知道如何獲取不一樣的視頻片斷。在某些多媒體引擎中,這些視覺圖像先以一副抽象多媒體圖的形式出現,而後在屏幕上繪製出不一樣 HTTP 視頻流格式的差別特徵。

在直播流場景中,解析器也必須週期性的從新獲取聲明文件,以便得到最新的視頻片斷信息。

2. 下載器(下載聲明文件、多媒體片斷以及密鑰)

下載器是一個包裝了處理 HTTP 請求原生 API 的模塊。它不只用於下載多媒體文件,在必要的時候也能夠用於下載聲明文件和 DRM 密鑰。下載器在處理網絡錯誤和重試方面扮演着很是重要的角色,同時可以收集當前可用帶寬的數據。

注意:下載多媒體文件可能使用 HTTP 協議,也可能使用別的協議,如點對點實時通訊場景中的 WebRTC 協議。

3. 流播放引擎

流播放引擎是和解碼器 API 交互的中央模塊,它將不一樣的多媒體片斷導入編碼器,同時處理多碼率切換和播放時的差別性(如聲明文件和視頻切片的差別,以及卡頓時的自動跳幀)。

4. 資源質量參數預估器(帶寬、CPU 和幀率等)

預估器從各類不一樣的維度獲取數據(塊大小,每片斷下載時間,以及跳幀數),並將其匯聚起來用於估算用戶可用的帶寬和 CPU 計算能力。這是輸出用於 ABR (Adaptive Bitrate, 自適應碼率)切換控制器作判斷。

5. ABR 切換控制器

ABR 切換器多是多媒體引擎中最爲關鍵的部分——一般也是你們最爲忽視的部分。該控制器讀取預估器輸出的數據(帶寬和跳幀數),使用自定義算法根據這些數據作出判斷,告訴流播放引擎是否須要切換視頻或者音頻質量。該領域有不少研究性的工做,其中最大的難點在於在再緩衝風險和切換頻率(太頻繁的切換可能致使糟糕的用戶體驗)之間找到平衡。

6. DRM 管理器(可選組件)

今天全部的付費視頻服務都基於 DRM 管理,而 DRM 則很大程度上依賴於平臺或者設備,咱們將在後續講解播放器的時候看到。多媒體引擎中的 DRM 管理器是更底層解碼器中內容解密 API 的包裝。只要有可能,它會盡可能經過抽象的方式來屏蔽瀏覽器或者操做系統實現細節的差別性。該組件一般和流處理引擎緊密鏈接在一塊兒,由於它常常和解碼器層交互。

7. 格式轉換複用器(可選組件)

後文中咱們將看到,每一個平臺在封包和編碼方面都有它的侷限性(Flash 讀的是 FLV 容器封裝的 H.264/AAC 文件,MSE 讀的是 ISOBMFF 容器封裝的 H.264/AAC 文件)。這就致使了有些視頻片斷在解碼以前須要進行格式轉換。例如,有了 MPEG2-TS 到 ISOBMFF 的格式轉換複用器以後,hls.js 就能使用 MSE 格式的內容來播放 HLS 視頻流。多媒體引擎層面的格式轉換複用器曾經遭受質疑;然而,隨着現代 JavaScript 或者 Flash 解釋權性能的提高,它帶來的性能損耗幾乎能夠忽略不計,對用戶體驗也不會形成多大的影響。

總結

多媒體引擎中也有很是多的不一樣組件和特性,從字幕到截圖到廣告插入等等。接下來咱們也會單獨寫一篇文章來對比多種不一樣引擎的差別,經過一些測試和市場數據來爲引擎的選擇給出一些實質性的指導。值得注意的是,要構建一個兼容各平臺的播放器,提供多個可自由替換的多媒體引擎是很是重要的,由於底層解碼器是和用戶平臺相關的,接下來咱們將重點講解這方面的內容。

3、解碼器和 DRM 管理器

出於解碼性能(解碼器)和安全考慮(DRM),解碼器和 DRM 管理器與操做系統平臺密切綁定。

圖 6. 解碼器、渲染器和 DRM 工做流程圖

1. 解碼器

解碼器處理最底層播放相關的邏輯。它將不一樣封裝格式的視頻進行解包,並將其內容解碼,而後將解碼後的視頻幀交給操做系統進行渲染,最終讓終端用戶看到。

因爲視頻壓縮算法變得愈來愈複雜,解碼過程是一個須要密集計算的過程,而且爲了保證解碼性能和流暢的播放體驗,解碼過程須要強依賴於操做系統和硬件。如今的大部分解碼都依賴於 GPU 加速解碼的幫助(這也是爲何免費而更強大的 VP9 解碼器沒有贏得 H.264 市場地位的緣由之一)。若是沒有 GPU 的加速,解碼一個 1080P 的視頻就會佔去 70% 左右的 CPU 計算量,而且丟幀率還可能很嚴重。

在解碼和渲染視頻幀的基礎之上,管理器也提供了一個原生的 buffer,多媒體引擎能夠直接與該 buffer 進行交互,實時瞭解它的大小並在必要的時候刷新它。

咱們前面提到,每一個平臺都有它本身的渲染引擎和相應的 API:Flash 平臺有 Netstream,Android 平臺有 Media Codec API,而 Web 上則有標準的 Media Sources Extensions。MSE 愈來愈吸引眼球,未來可能會成爲繼瀏覽器以後其它平臺上的事實標準。

2. DRM 管理器

圖 7. DRM 管理器

今天,在傳輸工做室生產的付費內容的時候,DRM 是必要的。這些內容必須防止被盜,所以 DRM 的代碼和工做過程都向終端用戶和開發者屏蔽了。解密過的內容不會離開解碼層,所以也不會被攔截。

爲了標準化 DRM 以及爲各平臺的實現提供必定的互通性,幾個 Web 巨頭一塊兒建立了通用加密標準Common Encryption (CENC) 和通用的多媒體加密擴展Encrypted Media Extensions,以便爲多個 DRM 提供商(例如,EME 可用於 Edge 平臺上的 Playready 和 Chrome 平臺上的 Widewine)構建一套通用的 API,這些 API 可以從 DRM 受權模塊讀取視頻內容加密密鑰用於解密。

CENC 聲明瞭一套標準的加密和密鑰映射方法,它可用於在多個 DRM 系統上解密相同的內容,只須要提供相同的密鑰便可。

在瀏覽器內部,基於視頻內容的元信息,EME 能夠經過識別它使用了哪一個 DRM 系統加密,並調用相應的解密模塊(Content Decryption Module, CDM)解密 CENC 加密過的內容。解密模塊 CDM 則會去處理內容受權相關的工做,得到密鑰並解密視頻內容。

CENC 沒有規定受權的發放、受權的格式、受權的存儲、以及使用規則和權限的映射關係等細節,這些細節的處理都由 DRM 提供商負責。

4、總結

今天咱們深刻了解了一下視頻播放器三個層面的不一樣內容,這個現代播放器結構最優秀之處在於其交互部分徹底和多媒體引擎邏輯部分分離,讓主播能夠無縫而自由靈活的定製終端用戶體驗,同時在多種不一樣終端設備上使用不一樣的多媒體引擎還能保證順利播放多種不一樣格式的視頻內容。

在 Web 平臺,得益於多媒體引擎如 dash.js、Shaka Player 和 hls.js 這些趨於成熟庫的幫助, MSE 和 EME 正在成爲播放的新標準,同時也愈來愈多有影響力的廠家使用這些播放引擎。近年來,注意力也開始伸向機頂盒和互聯網電視,咱們也看到愈來愈多這樣的新設備使用 MSE 來做爲其底層多媒體處理引擎。咱們也將持續投入更多的力量去支持這些標準。

 

本文由七牛雲佈道師何李石翻譯自How Modern Video Players Work,原文可去七牛雲官方博客查看。

相關文章
相關標籤/搜索