音視頻從採集到播放都經歷了哪些流程呢::
通過上面的圖,我們簡單的把音視頻方向分爲主要的兩塊:
- 媒體部分(藍色+綠色)
- 傳輸部分(紅色)
1.媒體部分
我們這篇文章不再從音視頻專業知識開始,而從Android系統API的角度,逐層深入.
1.1 原始版本
我們最開始接觸的攝像拍照是通過Intent調用系統攝像頭:
Intent intent=new Intent();
// 指定開啓系統相機的Action
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 根據文件地址創建文件
File file=new File(FILE_PATH);
// 把文件地址轉換成Uri格式
Uri uri=Uri.fromFile(file);
// 設置系統相機拍攝照片完成後圖片文件的存放地址
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
複製代碼
我們要播放視頻最原始的是基於VideoView系統控件.
但是系統相機和系統控件VideoView的侷限性都是可定製型太差,系統相機的圖像分辨率,視頻碼率以及VideoView的進度條等.
1.2 初級版本
接下來,Android開發中我們接觸到最上層的兩個API(Android官方提供了的麼:github.com/android/med… 包含了MediaRecorder VideoPlayer等)是:
- MediaRecorder 音頻/視頻採集 對應上圖藍色部分, 參考 github.com/werbhelius/… 實現
- MediaPlayer 音頻/視頻播放, (VideoView封裝了MediaPlayer),對應上圖綠色部分 參考:github.com/crossle/Med… 實現
MediaRecorder示例:
mediaRecorder = new MediaRecorder(); // 創建
mediaRecorder.reset(); // 設置爲空閒模式 可以賦屬性了
mediaRecorder.setCamera(mCamera);// 設置一個攝像頭用於錄製。
// 使用SurfaceView預覽
mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
// 1.設置採集聲音
// mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 設置採集圖像
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 2.設置視頻,音頻的輸出格式 mp4
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
// 開始錄製
mediaRecorder.prepare();
mediaRecorder.start();
複製代碼
MediaPlayer示例:
MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.prepareAsync();
複製代碼
示例代碼簡單介紹了一下MediaRecorder和MediaPlayer的API,參考上面提供的demo已經可以實現簡單的播放器和音視頻錄製功能了.上面我們又引出兩個接口來:Camera, Surface. 拍照等功能我們都可以使用Camera的接口實現,關於Camera的API可以參考google的demo:github.com/googlearchi… Surface我們接下來介紹.
1.3 進階版本
上面的的MediaRecorder,MediaPlayer直接封裝了圖中的藍色部分與綠色部分.它們將輸入編碼複用以及解碼解複用輸出封裝到了一起,可定製性差: 1.MediaPlayer只支持固定的編碼和封裝,不支持rtmp等 2.MediaRecorder無法支持mp3,opus, ogg等編碼,無法對採集到音視頻做預處理(比如變聲,美顏等)
基於上述幾個原因,我們再認識幾個API:
- 視頻採集 Camera
- 音頻採集 AudioRecord
- 視頻預處理:SurfaceTexture, Surface, EGL ,GLES10
- 音視頻編碼 MediaCodec MediaFormat
- 音視頻封裝(複用) MediaMuxer
- 音視頻(解複用) MediaExtractor
- 音視頻解碼 MediaCodec
- 視頻預覽 SurfaceView, GLSurfaceView, TextureView
- 音頻播放 AudioTrack
上述API Android也爲我們提供了示例https://github.com/google/grafika,裏面包含的示例相當全面:
- Play video (TextureView). 基於MediaCodec ,MediaExtractor, TextureView封裝的播放器,可以幫助理解這幾個api.
- Continuous capture. 基於Camera,GLES20,SurfaceTexture,SurfaceView,MediaCodec實現的建議的視頻錄製器.
- Double decode. 類似於Play video示例,只是解碼兩路視頻渲染到TextureView.
- Hardware scaler exerciser. 演示OpenGL進行畫面縮放
- Live camera (TextureView). 演示Camera,SurfaceTexture以及TextureView使用
- Multi-surface test. 演示三路視頻渲染
- Play video (SurfaceView). 類似於Play video (TextureView),只是輸出從TextureView變成了SurfaceView.
- Record GL app. 基於FBO同時將攝像頭採集數據輸出到編碼器和屏幕,FBO是實時美顏的關鍵技術.
- Record Screen using MediaProjectionManager.基於MediaProjectionManager將屏幕內容錄製成文件.之前我們的輸入都是攝像頭,Android5.0開始提供了MediaProjectionManager,可以對屏幕內容進行採集.
- Scheduled swap. 瞭解一個新夥伴Choreographer
- Show + capture camera. 攝像頭同時輸出到文件和屏幕(與"RecordFBOActivity"輸出對象變成了GLSurfaceView)
- Simple Canvas in TextureView. 一般的我們把基於OpenGL的渲染稱爲"硬"渲染,基於Canvas的稱爲"軟"渲染,這個示例展示瞭如何通過Canvas繪製到TextureView
- Simple GL in TextureView. 可以理解爲實現了GLThread的TextureView.
- Texture from Camera. Camera->SurfaceTexture->SurfaceView
- Color bars. Canvas繪製示例
- OpenGL ES Info. 獲取OpenGL 版本等相關信息
- glTexImage2D speed test. 紋理上傳示例,從圖片裝換爲OpenGL紋理,又要認識一個新夥伴:
glTexImage2D()
. - glReadPixels speed test. OpenGL紋轉換爲圖片(RGBA/YUV),再認識一個新夥伴
glReadPixels()
上面的demo主要是圖形相關的,編解碼器觀光一下官方文檔:developer.android.google.cn/reference/a… 已經不能再明白了.
此外,想弄明白MediaCodec,還需要了解一個數據結構ByteBuffer(移步官方文檔瞭解一下? developer.android.google.cn/reference/j…)
如果學習完這些,那麼恭喜你,你已經對音視頻相關知識有了一些瞭解了.接下來你可以試着去接觸一下著名的android-gpuimage,以及瞭解OpenGL相關的FBO,PBO,Texture等,可以處理視頻編輯,簡單實現美顏等濾鏡了. 推薦一些OpenGL相關文章:
- 第一個OpenGL程序:blog.csdn.net/fuyajun01/a…
- 計算機圖形學網絡課程:netclass.csu.edu.cn/NCourse/hep…
- LearnOpenGl-CN:learnopengl-cn.readthedocs.io/zh/latest/0…
- opengl-tutorial:learnopengl-cn.readthedocs.io/zh/latest/0…
- OpenGl Pixel Buffer Object(PBO):www.songho.ca/opengl/gl_p…
- OpenGL深入探索——緩衝區對象(*BO):blog.csdn.net/panda1234le…
- OpenGL深入探索——像素緩衝區對象 (PBO):blog.csdn.net/panda1234le…
- Android 關於美顏/濾鏡 利用PBO從OpenGL錄製視頻:www.jianshu.com/p/3bc4db687…
- EGL API Notes
- Learn OpenGL ES:www.learnopengles.com/android-les…
- OpenGL Transformation:www.songho.ca/opengl/gl_t…
- glsl_tutorial:zach.in.tu-clausthal.de/teaching/cg…
- GLSL ES(OpenGL ES着色器語言)_WebGL筆記9:www.ayqy.net/blog/glsl-e…
- OpenGL 紋理座標 和 頂點座標映射關係 詳解:blog.csdn.net/xipiaoyouzi…
- www.khronos.org/registry/EG… OpenGL中FrameBuffer使用:blog.csdn.net/wl_soft50/a…
1.4 高級版本
進階版本中處理的都是Java層數據,有時候我們要編碼mp3,opus等,手機硬件編碼器(就是MediaCodec)不支持,我們需要引入編解碼器庫(lame,opus),這些庫都是c/cpp實現,我們要經過jni封裝,但是jni是有消耗的,那麼我們可以不可以直接在c/cpp層實現採集,編碼,播放呢? 當然是YES,下面我們再來了解一下jni層的API:
- 圖像採集: 圖像採集可以使用Java Camera,通過給Camera Surface,Surface再給jni的MediaCodec,也可以試試<camera/NdkCameraManager.h>
- 聲音採集: 瞭解一下<SLES/OpenSLES_Android.h> , <SLES/OpenSLES.h>, opensl的文檔太粗陋,給你一份Android官方demo:github.com/android/ndk…
- 編解碼: 瞭解一下<media/NdkMediaCodec.h>
- 封裝(複用)器: <media/NdkMediaMuxer.h>
- 解封裝(解複用)器: <media/NdkMediaExtractor.h>
- 圖像渲染:
ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include
下的EGL, GLES, GLES2, GLES3等
如果瞭解到這,那麼恭喜你,可以繼續學習一些其他庫了:
- lamemp3:Android只支持mp3解碼,不支持mp3編碼,幸好有lame:官網, 使用示例 文章介紹: 帶你寫一個Mp文件解析器-Mp3文件結構全解析(一),帶你寫一個Mp文件解析器-Mp3文件結構全解析(二)
- opus: 實時語音場景的首選是opus,但是Android還是隻能解碼不能編碼,索性移步:官網,文章介紹Opus從入門到精通(一):簡介,Opus從入門到精通(二):編解碼器使用, Opus從入門到精通(三)手擼一個Opus編碼程序,Opus從入門到精通(四)Opus解碼程序實現,Opus從入門到精通(五)OggOpus封裝器全解析,學習到這應該不再需要demo了,自己動手來一個吧
- aac: Android支持了aac硬件編解碼,但是出於編碼效率以及低端手機考慮,瞭解一下FAAC
- x264: Android默認支持了h264的編解碼,但也是出於編碼效率及低端手機考慮,瞭解一下x264
- ffmpeg: 現在終於可以瞭解下傳說中的ffmpeg了,音視頻界的萬能神器.
1.5 終極階段
現在你可以更深入的瞭解聲音的本質,特性,圖像的壓縮原理等等,去理解時域與頻域,去學習charlesliuyx.github.io/2018/02/18/…,這個時候可以把高等數學和線性代數翻出來了.
2.傳輸部分
傳輸部分我們音視頻領域主要用到的應用層協議:
- http
- rtmp
- rtc
2.1基於http的音視頻傳輸
Android上面的系統播放器MediaPlayer默認支持http的,可以傳入一個遠程的mp4地址給MediaPlayer播放.但是這種只能實現點播,如果要在http上實現直播的話,瞭解一下HLS以及HttpFLV:www.jianshu.com/p/32417d8ee…
2.2 rtmp
rtmp是adobe的產物,主要用於直播場景,主播一路上行,觀衆多路下行
具體資源,文章裏都有介紹了
2.3 rtc
rtmp實現了直播,但要互動直播就需要rtc了.現在好多都是基於webrtc的二次開發.
- How to get started with WebRTC and iOS without wasting 10 hours of your life:ninjanetic.com/how-to-get-…
- WebRTC 1.0: Real-time Communication Between Browsers:www.w3.org/TR/webrtc/#…
- Android之WebRTC介紹:www.tuicool.com/articles/Vv…
- SDP for the WebRTC:tools.ietf.org/id/draft-na…
- WebRTC 1.0: Real-time Communication Between Browsers:w3c.github.io/webrtc-pc/
3.資源整理
3.1 攝像頭及錄製相關
- github.com/aserbao/And… : 自定義Android相機(仿抖音),其中功能包括視頻人臉識別貼紙,分段錄製,回滾刪除,倒計時錄製,視頻裁剪,視頻幀處理,獲取視頻第一幀,關鍵幀,視頻旋轉,濾鏡添加,水印添加,Gif合成到視頻,文字轉視頻,圖片轉視頻,音視頻合成,音頻變聲處理,SoundTouch,Fmod音頻處理。
- github.com/CJT2325/Cam… : 仿微信拍照Android控件(輕觸拍照,長按攝像)
- github.com/wuhaoyu1990… : Real-time Filter Camera&VideoRecorder And ImageEditor With Face Beauty For Android---包含美顏等40餘種實時濾鏡相機,可拍照、錄像、圖片修改,吸取了gpuimage很多濾鏡
- github.com/android/cam… : 谷歌官方demo
3.2 webrtc
- Pion WebRtc(github.com/pion/webrtc ):Pure Go implementation of the WebRTC API
- WebRtc 學而思鏡像(gitlab.com/webrtc-mirr…):
- WebRtc聲網鏡像(webrtc.agora.io/mirror/)
- Flutter-p2p-engine(gitee.com/cdnbye/flut…):Flutter視頻/直播APP省流量&加速,基於webrtc
- Android-p2p-engine(gitee.com/cdnbye/andr…):傳輸能力基於WebRTC Datachannel,可以與CDNBye的Web端插件互聯互通
- UnityRenderStreaming(github.com/Unity-Techn…):Streaming Server for unity
- WebRTC的擁塞控制和帶看策略(mp.weixin.qq.com/s/Ej63-FTe5…):
- WebRTC擁塞控制策略(www.freehacker.cn/media/webrt…)
- Google's BBR擁塞控制算法如何對抗diu丟包(blog.csdn.net/dog250/arti…)
- RTP Media Congestion Avoidance Techniques:datatracker.ietf.org/wg/rmcat/ch…
- medooze/media-server(github.com/medooze/med…):WebRTC Media Server
- 塗鴉開源voip:gitee.com/tucodec/rel…
- Jackarain/avplayer(github.com/Jackarain/a…):一個基於FFmpeg、libtorrent的P2P播放器實現
- EricssonResearch/openwebrtc:A cross-platform WebRTC client framework based on GStreamer www.openwebrtc.org
- webrtc/apprtc: The video chat demo app based on WebRTC. This project is currently on HOLD with minimal maintenance. appr.tc
- AirenSoft/OvenMediaEngine: OvenMediaEngine (OME) is a streaming engine for real-time live broadcasting with ultra-low latency. OvenMediaEngine.com/ome
- runner365/read_book:一點點從基礎做起 從音視頻協議原文精讀翻譯做起,歡迎交流指導!
- WebRTC in the real world: STUN, TURN and signaling:www.html5rocks.com/en/tutorial…
- WebRTC 的 Android 2 Android 實現:blog.csdn.net/youmingyu/a…
- webrtc進階-信令篇-之四: 如何爲WebRTC項目選擇信令協議
- pristineio/webrtc-build-scripts: A set of build scripts useful for building WebRTC libraries for Android and iOS.
- weizhenwei www.jianshu.com/u/102fafe8c… Webrtc源碼分析相關博客
- WebRTC代碼走讀(八):代碼目錄結構:blog.csdn.net/wanghorse/a…
- WEBRtc相關:www.wolfcstech.com/archives/
3.3 音視頻標準/歷史相關
- 編解碼和視頻處理技術介紹:wenku.baidu.com/view/0ce015…
- 多媒體技術基礎第三方03章_數字聲音編碼:wenku.baidu.com/view/f098cf…
- 音視頻系統培訓資料(內部):wenku.baidu.com/view/3fa2be…
- 音視頻編解碼技術:wenku.baidu.com/view/419f83…
- 音視頻專業知識:wenku.baidu.com/view/6ea5db…
- 音視頻通信基礎知識:wenku.baidu.com/view/7d3c24…
- 第二章音頻的數字化:wenku.baidu.com/view/715444…
- 音視頻技術及發展:wenku.baidu.com/view/4d4f13…
3.4 其他
- rainfly123/flvmuxer(github.com/rainfly123/…):This tool is used to encapsulate H264 and AAC to RTMP
- ant-media/LibRtmp-Client-for-Android(github.com/ant-media/L…):It is probably the smallest(~60KB, fat version ~300KB) rtmp client for android. It calls librtmp functions over JNI interface antmedia.io
- video-dev/hls.js(github.com/video-dev/h…):JavaScript HLS client using Media Source Extension hls-js.netlify.com/demo
- rao1219/VideoAnalysisTool(github.com/rao1219/Vid…):這是一款視頻分析處理工具,目前嵌入了Visual Tracking功能,手動勾選視頻中第一幀的某個物體,程序自動跟蹤該物體在整個視頻序列中的位置
- github.com/guoguo11/JS… JNI 調用C實現.speex轉換爲.wav;使用場景:微信高清語音.speex解碼爲.wav
- github.com/kaldi-asr/k… is the official location of the Kaldi project. kaldi-asr.org
- latelee/H264BSAnalyzer:H264(AVC) and H265(HEVC) bit stream Analyzer, VS2010 MFC project(Windows 7 x64).
- ZhengfengRao/rtp2mp4:recv rtp(h264+aac), save as mp4 file
- hmgle/h264_to_rtp:Send H264 file by RTP over UDP
- kn007/silk-v3-decoder:[Skype Silk Codec SDK]Decode silk v3 audio files (like wechat amr, aud files, qq slk files) and convert to other format (like mp3). Batch conversion support. kn007.net/topics/deco…
- SimpleLivePublisher.Lite github.com/gezhaoyou/S… : 簡介的Android平臺直播推流
其他資源持續整理輸出中...
作者:老司機丿
鏈接:https://juejin.im/post/5e61e19be51d4526db751082
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。