前言java
從2016年6月開始寫《javacv開發詳解》系列,到而今的《javacv入門指南》,雖然僅隔了兩年多時間,卻也改變了不少東西。nginx
好比咱們的流媒體技術羣從剛開始的兩三我的發展到如今的三個500人羣。又好比博主剛開始也想放棄,期間自行腦洞心裏掙扎的場面也就不詳說了,結果是如今還在堅持更新博客。固然這期間離不開羣裏小夥伴們一直以來的陪伴和支持,感謝你們一塊兒默默爲java流媒體技術踩坑,踩的多了也就真的成了路(也可能踩成深坑 )。另外感謝雷霄驊博士的ffmpeg博客,給予博主很大幫助,2016年剛開始接觸ffmpeg就忽聞博士去世,甚爲感慨,你們且行且珍惜吧。c++
之前歷來不以爲java能夠作流媒體、音視頻編解碼這些,直到如今,頂多說java作流媒體是非主流。業界普遍應用的librtmp、live55五、ffmpeg也都是c/c++的庫,剛開始也確實嘗試過使用jni方式調ffmpeg,發現作起來吃力不討好,後來在github發現了新大陸:javaCV。git
有,總比沒有強。雖然連個API文檔都沒有,經過github項目描述的那可憐的幾個字勉勉強強知道它對ffmpeg、opencv等等等十幾個庫作了封裝,用javacpp方式爲fmpeg、opencv等庫編譯了各個系統環境的包方便跨平臺調用。github
一些題外話算法
踩坑到今天,可能還會有許多人躊躇疑惑javacv除了能夠在音視頻和圖像處理這塊稍微能夠施展手腳外,還能夠作什麼?除了這些,在應對各類紛繁複雜的流媒體協議(rtp/rtsp/rtmp/flv/hls等等)也不在話下,固然一些小衆和國產協議(好比sip/gb28181/jtt178等)可能須要依賴netty/mina等網絡庫來實現,編解碼上結合javaCV,性能上也已經沒有什麼顧慮。另外在深度學習領域,deeplearning4j藉助javaCV的東風令java在深度學習領域也一樣引領風騷。數組
本系列將結合《javacv開發詳解》系列做爲實戰教程,結合實例,力求簡單易懂,快速上手。網絡
1、老生常談機器學習
javaCV能作什麼,既然是"CV"大法,那天然是計算機視覺領域的庫,諸如音視頻、流媒體、圖像處理、深度學習、機器學習、人工智能等等等(如今流行後面這三個,寫上去應該能唬住很多人,deeplearning曉得不,裏面一堆的javaCV庫沒發現嗎)。tcp
2、入門基礎
以上全是些空話,咱們無非就是要用javaCV採集視頻和音頻,給這些音視頻編解碼,而後是用什麼封裝格式封裝這些音視頻數據,以及用什麼協議傳輸,可能還要對視頻裏的圖像進一步進行處理(這個屬於圖像處理範疇),流程大體如此(音頻方面瞭解很少,你們見諒):
拉流(採集)--->圖像像素數據/音頻數據<---->編/解碼 <---->音/視頻幀<---->解封裝/封裝---->推流
一、圖像像素格式與圖片封裝格式
圖像像素格式(簡稱像素格式),通常指的是沒有通過編碼的按照原始像素排列的數據。
舉個栗子,一個完整圖像的像素排列通常是這樣的(以4*4像素的rgb像素格式爲例):
rgbrgbrgbrgb
rgbrgbrgbrgb
rgbrgbrgbrgb
rgbrgbrgbrgb
固然咱們存儲的時候通常使用一維數組來存這些數據,因此排列順序就變成這樣:rgbrgbrgbrgb.......以此類推。
圖片封裝格式指的咱們平常見到的png,jpg,bmp,gif等等圖片格式,其中bmp是無損格式,裏面的數據格式就是圖片頭信息加上rgb排列的像素數據,png/jpg這些都是有損壓縮格式,可是壓縮比仍是很高的,爲何要壓縮下面會講到。
二、圖像?視頻幀?傻傻分不清楚
圖像像素數據指的是yuv、rgb,rbga,bgr,gbra等圖像像素格式,通過編碼後纔是視頻幀。好比咱們常見的h264編碼,編碼其實就是對圖像像素數據的壓縮,(以rgb爲例,假如當前圖像像素尺寸爲1920*1080,,每種顏色用一個字節表示,也就是說每一個像素點有紅綠藍三色共3字節,圖像有1920*1080個像素點,也就是說這張圖像大小爲1920*1080*3字節,顯然數據太大了),能夠這樣理解,h264編碼本質上就是一種圖像數據壓縮算法。
三、編碼?封裝?傻傻分不清楚
編碼上面已經講了,是一種壓縮算法;那麼封裝格式又是什麼呢,封裝格式就是咱們平常見到的視頻文件了,好比mp4,avi,mkv,flv等等等,按照每種封裝格式的規範把視頻幀和音頻按照必定順序存起來就成咱們平常看到的視頻文件了,這些封裝格式通常都會包含一些頭/尾標識和一些視頻描述信息,這樣播放器讀取視頻文件的時候就知道該怎麼播放這些視頻文件了(能夠把封裝格式理解成收納箱,上面貼着小紙條說明裏面放了哪些東西)。
壓縮圖片格式也能夠參考視頻編碼格式,原理都同樣,都是對圖像數據作有損/無損壓縮。
四、音/視頻源
音/視頻源能夠是視頻文件、音頻文件,流媒體源,設備等等。
好比咱們要看電腦或手機攝像頭視頻,就得采集設備的圖像數據(從源設備採集到的是像素數據,通常是bgr或者rgb像素數據)若是是某些廠商的商用攝像機,可能會支持rtsp/rtmp協議,要採集聲音呢,就得采集錄音/話筒設備裏面的數據(通常是pcm採樣數據)。
五、流媒體協議
rtsp協議棧,rtmp協議棧,hls,http-flv(理論上講這個flv不能算是流媒體協議,它只是個無限大的flv文件)等等。
例如rtmp,對編碼後的音視頻幀,要對其進行封裝成flv進行傳輸。
補充:說到底這些協議原理上依然是創建在tcp/udp基礎上的應用層傳輸協議。
六、流媒體服務
支持音視頻存儲分發的服務均可以叫流媒體服務。
好比常見的srs(開源的rtmp流媒體服務,固然它支持rtmp/hls/http-flv的分發)和nginx(經過安裝模塊能夠支持rtmp,hls,http-flv分發),除此以外的收費的和一些不太友好的開源流媒體服務就不一一介紹了。
下一章:javaCV入門指南:調用FFmpeg原生API和JavaCV是如何封裝了FFmpeg的音視頻操做?
支持eguid原創