其實老早就想寫一些關於音視頻學習的文章了,但由於各方面的原因遲遲都沒有開始。一個方面是因爲筆者寫文章都是成系統的,音視頻需要大家有一定的 c/c++ 基礎;還有一個方面是因爲之前經驗不足,這一塊涉及到的細節也比較多。我自己學習時看過大量的文章和資料,這裏推薦 雷霄驊的專欄 ,雖然文章的更新永遠停在了那一刻,但其無私分享的精神值得我們每一個開發者學習。音視頻這系列文章我們打算從基礎開始學,然後結合移動端 NDK 來開發。因此如果你已經是音視頻開發的老司機,那麼本文可能不太適合你,其次如果之前沒了解過 NDK 開發,學習起來也可能會有些難度。
目前市面上我們所熟悉的音視頻開發大致有:視頻播放器、短視頻、視音頻直播 等等,他們之間有很多的共性像音視頻編解碼、視音頻同步等,因此我們首先來看下這些共性內容。假設我們現在要播放一個本地視頻,需要經過哪些步驟呢?大家不妨自己先思考一下,當然這裏不是說集成 ijkplayer 或者 ExoPlayer 等開源庫,目前只給一個 SurfaceView 和一個視頻文件,在此基礎上實現一個視頻播放。我們先來看一個簡單的流程圖:
上面這張圖我們務必得要記在心裏,想必理解這麼一張圖對於大家來說應該 soEasy 。很多東西都是一通百通的,之前就講過怎麼解析一張圖片,我們再渙散一下思維,假如去解析加載一個 dex/class 文件呢?基於上面這個圖,我們再來看一些具體的細節:
解封裝
將輸入的封裝格式的數據(文件),分離成爲音頻流壓縮編碼數據和視頻流壓縮編碼數據。封裝格式種類很多,具體可以參考下面這張表,它的作用就是將已經壓縮編碼的視頻數據和音頻數據按照一定的格式放到一起。例如,FLV 格式的數據,經過解封裝操作後,輸出 H.264 編碼的視頻碼流和 AAC 編碼的音頻碼流。
名稱 | 推出機構 | 支持的視頻編碼 | 支持的音頻編碼 |
---|---|---|---|
AVI | Microsoft Inc. | 幾乎所有格式 | 幾乎所有格式 |
MP4 | MPEG | MPEG-2, MPEG-4, H.264, H.263等 | AAC, MPEG-1 Layers I, II, III, AC-3等 |
TS | MPEG | MPEG-1, MPEG-2, MPEG-4, H.264 | MPEG-1 Layers I, II, III, AAC, |
FLV | Adobe Inc. | Sorenson, VP6, H.264 | MP3, ADPCM, Linear PCM, AAC等 |
MKV | CoreCodec Inc. | 幾乎所有格式 | 幾乎所有格式 |
RMVB | Real Networks Inc. | RealVideo 8, 9, 10 | AAC, Cook Codec, RealAudio Lossless |
視音頻解碼
將視頻/音頻壓縮編碼數據,解碼成爲非壓縮的視頻/音頻原始數據。音頻的壓縮編碼標準包含 AAC,MP3,AC-3 等等,視頻的壓縮編碼標準則包含 H.264,MPEG2,VC-1 等等。解碼是整個系統中最重要也是最複雜的一個環節。通過解碼,壓縮編碼的視頻數據輸出成爲非壓縮的顏色數據,例如 YUV420P,RGB 等等;壓縮編碼的音頻數據輸出成爲非壓縮的音頻抽樣數據,例如 PCM 數據。
視頻編碼
視頻編碼的主要作用是將視頻像素數據(RGB,YUV等)壓縮成爲視頻碼流,從而降低視頻的數據量。如果視頻不經過壓縮編碼的話,體積通常是非常大的,一部電影可能就要上百G的空間。視頻編碼是視音頻技術中最重要的技術之一。視頻碼流的數據量佔了視音頻總數據量的絕大部分。高效率的視頻編碼在同等的碼率下,可以獲得更高的視頻質量。主要的編碼方式有 HEVC(H.265),H.264,MPEG4,MPEG2,VP9,VP8,VC-1 等等。
音頻編碼
音頻編碼的主要作用是將音頻採樣數據(PCM等)壓縮成爲音頻碼流,從而降低音頻的數據量。音頻編碼也是互聯網視音頻技術中一個重要的技術。但是一般情況下音頻的數據量要遠小於視頻的數據量,因而即使使用稍微落後的音頻編碼標準,而導致音頻數據量有所增加,也不會對視音頻的總數據量產生太大的影響。高效率的音頻編碼在同等的碼率下,可以獲得更高的音質。主要的編碼方式有 AAC,AC-3,MP3,WMA 等等。
FFmpeg
整個音視頻技術學習的核心就在協議和編解碼,其中最複雜重要的部分當屬編解碼了,如果沒有基礎的話,我們可以買一些書看一下,實體書或電子書都行。如果真的只給大家一個文件和一個 SurfaceView ,第一步解封裝估計就得難倒一大部分人。因此如果是初學習音視頻技術,還是建議大家基於一些第三方的開源庫來實現功能,等時機成熟了再去了解底層的源碼和算法。我選的是一個常用的同時也是大家比較熟悉的開源庫 FFmpeg。所以後面我們基於 FFmpeg + NDK 來開發音視頻,等有了一定的經驗我們再去閱讀源碼學習算法。
準備工作
首先我們得去編譯 FFmpeg 的 so 庫文件,而編譯 so 庫又涉及到 shell 腳本和 cmake 語法知識,所以我們又需要一個 linux 環境。我當初在學習這些基礎知識時,買的是半年的雲主機服務,如果大家本來就是用的 linux 系統或 mac 系統,那麼就沒必要再去購買雲主機了。考慮到 Android 底層本身也是基於 linux 內核,趁着買了雲主機的這個機會,我把 linux 內核的基礎也學習了一遍。所以未來幾個月的文章和視頻,基本都是一些關於 shell 腳本,cmake 語法,linux 內核,音視頻編解碼,音視頻通話,視頻直播 等知識。
視頻地址:https://pan.baidu.com/s/1J4smfhiPXnuiCPSh1-Kwfw
視頻密碼:7b83