《視頻直播技術詳解》系列之一:視頻採集和處理

直播中的各個環節:

1.採集

採集是播放環節中的第一環,iOS 系統因爲軟硬件種類不多,硬件適配性較好,所以比較簡單。Android 則不同,市面上硬件機型非常多,難以做到一個庫適配所有硬件。PC 端的採集也跟各種攝像頭驅動有關,推薦使用目前市面上最好用的 PC 端開源免費軟件 OBS。

2.處理

「80% 的主播沒有美顏根本沒法看。」不光是美顏,很多其它的視頻處理如模糊效果、水印等也都是在這個環節做。目前 iOS 端比較知名的是 GPUImage 這個庫,提供了豐富端預處理效果,還可以基於這個庫自己寫算法實現更豐富端效果。Android 也有 GPUImage 這個庫的移植,叫做 android-gpuimage。同時,Google 官方開源了一個偉大的庫,覆蓋了 Android 上面很多多媒體和圖形圖像相關的處理。

3.編碼

編碼主要難點有兩個:1. 處理硬件兼容性問題。2. 在高 fps、低 bitrate 和音質畫質之間找到平衡。iOS 端硬件兼容性較好,可以直接採用硬編。而 Android 的硬編的支持則難得多,需要支持各種硬件機型,推薦使用軟編。

4.推流和傳輸

傳輸涉及到很多端:從主播端到服務端,從收流服務端到邊緣節點,以及再從邊緣節點到觀衆端。
推流端和分發端理論上需要支持的併發用戶數應該都是億級的,不過畢竟產生內容的推流端在少數,和消費內容端播放端不是一個量級,但是他們對推流穩定性和速度的要求比播放端高很多,這涉及到所有播放端能否看到直播,以及直播端質量如何。
很多人吐槽現在的 CDN 不靠譜,我也承認傳統的 CDN 在新時代顯得心有餘力不足。你能夠藉助 CDN 快速實現大規模的流分發,但是穩定高速的推流上傳可能還需要自己做很多工作。因此,我們七牛打造了一個直播專屬的實時流網絡,接下來我們會重點介紹這個網絡和傳統 CDN 的差別。

5.轉碼

爲了讓主播推上來的流適配各個平臺端各種不同協議,需要在服務端做一些流處理工作,比如轉碼成不同格式支持不同協議如 RTMP、HLS 和 FLV,一路轉多路流來適配各種不同的網絡狀況和不同分辨率的終端設備。
同時,爲了配合一些運營需求,比如一些監管部門的要求,我們在服務端也提供了內容識別如鑑黃的功能。

6.解碼和渲染

解碼和渲染,也即音視頻的播放,目前 iOS 端的播放兼容性較好,在延遲可接受的情況下使用 HLS 協議是最好的選擇,我們也提供了能夠播放 RTMP 和 HLS 的播放器 SDK。Android 的硬件解碼和編碼一樣也存在兼容性問題,目前比較好的開源播放器是基於 ffplay 的 ijkplayer,我們也基於此實現了一個更好的 Android SDK。
除了 SDK 的介紹之外,我們將重點介紹播放器的原理,以及現代視頻播放器的基本架構。

7.直播場景化解決方案

除了整個直播流程的介紹之外,我們將圍繞當下最火的直播場景如社交直播和遊戲直播,介紹它背後的技術方案。這些技術方案不僅涉及到七牛這樣的直播基礎服務,還可能涉及到和場景相關的其它技術,如社交直播下的聊天、點贊和彈幕的支持。

採集內容

1.音頻採集

音頻數據既能與圖像結合組合成視頻數據,也能以純音頻的方式採集播放,後者在很多成熟的應用場景如在線電臺和語音電臺等起着非常重要的作用。音頻的採集過程主要通過設備將環境中的模擬信號採集成 PCM 編碼的原始數據,然後編碼壓縮成 MP3 等格式的數據分發出去。常見的音頻壓縮格式有:MP3,AAC,OGG,WMA,Opus,FLAC,APE,m4a 和 AMR 等。

