轉: 移動直播技術秒開優化經驗

移動直播技術秒開優化經驗(含PPT)

2016-04-28 09:27

移動直播技術秒開優化經驗(含PPT)徐立,七牛創始合夥人兼產品副總裁,負責七牛直播雲的總體研發,是國內 Go / Docker / Container 技術早期佈道者,Go / Containers / Distributed Systems 技術的忠實愛好者和實踐者。曾合著國內第一本 Go 語言圖書《Go 語言編程》,翻譯《Go 語言程序設計》。nginx

現今移動直播技術上的挑戰要遠遠難於傳統設備或電腦直播,其完整的處理環節包括但不限於:音視頻採集、美顏/濾鏡/特效處理、編碼、封包、推流、轉碼、分發、解碼/渲染/播放等。算法

直播常見的問題包括編程

  • 主播在不穩定的網絡環境下如何穩定推流?緩存

  • 偏遠地區的觀衆如何高清流暢觀看直播?性能優化

  • 直播卡頓時如何智能切換線路?服務器

  • 如何精確度量直播質量指標並實時調整?微信

  • 移動設備上不一樣的芯片平臺如何高性能編碼和渲染視頻?網絡

  • 美顏等濾鏡特效處理怎麼作?多線程

  • 如何實現播放秒開?架構

  • 如何保障直播持續播放流暢不卡頓?

本次分享將爲你們揭開移動直播核心技術的神祕面紗。

視頻、直播等基礎知識

什麼是視頻?

首先咱們須要理解一個最基本的概念:視頻。從感性的角度來看,視頻就是一部充滿趣味的影片,能夠是電影,能夠是短片,是一連貫的視覺衝擊力表現豐富的畫面和音頻。但從理性的角度來看,視頻是一種有結構的數據,用工程的語言解釋,咱們能夠把視頻剖析成以下結構:

移動直播技術秒開優化經驗(含PPT)

內容元素 ( Content )

  • 圖像 ( Image )

  • 音頻 ( Audio )

  • 元信息 ( Metadata )

編碼格式 ( Codec )

  • Video : H.264,H.265, …

  • Audio : AAC, HE-AAC, …

容器封裝 (Container)

  • MP4,MOV,FLV,RM,RMVB,AVI,…

任何一個視頻 Video 文件,從結構上講,都是這樣一種組成方式:

  • 由圖像和音頻構成最基本的內容元素;

  • 圖像通過視頻編碼壓縮格式處理(一般是 H.264);

  • 音頻通過音頻編碼壓縮格式處理(例如 AAC);

  • 註明相應的元信息(Metadata);

最後通過一遍容器(Container)封裝打包(例如 MP4),構成一個完整的視頻文件。

若是以爲難以理解,能夠想象成一瓶番茄醬。最外層的瓶子比如這個容器封裝(Container),瓶子上註明的原材料和加工廠地等信息比如元信息(Metadata),瓶蓋打開(解封裝)後,番茄醬自己比如通過壓縮處理事後的編碼內容,番茄和調料加工成番茄醬的過程就比如編碼(Codec),而原材料番茄和調料則比如最本來的內容元素(Content)。

視頻的實時傳輸

簡而言之,理性的認知視頻的結構後,有助於咱們理解視頻直播。若是視頻是一種「有結構的數據」,那麼視頻直播無疑是實時傳輸這種「有結構的數據」(視頻)的方式。

那麼一個顯而易見的問題是:如何實時(Real-Time)傳輸這種「有結構的數據」(視頻)呢?

這裏邊一個悖論是:一個通過容器(Container)封裝後的視頻,必定是不可變的 ( Immutable ) 視頻文件,不可變的 ( Immutable ) 的視頻文件已是一個生產結果,根據「相對論」,而這個生產結果顯然不可能精確到實時的程度,它已是一段時空的記憶。

所以視頻直播,必定是一個 「邊生產,邊傳輸,邊消費」的過程。這意味着,咱們須要更近一步瞭解視頻從原始的內容元素 ( 圖像和音頻 ) 到成品 ( 視頻文件 ) 以前的中間過程 ( 編碼 )。

視頻編碼壓縮

不妨讓咱們來深刻淺出理解視頻編碼壓縮技術。

爲了便於視頻內容的存儲和傳輸,一般須要減小視頻內容的體積,也就是須要將原始的內容元素(圖像和音頻)通過壓縮,壓縮算法也簡稱編碼格式。例如視頻裏邊的原始圖像數據會採用 H.264 編碼格式進行壓縮,音頻採樣數據會採用 AAC 編碼格式進行壓縮。

