短視頻技術詳解:Android端的短視頻開發技術

在《如何快速實現移動端短視頻功能?》中,我們主要介紹了當前短視頻的大熱趨勢以及開發一個短視頻應用所涉及到的功能和業務。在本篇文章中,我們主要談一談短視頻在Android端上的具體實現技術。
推薦閱讀
《視頻私有云實戰:基於Docker構建點播私有云平臺》

《如何快速實現移動端短視頻功能》

短視頻業務主要包含:“視頻錄製”以及 “視頻編輯”這兩個核心功能。

其中視頻錄製又包括:視頻採集、實時美顏、自定義碼率、攝像頭切換、變焦、對焦、曝光度調節以及濾鏡等功能。

視頻編輯包括:視頻裁剪、視頻拼接、混音、視頻動畫效果、動態貼圖等功能。

Android端短視頻錄製的技術方案
我們先來說說視頻錄製:

視頻錄製的大致實現流程就如上圖所示,先由Camera、AudioRecord進行最原始的相機畫面以及聲音的採集,然後將採集的數據進行濾鏡、降噪等前處理,處理完成後由MediaCodec進行硬件編碼,最後採用MediaMuxer生成最終的MP4文件。

這個方案的優點在於,由於全程採用了GPU以及硬件編碼,基本上不涉及CPU上的操作,因此可實現在高幀率(30fps)、高分辨率(720P)以及高碼率的情況下CPU暫用率也非常低,即使在性能較差的手機上也能很好的運行。但同時這個方案的難點也在於此。

做過音視頻的同學都知道,通常情況下我們所說的對音視頻的處理,主要是對視頻的 YUV、H264 音頻的PCM、AAC這類數據格式進行操作,這類操作都有相關的RFC技術也比較成熟,實現起來比較容易,出了問題也更容易定位,通常情況下在PC等設備上也都是這麼處理的。

但這樣的方案在對於手機端情況就不同了,雖然手機這幾年的性能大大加強了,很多旗艦手機基本都是8核的CPU了,但要操作如此大量的圖片數據並進行浮點運算對CPU的消耗還是很大的。CPU暫用率高就會引起手機發燙,手機發燙就會導致Camera採集的掉幀,甚至在一些小米等廠商下,手機發燙還會引起CPU降頻,CPU一降頻那APP所暫用的CPU比例就更高了,同時CPU暫用率高電量消耗就快。

因此上面的方案是目前Android上比較適合短視頻錄製的方案。

Android端短視頻錄製的具體實現
既然確定了技術方案,我們就來看看具體的實現。這裏首先需要知道幾個概念:

SurfaceTexture

我們知道在一些簡單的自定義相機應用中,要實現一個相機,只需要將一個SurfaceHolder設置給Camera,Android系統就會自動的幫我們把Camera採集的數據繪製到屏幕上。但由於在短視頻中我們需要對相機採集的數據進行前處理加工比如濾鏡等,而且還要做到可見即所得的效果,因此必須要求我們將相機採集的數據先緩存起來,前處理完後自己再繪製到屏幕上,這時候就需要用到SurfaceTexture了。按照Android官方文檔的介紹,SurfaceTexture就是這樣一塊用於接收Camera採集的數據,同時又不可見的畫布。這塊畫布是存在於GPU內存中的。

TextureID
紋理ID,主要用來標識每一塊紋理在GPU內存中的內存地址,類似於C語言中的內存指針。每一塊GPU的紋理(可以理解爲一塊用於顯示圖片的畫布)都有對應的一個TextureID進行標識。上述的SurfaceTexture在創建也同樣需要綁定一個紋理ID進行唯一標識。

知道了這兩個概念,我們就知道了Camera採集的數據具體存在於GPU的哪個位置了。接下來就可以對原始的數據進行前處理編碼了。

這裏有一個需要注意的地方,Android的camera採集到SurfaceTexture上的紋理是GL_TEXTURE_EXTERNAL_OES 類型的紋理,而目前市面的很多濾鏡算法,如開源的GPUImage中很多的濾鏡都是基於GL_TEXTURE_2D類型的紋理進行圖像處理的。

因此在進行我們在基於開源濾鏡算法或自研算法時需要先將GL_TEXTURE_EXTERNAL_OES類型的紋理轉化爲GL_TEXTURE_2D的紋理,或者在GPU Shader中加入 "#extension GL_OES_EGL_image_external: require" 來表明該紋理是OES紋理,同時編寫基於OES紋理的圖像處理算法。

目前網易這邊是先將OES轉化爲TEXTURE_2D在進行前處理,這樣便於與iOS端算法統一以及更好的接入一些開源的濾鏡算法。

解決了SurfaceTexture的問題,接下來的MediaCodec以及MediaMuxer就比較容易了。Android中的MediaCodec天生支持將GPU中的紋理繪製到MediaCodec的Surface中,然後對Surface中的圖像直接進行硬件編碼,圖像數據始終是在GPU空間中進行流轉,而沒有涉及到CPU。

這裏需要注意的是MediaCodec以及MediaMuxer需要在API 18及以上才能使用。同時需要注意MediaCodec在不同設備上的兼容性。

Android端視頻編輯功能
最後對於視頻編輯的功能,目前Android上沒有很好的系統API即硬件處理方式,主要還是利用ffmpeg進行相應的疊加、裁剪混音等後期處理。可以優化的一個點是,先將原始的MP4視頻進行解碼,然後將解碼後的YUV數據映射到GPU的紋理上進行亮度、飽和度等參數的調節,做到文件編輯的所見即所得,然後將調好的參數配置爲ffmpeg進行編輯處理。

想要獲取更多產品乾貨、技術乾貨,記得關注網易雲信博客。

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