音頻採集和編碼主要面臨的挑戰在於:延時敏感、卡頓敏感、噪聲消除(Denoise)、回聲消除(AEC)、靜音檢測(VAD)和各種混音算法等。

在音頻採集階段,參考的主要技術參數有 :

  • 採樣率(samplerate):採樣就是把模擬信號數字化的過程,採樣頻率越高,記錄這一段音頻信號所用的數據量就越大,同時音頻質量也就越高。

  • 位寬:每一個採樣點都需要用一個數值來表示大小,這個數值的數據類型大小可以是:4bit、8bit、16bit、32bit 等等,位數越多,表示得就越精細,聲音質量自然就越好,而數據量也會成倍增大。我們在音頻採樣過程中常用的位寬是 8bit 或者 16bit。

  • 聲道數(channels):由於音頻的採集和播放是可以疊加的,因此,可以同時從多個音頻源採集聲音,並分別輸出到不同的揚聲器,故聲道數一般表示聲音錄製時的音源數量或回放時相應的揚聲器數量。聲道數爲 1 和 2 分別稱爲單聲道和雙聲道,是比較常見的聲道參數。

  • 音頻幀(frame):音頻跟視頻很不一樣,視頻每一幀就是一張圖像,而從上面的正玄波可以看出,音頻數據是流式的,本身沒有明確的一幀幀的概念,在實際的應用中,爲了音頻算法處理/傳輸的方便,一般約定俗成取 2.5ms~60ms 爲單位的數據量爲一幀音頻。這個時間被稱之爲“採樣時間”,其長度沒有特別的標準,它是根據編解碼器和具體應用的需求來決定的。

根據以上定義,我們可以計算一下一幀音頻幀的大小。假設某音頻信號是採樣率爲 8kHz、雙通道、位寬爲 16bit,20ms 一幀,則一幀音頻數據的大小爲:

size = 8000 x 2 x 16bit x 0.02s = 5120 bit = 640 byte

2.圖像採集

圖像採集的圖片結果組合成一組連續播放的動畫,即構成視頻中可肉眼觀看的內容。圖像的採集過程主要由攝像頭等設備拍攝成 YUV 編碼的原始數據,然後經過編碼壓縮成 H.264 等格式的數據分發出去。常見的視頻封裝格式有:MP4、3GP、AVI、MKV、WMV、MPG、VOB、FLV、SWF、MOV、RMVB 和 WebM 等。

圖像由於其直觀感受最強並且體積也比較大,構成了一個視頻內容的主要部分。圖像採集和編碼面臨的主要挑戰在於:設備兼容性差、延時敏感、卡頓敏感以及各種對圖像的處理操作如美顏和水印等。

在圖像採集階段,參考的主要技術參數有:

  • 圖像傳輸格式:通用影像傳輸格式(Common Intermediate Format)是視訊會議(video conference)中常使用的影像傳輸格式。

  • 圖像格式:通常採用 YUV 格式存儲原始數據信息,其中包含用 8 位表示的黑白圖像灰度值,以及可由 RGB 三種色彩組合成的彩色圖像。

  • 傳輸通道:正常情況下視頻的拍攝只需 1 路通道,隨着 VR 和 AR 技術的日漸成熟,爲了拍攝一個完整的 360° 視頻,可能需要通過不同角度拍攝,然後經過多通道傳輸後合成。

  • 分辨率:隨着設備屏幕尺寸的日益增多,視頻採集過程中原始視頻分辨率起着越來越重要的作用,後續處理環節中使用的所有視頻分辨率的定義都以原始視頻分辨率爲基礎。視頻採集卡能支持的最大點陣反映了其分辨率的性能。

  • 採樣頻率:採樣頻率反映了採集卡處理圖像的速度和能力。在進行高度圖像採集時,需要注意採集卡的採樣頻率是否滿足要求。採樣率越高,圖像質量越高,同時保存這些圖像信息的數據量也越大。

