在這個顏值即正義的時代,不論是通過 Web 還是移動端發起直播,美顏與特效已經是很多直播平臺的標配功能。更有甚者,已經開始嘗試將AR融入產品,增加更多可以吸引使用者的體驗。不過要在直播中實現以上任何一個功能,都會對開發者的技術棧提出了進一步的要求。不論是在Web端基於 WebRTC 進行視訊通話或線上教育的產品,還是 Android、iOS 上做直播。本文將簡要梳理實現特效的原理,以及其中需要注意的難點。
直播特效的實現原理
直播的具體流程,包括:採集、前處理、編碼、傳輸、解碼、後處理、播放。通常情況下,我們會在攝像頭採集到視訊影象後,開始對其進行特效處理,也就是在前處理的過程中進行。
實現直播特效的流程如下:
-
採集:視訊的採集源主要有三種:攝像頭採集、螢幕錄製和從視訊檔案推流。直播中常見的是通過攝像頭採集的影象。以Android為例,由於需要進行影象的二次處理(濾鏡、特效),所以使用 SurfaceTexture來處理影象流,給採集到的影象增添特效、濾鏡等。SurfaceTexture 是一個紋理,可以想象成一個 View 的中介軟體。Camera 把視訊採集的內容交給 SurfaceTexture,SurfaceTexture 進行美顏處理,然後把內容交給 SurfaceView,渲染出來。
-
前處理:對採集到的影象進行處理:比如通過均值模糊、高斯模糊和中值濾波等去噪演算法,給原始視訊進行“磨皮”;或者利用 GPUImage 庫,增加濾鏡;又或者是利用 ARCore、ARKit 等工具,為視訊新增實時的 AR 特效。
-
在完成影象的處理後,按照合適位元速率、格式進行編碼。
-
最後,推流到 CDN。
要實現美顏效果,不論是基於 WebRTC 的移動端還是Web端,都可以通過 GPUImage 來實現。如果是基於 WebRTC 與 React Native、GPUImage 相結合即可,不過需要修改 react-native-webrtc 的原始碼。
開發中的難點
在直播中實現特效、濾鏡,甚至AR特效的例子,我們可以在網上找到很多,我們也曾分享過基於 ARCore、ARKit 來實現。不過其中有很多需要開發者注意的難點。
一、缺乏可擴充套件性、靈活性
如果通過 WebRTC 來進行開發,WebRTC 提供的渲染器是基於 GLSurfaceView 的 View 元件。與SurfaceView 相比,它沒有動畫或者變形特效,因為 GLSurfaceView 是視窗 (window)的一部分。 因此,如果想往其他地方繪製,或者獲取視訊資料,就會比較麻煩。
二、需要大量修改原始碼
通過 WebRTC 的 Native API 是無法獲取攝像頭資料的,如果要做美顏,需要做大量改動,比如上述提到的修改 react-native-webrtc 原始碼,也只是其中一部分工作。另外可能還需要調整 WebRTC 原始碼,並不是拿來即用,這就要求開發者要熟悉 WebRTC。
三、效能與功耗問題
效能與功耗問題在 Android 平臺上比較明顯。通常情況下,對影象進行處理時,我們可以選擇輸入 YUV 資料,讓 CPU 進行影象處理,然後交給軟體/硬體編碼器進行編碼。但這樣做會產生較高的 CPU 佔用率,功耗隨之增加,App 響應速度受到影響。所以我們需要儘量使用 GPU 來完成圖形處理,更多地利用硬體效能。
在編碼上也存在相同問題。軟體編碼的優點是靈活度高,但是缺點是功耗高,影響效能。硬體編碼則相對速度更快、功耗更低,是更優的選擇。但它的問題在於,能做的優化和引數調整,取決於硬體廠商開放的介面。而且硬體編碼在部分 Android 手機上的相容性也存在問題。
四、硬體相容性問題
WebRTC 等自研方案還需要考慮硬體的相容性問題。iOS 裝置相對簡單,但是在 Android 裝置上,不同晶片、系統版本等因素,存在相容問題。
Agora SDK 2.1版:實現直播特效更靈活
相對於這種自研來講,聲網Agora SDK 將採集和渲染開放,開發者可以更靈活的處理視訊資料。如下圖綠色部分所示,處理許可權開放給開發者,帶來更大的靈活性與擴充套件性。
Capture(採集):聲網Agora SDK 支援自定義的視訊源型別,可以方便利用我們提供的輔助類構建 camera 視訊源,或者螢幕共享視訊源,或者檔案視訊源等。
新增特效:Agora SDK 的新介面直接利用 Android 系統元件Surface Texture 處理,並傳遞給 GPU,最後通過Agora SDK 硬體編碼器進行視訊編碼。整條鏈路上最大限度發揮硬體效能,不經過記憶體拷貝,不僅可以獲得更好的效能與功耗表現,避免影響 App 響應速度,也無需擔心硬體編解碼問題。
Renderer(渲染):聲網Agora SDK 開放了視訊渲染器的介面,使用者可以靈活的根據現有的業務,向 Android 標準的 SurfaceView,TextureView元件上或者是自定義的 View 元件上渲染。
開放新功能帶來的差異
升級2.1版之前:
在2.1之前的版本中,開發者需要通過 pushExternalVideoSource 介面,以共享Texture id 的方式來實現特效、美顏等功能,即需要傳入texture 所在的 EGL Context,以及Texture 的id。
升級2.1之後:
通過2.1版的自定義視訊源、自定義渲染器兩個新功能,能更靈活地實現想要的效果。通過它們,開發者可以使用原有的共享 texture id 的方式,也可以利用系統元件,如 SurfaceTexture 或者 Surface 來傳遞 texture。例如,TextureSource 類封裝了 SurfaceTexture 物件,開發者可以利用它建立出 EglSurface,美顏處理後得到紋理資料,直接繪製到 EglSurface 上即可。
這兩個功能給了我們在視訊、影象渲染方面提供更開放的想象空間,可以在直播中實現更多場景,比如我們此前結合 ARCore、ARKit 實現的 AR 場景,再比如類似抖音跳舞機的遊戲也能放到直播中。
在 Agora SDK 2.1 中,我們為自定義視訊源與自定義渲染器增加了多個新介面,點選這裡瞭解更多詳情與介面呼叫方法。