天天看點

Android 音視訊涉及到的技術總結

作者:音視訊流媒體技術

前言

現在市面上的圖像,音視訊軟體越來越多,最近兩年也是直播,短視訊的紅利期。而圖像、音視訊一直是網際網路視覺的入口,掌握并熟練運用音視訊、圖像技術已經是目前網際網路時代不可或缺的技能,而且這個技能是具有沉澱性質的。

目前市面上的學習資料參差不齊,我覺得想要開啟音視訊的學習之路,先得了解整體流程上會涉及的技術點,再一個個擊破。我也是音視訊方面的小白,最近公司要做一個視訊換臉的應用,目前處于技術調研期。趁此空檔,我準備開始我的音視訊學習之路。

音視訊 app

圖像類:

Android 音視訊涉及到的技術總結
Android 音視訊涉及到的技術總結

音頻類:

Android 音視訊涉及到的技術總結
Android 音視訊涉及到的技術總結

視訊類:

Android 音視訊涉及到的技術總結
Android 音視訊涉及到的技術總結

整體流程

以手機直播為例,其整體流程如下:

Android 音視訊涉及到的技術總結

資料采集

1. 音頻采集

音頻采集涉及到以下幾點:

  • 檢測麥克風是否可以使用;
  • 需要檢測手機對某個音頻采樣率的支援;
  • 在一些情況下需要對音頻進行回聲消除處理;
  • 音頻采集時設定正确的緩沖區大小。

在 Android 系統中,一般使用 AudioRecord 或者 MediaRecord 來采集音頻。AudioRecord 是一個比較偏底層的 API,它可以擷取到一幀幀 PCM 資料,之後可以對這些資料進行處理。而 MediaRecorder 是基于 AudioRecorder 的 API (最終還是會建立AudioRecord 用來與 AudioFlinger 進行互動) ,它可以直接将采集到的音頻資料轉化為執行的編碼格式,并儲存。

相關學習資料推薦,點選下方連結免費報名,先碼住不迷路~】

【免費分享】音視訊學習資料包、大廠面試題、技術視訊和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點選加群免費領取~

Android 音視訊涉及到的技術總結

2. 視訊采集

視訊采集涉及到以下幾點:

  • 檢測攝像頭是否可以使用;
  • 攝像頭采集到的圖像是橫向的,需要對采集到的圖像進行一定的旋轉後再進行顯示;
  • 攝像頭采集時有一系列的圖像大小可以選擇,當采集的圖像大小和手機螢幕大小比例不一緻時,需要進行特殊處理;
  • Android 手機攝像頭有一系列的狀态,需要在正确的狀态下才能對攝像頭進行相應的操作。
  • Android 手機攝像頭的很多參數存在相容性問題,需要較好地處理這些相容性的問題。

在 Android 系統下有兩套 API 可以進行視訊采集,它們是 Camera 和 Camera2 。Camera是以前老的 API ,從 Android 5.0(21) 之後就已經放棄了。和音頻一樣,也有高層和低層的 API,高層就是 Camera 和 MediaRecorder,可以快速實作編碼,低層就是直接使用 Camera,然後将采集的資料進行濾鏡、降噪等前處理,處理完成後由 MediaCodec 進行硬體編碼,最後采用 MediaMuxer 生成最終的視訊檔案。

資料處理

1. 音頻處理

可以對音頻的原始流做處理,如降噪、回音、以及各種 filter 效果。

2. 視訊處理

現在抖音、美圖秀秀等,在拍攝,視訊處理方面,都提供了很多視訊濾鏡,而且還有各種貼紙、場景、人臉識别、特效、添加水印等。

其實對視訊進行美顔和添加特效都是通過 OpenGL 進行處理的。Android 中有 GLSurfaceView,這個類似于 SurfaceView,不過可以利用 Renderer 對其進行渲染。通過 OpenGL 可以生成紋理,通過紋理的 Id 可以生成 SurfaceTexture,而 SurfaceTexture 可以交給 Camera,最後通過紋理就将攝像頭預覽畫面和 OpenGL 建立了聯系,進而可以通過 OpenGL 進行一系列的操作。