以上,構成了一個視頻採集的主要技術參數,以及視頻中音頻和圖像編碼的常用格式。而對於直播 App 開發者來說,瞭解這些細節雖然更有幫助,但實際開發過程中可能很少能夠關注採集環節中技術參數的控制,而是直接在 SDK 中將採集後的數據傳遞給下一個「處理」和「編碼」環節。

 

採集源

1.攝像頭採集

對於視頻內容的採集,目前攝像頭採集是社交直播中最常見的採集方式,比如主播使用手機的前置和後置攝像頭拍攝。在現場直播場景中,也有專業的攝影、攝像設備用來採集。安防監控場景中也有專業的攝像頭進行監控採集。

目前七牛提供的 SDK 對以上兩類攝像頭的採集都支持,對於手機,iOS 和 Android 分別支持前置後置攝像頭的採集,只是 iOS 由於設備種類和系統版本不多,因此採集模塊兼容性較好;而 Android 需要適配的硬件設備和系統則非常多,目前支持 Android 4.0.3 及以上的攝像頭採集。對於專業攝像機或者攝像頭,七牛雲提供了兼容適合嵌入式系統的 C 語言採集模塊的實現,歡迎參考使用:https://github.com/pili-engineering/ipcam_sdk

2.屏幕錄製

屏幕錄製採集的方式在遊戲直播場景中非常常見,目前我們在 Android SDK 中實現了屏幕錄製的功能。而 iOS 則由於系統本身沒有開放屏幕錄製的權限而沒法直接操作,但對於 iOS 9 以上的版本,是有個取巧的辦法,可以通過模擬一個 AirPlay 鏡像連接到(當前 App)自身,這樣就可以在軟件上捕獲到屏幕上的任何操作,達到錄製屏幕的效果。

在教育直播或者會場演講場合,我們經常看見需要錄製電腦桌面上 PPT 的場景,針對這種場景,目前市面上比較方便的方案是使用開源的桌面推流工具 OBS 來進行屏幕錄製和推流:https://obsproject.com/ 

3.從視頻文件推流

除了從硬件設備採集視頻進行推流之外,我們也可能需要將一個視頻或者音頻文件以直播流的形式實時傳輸給觀衆,比如在線電臺或者電視節目,它們的輸入可能直接來自於一些已經錄製剪輯好的視頻內容。

 

開放式設計

以上從採集內容和採集源兩個維度分別介紹了視頻採集相關的知識,但對於採集源來說,市場上可見的採集源遠遠不止這三種,即便是攝像頭也有很多分類。對於一個完整的覆蓋推流、傳輸和播放三個環節的直播雲服務來說,支持儘可能多的採集源和播放終端是一項既無法規避也很難完成的工作。

爲了支持市場上所有采集源的接入,我們在 SDK 中採用了開放式的設計,只要採集源實現方遵循相應的接口,即可支持任意的採集源。

《視頻直播技術詳解》系列之一:視頻採集和處理0

圖中我們把採集的內容分爲圖像和音頻,其中圖像的採集源包含攝像頭、屏幕錄製或者本地的視頻文件,甚至是其它需要重新定義和實現的採集源。而音頻的採集源包含麥克風、系統聲音或者本地音頻文件,當然也可以爲它定義別的輸入源。

這樣設計最大的好處在於,可以以輕量的設計方式支持豐富的採集源,而採集源的具體實現也可以交給使用者。

我們將講解常見視頻處理功能如美顏、視頻水印、濾鏡、連麥等。

《視頻直播技術詳解》系列之一:視頻採集和處理1

視頻或者音頻完成採集之後得到原始數據,爲了增強一些現場效果或者加上一些額外的效果,我們一般會在將其編碼壓縮前進行處理,比如打上時間戳或者公司 Logo 的水印,祛斑美顏和聲音混淆等處理。在主播和觀衆連麥場景中,主播需要和某個或者多個觀衆進行對話,並將對話結果實時分享給其他所有觀衆,連麥的處理也有部分工作在推流端完成。

