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

轉:https://www.cnblogs.com/jhj117/p/5455761.html

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

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

直播常見的問題包括

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

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

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

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

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

  • 美顏等濾鏡特效處理怎麼做?

  • 如何實現播放秒開?

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

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

視頻、直播等基礎知識

什麼是視頻?

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

移動直播技術秒開優化經驗(含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)

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

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

一、怎麼優化打開速度,達到傳說中的 “秒開”?

大家可能會看到,市面上某些手機直播 APP 的打開速度非常快,一點就開。而某些手機直播 APP,點擊播放後要等好幾秒以後才能播放。是什麼原因導致如此的天壤之別呢?

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

“秒開”可以從以下幾個方面考慮:

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

GOP 的第一幀通常都是關鍵幀,由於加載的數據較少,可以達到 “首幀秒開”。

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

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

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

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

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

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

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

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

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

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

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

其次,可以貼近終端就近處理和分發

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

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

“秒開”解決的是直播首次加載的播放體驗,如何保障直播持續播放過程中的畫面和聲音視聽流暢呢?因爲,一個直播畢竟不是一個 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 文件,有問題想請教一下:1、這段 ts 的分辨率是否一定要和之前的視頻流一致?2、pts 時間戳是否要和上一個 ts 遞增?

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

由於移動直播在實踐上還有非常多細節,本文未能全部覆蓋,感興趣的朋友歡迎在文章最後留言討論。

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

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

高可用架構

改變互聯網的構建方式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章