Android MediaRecorder架构详解
本文主要詳解MediaRecorder架構,從上層調到StagefrightRecorder的流程以及應用層錄音接口調用的流程。(注:本次分析基于android4.4.2源碼)
?
2.?應用層錄音接口調用流程
(1)???? 調用new MediaRecorder()構造函數得到實例。
(2)???? 調用setOutputFormat()設定媒體文件的輸出格式。
(3)???? 調用setAudioSource()設定音頻的錄入源以及調用setAudioEncoder()設定音頻的編碼方式。
(4)???? 調用setOutputFile()設定記錄的媒體文件保存的路徑。
(5)???? 調用prepare()準備錄制。
(6)???? 調用start()開始錄制。
(7)???? 記錄完成后,調用stop()停止錄制。
?
3.?應用層調到StagefrightRecorder的流程
如圖1所示,MediaRecorder在運行時,可以分成Client和Server兩個部分,它們分別在兩個進程中運行,它們之間使用Binder機制實現IPC通訊。
??
?圖1 錄音從Java層調到StagefrightRecorder的流程圖
?
(1)?手機啟動時會啟動進程/system/bin/mediaserver。該進程會把media相關服務注冊到ServiceManager中,如MediaPlayerService。
(/frameworks/av/media/mediaserver/main_mediaserver.cpp)
?
?
?
?
?
?
(/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp)
?
?
?
(2)應用層創建MediaRecorder實例:mMediaRecorder = new MediaRecorder(); 調用SDK中MediaRecorder.java
(frameworks\base\media\java\android\media\MediaRecorder.java)
?
?
?
?
?
?
?
?
?
通過JNI方式調用到framework層android_media_MediaRecorder.cpp。
(\frameworks\base\media\jni\android_media_MediaRecorder.cpp)
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
(3)?繼而調用mediarecorder.cpp的構造函數,它首先會從ServiceManager中獲得MediaPlayerService服務,然
后通過服務來創建recorder。這個recorder就是錄音的真實實例。
?(frameworks\av\media\libmedia\mediarecorder.cpp)
?
?
?
?
?
?
?
?
(4)?通過getMediaPlayerService得到的service其實是BpMediaPlayerService,它和mediaserver進程中的BnMediaPlayerService是相對應的,共同負責進程間binder通信。BpMediaPlayerService中的createMediaRecorder其實是通過binder機制將CREATE_MEDIA_RECORDER消息發送出去。
(/frameworks/av/media/libmedia/IMediaPlayerService.cpp)
?
?
?
?
?
(5)在BnMediaPlayerService中,通過onTransact()來處理接收到的消息,并返回結果。當接收消息中的code為CREATE_MEDIA_RECORDER時,調用MediaPlayerService 中的createMediaRecorder函數。在該函數中創建了一個MediaRecorderClient的實例,也就是說MediaPlayerService會為每個client應用進程創建一個相應的MediaRecorderClient的實例,來提供服務。
(/frameworks/av/media/libmedia/IMediaPlayerService.cpp)
?
?
?
?
?
?
?
…
?
?
?
?
…
?
?
(/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp)
?
?
?
?
(6)如此MediaRecorder.cpp就得到了一個recorder的實例,對它來說這個實例和本地的其他類的實例沒什么用法上的區別,但其實這個實例是運行在另外一個進程中。實現這種假象的就是binder機制。在MediaRecorderClient的構造函數中,才會真正的創建StagefrightRecorder的具體實例,即真正的錄制對象,使用的StageFright多媒體框架。在android 4.0以后只有StagefrightRecorder一個錄制框架。在2.2、2.3中還存在另外一個錄制對象PVMediaRecorder,使用的是OpenCore框架實現錄音或錄像。
(/frameworks/av/media/libmediaplayerservice/MediaRecorderClient.cpp)
?
?
?
?
圖2是錄音創建實例的時序圖
?
圖2 錄音創建實例的時序圖
?
4.?Application Framework層與libraries層錄音函數對應關系
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setOutputFile(recordFile.getAbsolutePath());
mMediaRecorder.prepare();?
mMediaRecorder.start();
mMediaRecorder.stop();
mMediaRecorder.release();
?
sp<MediaRecorder> mr = new MediaRecorder();
mr->setAudioSource(1);? //MIC = 1
mr->setOutputFormat(0); //DEFAULT = 0;
mr->setAudioEncoder(0);//DEFAULT = 0;
mr->setOutputFile(fos.getFD(), 0, 0);
mr->prepare();
mr->start();
mr->stop();
mr->release();
?
5.?總結
通過對android mediarecorder架構的詳解,了解各模塊調用的流程,不僅可以實現在應用層調用錄音接口進行錄音,還能直接調用libraries層錄音接口函數進行C層錄音。同時,若需要監控錄音,則可以Hook系統進程/system/bin/mediaserver的ioctl函數,從而攔截該進程的binder通信過程,通過解析binder通信數據包,就可以監控到手機中所有錄音軟件的錄音行為。
?
6.?參考資料
[1]Android錄音MediaRecorder/AudioRecorder相關總結:
http://www.360doc.com/content/12/0919/19/10764837_237084032.shtml
[2]MediaRecorder和AudioRecord的區別和聯系:
http://blog.csdn.net/ameyume/article/details/7885744
[3]MediaRecorder類介紹:http://blog.csdn.net/mark_dev/article/details/7249415
[4]AndroidXRef:http://androidxref.com/
 
 
原文地址:?http://www.isclab.org.cn/archives/2014/12/2946.html
總結
以上是生活随笔為你收集整理的Android MediaRecorder架构详解的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Android 4.4 MediaRec
- 下一篇: AudioRecorder 录音相关的处