開放式設計 《視頻直播技術詳解》系列之一:視頻採集和處理2

如上圖所示,處理環節中分爲音頻和視頻處理,音頻處理中具體包含混音、降噪和聲音特效等處理,視頻處理中包含美顏、水印、以及各種自定義濾鏡等處理。對於七牛這樣的直播雲服務來說,爲了滿足所有客戶的需求,除了要提供這些「標準」處理功能之外,我們還需要將該模塊設計成可自由接入自定義處理功能的方式。

iOS SDK 地址:https://github.com/pili-engineering/PLMediaStreamingKit

Android SDK 地址:https://github.com/pili-engineering/PLDroidMediaStreaming

常見視頻處理功能

1. 美顏 

都說「80% 的主播沒有美顏根本沒法看」,美顏是直播產品中最常見的功能之一。最近準備在香港上市的美圖公司的主打產品就是美顏相機和美拍,有媒體戲稱其會衝擊化妝品行業,其實就是美顏的效果的功勞,讓美女主播們不化妝也可以自信的直播,而美顏相機的用戶則可以拍出「更好的自己」。

美顏的主要原理是通過「磨皮+美白」來達到整體美顏的效果。磨皮的技術術語是「去噪」,也即對圖像中的噪點進行去除或者模糊化處理,常見的去噪算法有均值模糊、高斯模糊和中值濾波等。當然, 由於臉部的每個部位不盡相同,臉上的雀斑可能呈現出眼睛黑點的樣子,對整張圖像進行「去噪」處理的時候不需要將眼睛也去掉,因此這個環節中也涉及到人臉和皮膚檢測技術。

七牛直播雲提供的 iOS 和 Android 推流 SDK 中內置了美顏功能,你可以根據自己的需要選擇開關美顏功能,並且能夠自由調節包括美顏,美白,紅潤等在內的參數。其中 iOS 端 SDK PLCameraStreamingKit 的參數設置如下:

1)按照默認參數開啓或關閉美顏:

  1. -(void)setBeautifyModeOn:(BOOL)beautifyModeOn;

2)設置美顏程度,範圍爲 0 ~ 1:

  1. -(void)setBeautify:(CGFloat)beautify;

3)設置美白程度,範圍爲 0 ~ 1

  1. -(void)setWhiten:(CGFloat)whiten;

4)設置紅潤程度,範圍爲 0 ~ 1

  1. -(void)setRedden:(CGFloat)redden;

2. 視頻水印 

水印是圖片和視頻內容中常見的功能之一,它可用於簡單是版權保護,或者進行廣告設置。處於監管的需求,國家相關部門也規定視頻直播過程中必須打上水印,同時直播的視頻必須錄製存儲下來保存一定的時間,並在錄製的視頻上打上水印。

視頻水印包括播放器水印和視頻內嵌水印兩種方式可供選擇,對於播放器水印來說,如果沒有有效的防盜措施,對於沒有播放鑑權的推流,客戶端拿到直播流之後可以在任何一個不帶水印的播放器裏面播放,因此也就失去了視頻保護的能力。綜合考慮雲端錄製對於水印的需求,我們一般會選擇「視頻內嵌水印」的方式打水印。

七牛直播雲提供的 iOS 和 Android 推流 SDK 中也內置了水印功能,你可以根據自己的需要添加水印或移除水印,並且能夠自由設置水印的大小和位置。其中 iOS 端 SDK PLCameraStreamingKit 的參數設置如下:

1)添加水印

  1. -(void)setWaterMarkWithImage:(UIImage *)wateMarkImage position:(CGPoint)position;

該方法將爲直播流添加一個水印,水印的大小由 wateMarkImage 的大小決定,位置由 position 決定,需要注意的是這些值都是以採集數據的像素點爲單位的。例如我們使用AVCaptureSessionPreset1280x720 進行採集,同時 wateMarkImage.size 爲 (100, 100) 對應的origin 爲 (200, 300),那麼水印的位置將在大小爲 1280×720 的採集畫幅中位於 (200, 300) 的位置,大小爲 (100, 100)。