視頻內容通過編碼壓縮後,確實有利於存儲和傳輸; 不過當要觀看播放時,相應地也須要解碼過程。所以編碼和解碼之間,顯然須要約定一種編碼器和解碼器均可以理解的約定。就視頻圖像編碼和解碼而言,這種約定很簡單:

編碼器將多張圖像進行編碼後生產成一段一段的 GOP ( Group of Pictures ) , 解碼器在播放時則是讀取一段一段的 GOP 進行解碼後讀取畫面再渲染顯示。

移動直播技術秒開優化經驗(含PPT)

GOP ( Group of Pictures ) 是一組連續的畫面,由一張 I 幀和數張 B / P 幀組成,是視頻圖像編碼器和解碼器存取的基本單位,它的排列順序將會一直重複到影像結束。

移動直播技術秒開優化經驗(含PPT)

I 幀是內部編碼幀(也稱爲關鍵幀),P 幀是前向預測幀(前向參考幀),B 幀是雙向內插幀(雙向參考幀)。簡單地講,I 幀是一個完整的畫面,而 P 幀和 B 幀記錄的是相對於 I 幀的變化。

若是沒有 I 幀,P 幀和 B 幀就沒法解碼。

移動直播技術秒開優化經驗(含PPT)

小結一下,一個視頻 ( Video ) ,其圖像部分的數據是一組 GOP 的集合, 而單個 GOP 則是一組 I / P / B 幀圖像的集合。

在這樣的一種幾何關係中,Video 比如一個 「物體」,GOP 比如 「分子」,I / P / B 幀的圖像則比如 「原子」。

想象一下,若是咱們把傳輸一個 「物體」,改爲傳輸一個一個的 「原子」,將最小顆粒以光速傳送,那麼以人的生物肉眼來感知,將是一種怎樣的體驗?

什麼是視頻直播?

不難腦洞大開一下,直播就是這樣的一種體驗。視頻直播技術,就是將視頻內容的最小顆粒 ( I / P / B 幀,…),基於時間序列,以光速進行傳送的一種技術。

簡而言之,直播就是將每一幀數據 ( Video / Audio / Data Frame ),打上時序標籤 ( Timestamp ) 後進行流式傳輸的過程。發送端源源不斷的採集音視頻數據,通過編碼、封包、推流,再通過中繼分發網絡進行擴散傳播,播放端再源源不斷地下載數據並按時序進行解碼播放。如此就實現了 「邊生產、邊傳輸、邊消費」 的直播過程。

理解以上兩個關於 視頻和直播兩個基礎概念後,接下來咱們就能夠一窺直播的業務邏輯了。

直播的業務邏輯

以下是一個最精簡的一對多直播業務模型,以及各個層級之間的協議。

移動直播技術秒開優化經驗(含PPT)

各協議差別對好比下

移動直播技術秒開優化經驗(含PPT)

移動直播技術秒開優化經驗(含PPT)

以上就是關於直播技術的一些基礎概念。下面咱們進一步瞭解下影響人們視覺體驗的直播性能指標。

影響視覺體驗的直播性能指標

直播第一個性能指標是延遲,延遲是數據從信息源發送到目的地所需的時間。

移動直播技術秒開優化經驗(含PPT)

根據愛因斯坦的狹義相對論,光速是全部能量、物質和信息運動所能達到的最高速度,這個結論給傳播速度設定了上限。所以,即使咱們肉眼感受到的實時,實際上也是有必定的延遲。

移動直播技術秒開優化經驗(含PPT)

因爲 RTMP/HLS 是基於 TCP 之上的應用層協議,TCP 三次握手,四次揮手,慢啓動過程當中的每一次往返來回,都會加上一次往返耗時 ( RTT ),這些交互過程都會增長延遲。

移動直播技術秒開優化經驗(含PPT)

其次根據 TCP 丟包重傳特性,網絡抖動可能致使丟包重傳,也會間接致使延遲加大。

移動直播技術秒開優化經驗(含PPT)

一個完整的直播過程,包括但不限於如下環節:採集、處理、編碼、封包、推流、傳輸、轉碼、分發、拉流、解碼、播放。從推流到播放,再通過中間轉發環節,延遲越低,則用戶體驗越好。

第二個直播性能指標卡頓,是指視頻播放過程當中出現畫面滯幀,讓人們明顯感受到「卡」。單位時間內的播放卡頓次數統計稱之爲卡頓率。

形成卡頓的因素有多是推流端發送數據中斷,也有多是公網傳輸擁塞或網絡抖動異常,也有多是終端設備的解碼性能太差。卡頓頻次越少或沒有,則說明用戶體驗越好。