美顔的整個過程無非是根據 Camera 預覽的紋理通過 OpenGL 中 FBO 技術生成一個新的紋理,然後在 Renderer 中的onDrawFrame() 使用新的紋理進行繪制。添加水印也就是先将一張圖檔轉換為紋理,然後利用 OpenGL 進行繪制。添加動态挂件特效則比較複雜,先要根據目前的預覽圖檔進行算法分析識别人臉部相應部位,然後在各個相應部位上繪制相應的圖像,整個過程的實作有一定的難度,人臉識别技術目前有 OpenCV、Dlib、MTCNN 等。

資料編碼

1. 音頻編碼

Android 中利用 AudioRecord 可以錄制聲音,錄制出來的聲音是 PCM 聲音,使用三個參數來表示聲音,它們是:聲道數、采樣位數和采樣頻率。如果音頻全部用 PCM 的格式進行傳輸,則占用帶寬比較大,是以在傳輸之前需要對音頻進行編碼。

現在已經有一些廣泛使用的聲音格式,如:WAV、MIDI、MP3、WMA、AAC、Ogg 等等。相比于 PCM 格式而言,這些格式對聲音資料進行了壓縮處理,可以降低傳輸帶寬。對音頻進行編碼也可以分為軟編和硬編兩種。軟編則下載下傳相應的編碼庫,寫好相應的 JNI,然後傳入資料進行編碼。硬編則是使用 Android 自身提供的 MediaCodec。

寫死和軟編碼的差別是:軟編碼可以在運作時确定、修改;而寫死是不能夠改變的。

2. 視訊編碼

在 Android 平台上實作視訊的編碼有兩種實作方式:一種是軟編,一種是硬編。軟編的話,往往是依托于 cpu,利用 cpu 的計算能力去進行編碼。比如我們可以下載下傳 x264 編碼庫,寫好相關的 JNI 接口,然後傳入相應的圖像資料。經過 x264 庫的處理以後就将原始的圖像轉換成為 h264 格式的視訊。

硬編則是采用 Android 自身提供的 MediaCodec,使用 MediaCodec 需要傳入相應的資料,這些資料可以是 YUV 的圖像資訊,也可以是一個 Surface,一般推薦使用 Surface,這樣的話效率更高。Surface 直接使用本地視訊資料緩存,而沒有映射或複制它們到 ByteBuffers;是以,這種方式會更加高效。在使用 Surface 的時候,通常不能直接通路原始視訊資料,但是可以使用ImageReader 類來通路不可靠的解碼後 (或原始) 的視訊幀。這可能仍然比使用 ByteBuffers 更加高效,因為一些本地緩存可以被映射到 direct ByteBuffers。當使用 ByteBuffer 模式,可以利用 Image 類和 getInput/OutputImage(int) 方法來通路到原始視訊資料幀。

音視訊混合

下面我盜了一張圖,畫圖實在太費時間:

Android 音視訊涉及到的技術總結

以合成 MP4 視訊為例:

  1. 整體來看,合成的 MP4 檔案,視訊部分為 H.264 編碼格式的資料,音頻部分為 AAC 編碼格式的資料。
  1. 通過 MediaMuxer 提供的接口-writeSampleData(),将 H.264 和 AAC 資料分别同時寫入到 MP4 檔案。

資料傳輸

  • 目前比較主流的視訊推流協定有 RTMP 協定、RTSP 協定。

涉及的技術

涉及到如下技術,我将從圖像、音頻、視訊的順序來羅列:

  1. Camera、Camera2。
  2. SurfaceView、TextureView、SurfaceTexture、GLSurfaceView。
  3. OpenGL ES。
  4. OpenCV、DLIB。
  5. YUV、PCM、H.264、H.265、ACC。
  6. AudioRecord、AudioTrack。
  7. MediaRecorder。
  8. MediaCodec。
  9. MediaExtractor、MediaMuxer。
  10. ffmpeg、ijkplayer。
  11. RTMP、RTSP。

後面我将針對這些技術,總結下音視訊相關的技術,有需要的可以點贊關注下。

原文 https://zhuanlan.zhihu.com/p/145102951

繼續閱讀