2)移除水印

  1. -(void)clearWaterMark;

3. 濾鏡 

除了上面提到的美顏和水印之外,視頻中還有很多其它的處理效果也在這個環節完成。七牛直播雲提供的 SDK 在開放性設計基礎之上,通過數據源回調接口,可以支持各種自定義濾鏡的接入。

爲了實現豐富的濾鏡效果,在 iOS 端可以考慮使用 GPUImage 這個庫,這是一個開源的基於GPU的圖片或視頻的處理框架,內置了多達120多種常見的濾鏡效果。有了它,添加實時的濾鏡只需要簡單地添加幾行代碼,還可以基於這個庫自己寫算法實現更豐富端效果。GPUImage 地址:https://github.com/BradLarson/GPUImage

除了 iOS 端之外,Android 也有 GPUImage 這個庫的移植:https://github.com/CyberAgent/android-gpuimage

同時,Google 官方也開源了一個偉大的庫,覆蓋了 Android 上面很多多媒體和圖形圖像相關的處理:https://github.com/google/grafika

4. 連麥

《視頻直播技術詳解》系列之一:視頻採集和處理3

連麥是互動直播中常見的需求,其流程如上圖所示。主播和部分觀衆之間可以進行實時互動,然後將互動結果實時播放給其他觀衆觀看。

基於以上業務需求,我們很容易想到基於單向直播原理,在主播端和連麥觀衆端進行雙向推流和雙向播流的方式互動,然後在服務端將兩路推流合成一路推送給其他觀衆。但 RTMP 帶來的延遲決定了這種方式無法做到用戶可接受的互動直播。

實際上,互動直播的主要技術難點在於:

  • 低延遲互動:保證主播和互動觀衆之間能夠實時互動,兩者之間就像電話溝通,因此必須保證兩者能在秒級以內聽到對方的聲音,看到對方的視頻;

  • 音畫同步:互動直播中對音畫同步的需求和單向直播中類似,只不過互動直播中的延遲要求更高,必須保證在音視頻秒級傳輸情況下的秒級同步。

  • 音視頻實時合成:其他觀衆需要實時觀看到對話結果,因此需要在客戶端或者服務端將畫面和聲音實時合成,然後以低成本高品質的方式傳輸觀衆端。

在視頻和電話會議領域,目前比較成熟的方案是使用思科或者 WebEx 的方案,但這些商用的方案一不開源,二比較封閉,三成本比較高。對於互動人數比較少的互動直播,目前市場上比較成熟的方案是使用基於 WebRTC 的實時通訊方案。《視頻直播技術詳解》系列之一:視頻採集和處理4

上圖是一個基於 WebRTC 協議實現多方實時通訊的示意圖,本地用戶(主播)和遠程用戶(連麥觀衆)之間的連接通過 RTCPeerConnection API 管理,這個 API 包裝了底層流管理和信令控制相關的細節。基於該方案可以輕鬆實現多人(14 人以下)的多方實時通信,如下圖所示:《視頻直播技術詳解》系列之一:視頻採集和處理5

當然,在通信人數少的情況下,其複雜度相對簡單,如 2 人情況下。但人數增多至 4 人之後,其可選的網絡結構就增多了,如上圖所示,可以每個點之間形成自組織網絡的方式通信,也可以以 1 人爲中心形成星型通信網絡,還可以讓大家都通過一個集中式的服務端進行通信。《視頻直播技術詳解》系列之一:視頻採集和處理6
作爲一個高性能、可伸縮的直播基礎服務提供商,七牛直播雲經過評估選擇了以主播爲中心形成星形通信網絡,支持主播和多個觀衆之間的互動質量。同時,爲了保證合成後的音視頻實時傳輸到其他觀衆端,這裏採用經過改造的 UDP 協議傳輸:

  • 通過 UDP 降低傳輸延遲。

  • 在 UDP 之上進行傳輸控制,保證用戶互動體驗 QoS。


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