第三個直播性能指標首屏耗時,指第一次點擊播放後,肉眼看到畫面所等待的時間。技術上指播放器解碼第一幀渲染顯示畫面所花的耗時。一般說的 「秒開」,指點擊播放後,一秒內便可看到播放畫面。首屏打開越快,說明用戶體驗越好。

如上三個直播性能指標,分別對應一個低延遲、高清流暢、極速秒開 的用戶體驗訴求。瞭解這三個性能指標,對優化移動直播 APP 的用戶體驗相當重要。

那麼移動直播場景下具體而言有哪些常見的坑呢?

根據實踐總結下來的經驗,移動平臺上視頻直播的坑主要能夠總結爲兩方面:設備差別,以及網絡環境這些場景下帶來的技術考驗。

移動直播場景的坑與規避措施

不一樣芯片平臺上的編碼差別

移動直播技術秒開優化經驗(含PPT)

iOS 平臺上不管硬編仍是軟編,因爲是 Apple 一家公司出廠,幾乎不存在由於芯片平臺不一樣而致使的編碼差別。

然而,在 Android 平臺上,Android Framework SDK 提供的 MediaCodec 編碼器,在不一樣的芯片平臺上,差別表現很大, 不一樣的廠家使用不一樣的芯片,而不一樣的芯片平臺上 Android MediaCodec 表現略有差別,一般實現全平臺兼容的成本不低。

另外就是 Android MediaCodec 硬編層面的 H.264 編碼畫質參數是固定的 baseline,因此畫質一般也通常。所以,在 Android 平臺下,推薦是用軟編,好處是畫質可調控,兼容性也更好。

低端設備如何上高性能地採集和編碼?

移動直播技術秒開優化經驗(含PPT)

例如 Camera 採集輸出的多是圖片,一張圖的體積並不會小,若是採集的頻次很高,編碼的幀率很高,每張圖都通過編碼器,那麼編碼器又可能會出現過載。

這個時候,能夠考慮在編碼前,不影響畫質的前提下(前面咱們講過幀率的微觀意義),進行選擇性丟幀,以此下降編碼環節的功耗開銷。

弱網下如何保障高清流暢推流

移動直播技術秒開優化經驗(含PPT)

移動網絡下,一般容易遇到網絡不穩定,鏈接被重置,斷線重連,一方面頻繁重連,創建鏈接須要開銷。另外一方面尤爲是發生 GPRS / 2G / 3G / 4G 切換時,帶寬可能出現瓶頸。當帶寬不夠,幀率較高/碼率較高的內容較難發送出去,這個時候就須要可變碼率支持。

即在推流端,可檢測網絡狀態和簡單測速,動態來切換碼率,以保障網絡切換時的推流流暢。

其次編碼、封包、推流 這一部分的邏輯也能夠作微調,能夠嘗試選擇性丟幀,好比優先丟視頻參考幀(不丟 I 幀和音頻幀 ),這樣也能夠減小要傳輸的數據內容,但同時又達到了不影響畫質和版視聽流暢的目的。

須要區分直播流的狀態和業務狀態

直播是媒體流、APP 的交互是 API 信令流,二者的狀態不能混爲一談。尤爲是不能基於 APP 的交互的 API 狀態來判斷直播流的狀態。

移動直播技術秒開優化經驗(含PPT)

以上是移動直播場景下常見的幾個坑和規避措施。

移動直播場景其餘優化措施

1、怎麼優化打開速度,達到傳說中的 「秒開」?

你們可能會看到,市面上某些手機直播 APP 的打開速度很是快,一點就開。而某些手機直播 APP,點擊播放後要等好幾秒之後才能播放。是什麼緣由致使如此的天壤之別呢?

大部分播放器都是拿到一個完成的 GOP 後才能解碼播放,基於 FFmpeg 移植的播放器甚至須要等待音畫時間戳同步後才能播放(若是一個直播裏邊沒有音頻只有視頻至關於要等待音頻超時後才能播放畫面)。

「秒開」能夠從如下幾個方面考慮:

1. 改寫播放器邏輯讓播放器拿到第一個關鍵幀後就給予顯示。

GOP 的第一幀一般都是關鍵幀,因爲加載的數據較少,能夠達到 「首幀秒開」。

若是直播服務器支持 GOP 緩存,意味着播放器在和服務器創建鏈接後可當即拿到數據,從而省卻跨地域和跨運營商的回源傳輸時間。

GOP 體現了關鍵幀的週期,也就是兩個關鍵幀之間的距離,即一個幀組的最大幀數。假設一個視頻的恆定幀率是 24fps(即1秒24幀圖像),關鍵幀週期爲 2s,那麼一個 GOP 就是 48 張圖像。通常而言,每一秒視頻至少須要使用一個關鍵幀。

增長關鍵幀個數可改善畫質(GOP 一般爲 FPS 的倍數),可是同時增長了帶寬和網絡負載。這意味着,客戶端播放器下載一個 GOP,畢竟該 GOP 存在必定的數據體積,若是播放端網絡不佳,有可能不是可以快速在秒級之內下載完該 GOP,進而影響觀感體驗。

若是不能更改播放器行爲邏輯爲首幀秒開,直播服務器也能夠作一些取巧處理,好比從緩存 GOP 改爲緩存雙關鍵幀(減小圖像數量),這樣能夠極大程度地減小播放器加載 GOP 要傳輸的內容體積。

2. 在 APP 業務邏輯層面方面優化。

好比提早作好 DNS 解析(省卻幾十毫秒),和提早作好測速選線(擇取最優線路)。通過這樣的預處理後,在點擊播放按鈕時,將極大提升下載性能。

一方面,能夠圍繞傳輸層面作性能優化;另外一方面,能夠圍繞客戶播放行爲作業務邏輯優化。二者能夠有效的互爲補充,做爲秒開的優化空間。

2、美顏等濾鏡如何處理?

在手機直播場景下,這就是一個剛需。沒有美顏功能的手機直播 APP,主播基本不愛用。能夠在採集畫面後,將數據送給編碼器以前,將數據源回調給濾鏡處理程序,原始數據通過濾鏡處理完後,再送回給編碼器進行編碼便可。

除了移動端能夠作體驗優化以外,直播流媒體服務端架構也能夠下降延遲。例如收流服務器主動推送 GOP 至邊緣節點,邊緣節點緩存 GOP,播放端則能夠快速加載,減小回源延遲。

移動直播技術秒開優化經驗(含PPT)

其次,能夠貼近終端就近處理和分發

移動直播技術秒開優化經驗(含PPT)

3、如何保障直播持續播放流暢不卡頓?

「秒開」解決的是直播首次加載的播放體驗,如何保障直播持續播放過程當中的畫面和聲音視聽流暢呢?由於,一個直播畢竟不是一個 HTTP 同樣的一次性請求,而是一個 Socket 層面的長鏈接維持,直到直到主播主動終止推流。

上述咱們講過卡頓的定義:即播放時畫面滯幀,觸發了人們的視覺感覺。在不考慮終端設備性能差別的狀況下,針對網絡傳輸層面的緣由,咱們看看如何保障一個持續的直播不卡頓。

這實際上是一個直播過程當中傳輸網絡不可靠時的容錯問題。例如,播放端臨時斷網了,但又快速恢復了,針對這種場景,播放端若是不作容錯處理,很難不出現黑屏或是從新加載播放的現象。

爲了容忍這種網絡錯誤,並達到讓終端用戶無感知,客戶端播放器能夠考慮構建一個FIFO(先進先出)的緩衝隊列,解碼器從播放緩存隊列讀取數據,緩存隊列從直播服務器源源不斷的下載數據。一般,緩存隊列的容量是以時間爲單位(好比3s),在播放端網絡不可靠時,客戶端緩存區能夠起到「斷網無感」的過渡做用。

顯然,這只是一個「緩兵之計」,若是直播服務器邊緣節點出現故障,而此時客戶端播放器又是長鏈接,在沒法收到對端的鏈接斷開信號,客戶端的緩衝區容量再大也無論用了,這個時候就須要結合客戶端業務邏輯來作調度。

重要的是客戶端結合服務端,能夠作精準調度。在初始化直播推流以前,例如基於 IP 地理位置和運營商的精確調度,分配線路質量最優的邊緣接入節點。在直播推流的過程當中,能夠實時監測幀率反饋等質量數據,基於直播流的質量動態調整線路。

Q & A

1. 關鍵幀設置頻率通常是多少?有沒有根據接入動態設置?過長首屏秒會很難作到。

徐立:關鍵幀間隔越長,也就是 GOP 越長,理論上畫面越高清。可是生成 HLS 直播時,最小切割粒度也是一個 GOP,因此針對交互直播,一般不建議 GOP 設置太長。直播通常 2 個關鍵幀間隔便可。好比幀率是 24fps, 那麼 2 個關鍵幀的間隔就是 48fps ,這個 GOP 就是2s。

2. 七牛這個直播是用的網宿加速?有遇到什麼坑沒?

徐立:七牛在直播方面主要是自建節點,也支持融合衆多第三方 CDN 服務商,多樣化的線路組合爲客戶提供更優質的服務。在和第三方 CDN 合做的過程當中遇到的問題等有機會再作更細粒度的交流和分享。

3. RTMP 直播流除了優化線路外,還有什麼加速手段嗎?

徐立:物理上優化線路,邏輯上優化策略,好比選擇性丟幀,不影響編碼畫質的前提下減輕傳輸體積。

4. OBS 推流,播放端 HLS 出現視/音頻不一樣步是哪一個環節的問題?怎麼優化?

徐立:有多是採集端的問題,若是是採集端編碼環節就出現音畫不一樣步,能夠在收流服務器上作音畫時間戳同步,這樣是全局的校對。若是是播放端解碼性能問題,那麼須要調節播放邏輯,好比保證音畫時間戳強一致性的前提下,選擇性丟一部幀。

5. PPT 前幾頁中一個概念好像錯了,I 幀不是關鍵幀,IDR 幀纔是。IDR 幀是 I 幀,可是 I 幀不必定是 IDR 幀。只有 IDR 幀纔是可重入的。

徐立:中文都把 I 幀翻譯成關鍵幀了,不過既然提到了 IDR 幀,能夠展開說明一下。全部的 IDR 幀都是 I 幀,可是並非全部 I 幀都是 IDR 幀,IDR 幀是 I 幀的子集。I 幀嚴格定義是幀內編碼幀,因爲是一個全幀壓縮編碼幀,一般用 I 幀表示 「關鍵幀」。IDR 是基於 I 幀的一個 「擴展」,帶了控制邏輯,IDR 圖像都是 I 幀圖像,當解碼器解碼到 IDR 圖像時,會當即將參考幀隊列清空,將已解碼的數據所有輸出或拋棄。從新查找參數集,開始一個新的序列。這樣若是前一個序列出現重大錯誤,在這裏能夠得到從新同步的機會。IDR 圖像以後的圖像永遠不會使用 IDR 以前的圖像的數據來解碼。

6. 有沒有調研過 nginx rtmp module,爲何沒有用,對它有什麼評價?

徐立:有調研過,nginx_rtmp_module 是單進程多線程,非 go 這種輕量級線程/協程用併發天然語義的方式編寫流業務。nginx 本來的代碼量較大(約 16 萬行,但和直播業務相關的功能並非不少)。且主要靠寫 nginx.conf 作配置租戶,一般單租戶能夠,但業務可擴展性方面不是很靈活,可知足基本需求,不知足高級功能。

7. 用到了那些開源軟件?編碼用的是 x264 嗎?直播服務器大家本身開發仍是開源的?

徐立:直播服務器用 go 開發的,移動端編碼優先硬編,軟編用 x264

8. 請教一下用 OBS 推流到 nginx_rtmp_module 的時候是已經作了視頻壓縮了仍是須要基於 OBS 再開發?

徐立:OBS 把編碼壓縮都作了,不須要再開發。

9. 視頻直播想在 HLS 流中無縫插入一段廣告的 ts 文件,有問題想請教一下:一、這段 ts 的分辨率是否必定要和以前的視頻流一致?二、pts 時間戳是否要和上一個 ts 遞增?

徐立:一、能夠不一致。這種狀況兩段視頻徹底是獨立狀態,能夠沒有任何關係,只須要插入 discontinue 標記,播放器在識別到這個標記以後重置解碼器參數就能夠無縫播放,畫面會很平滑的切換。二、不須要遞增。舉個例子,視頻 A 正在直播,播放到 pts 在 5s 的時候,插入一個視頻 B,須要先插入一個 discontinue,再插入 B,等 B 播放完以後,再插入一個 discontinue,再插入 A,這個時候 A 的 pts 能夠和以前遞增,也能夠按照中間插入的 B 的時長作偏移,通常作點播和時移的時候 pts 會連續遞增,直播的話會算上 B 的時長。

因爲移動直播在實踐上還有很是多細節,本文未能所有覆蓋,感興趣的朋友歡迎在文章最後留言討論。

最後歡迎讀者將「高可用架構」在訂閱號置頂,更方便瀏覽高可用架構全部文章。

本文策劃 Tim、劉芸,主持人丁一瓊,編輯王傑,更多直播架構請關注公衆號。轉載請註明來自高可用架構「ArchNotes」微信公衆號及包含如下二維碼。

高可用架構

改變互聯網的構建方式

長按二維碼 關注「高可用架構」公衆號

相關文章
相關標籤/搜索