关于android电话录音问题的详细分析.doc
《关于android电话录音问题的详细分析.doc》由会员分享,可在线阅读,更多相关《关于android电话录音问题的详细分析.doc(15页珍藏版)》请在冰豆网上搜索。
![关于android电话录音问题的详细分析.doc](https://file1.bdocx.com/fileroot1/2022-11/2/14127e06-1c45-4fb1-8e31-b624f5e0c929/14127e06-1c45-4fb1-8e31-b624f5e0c9291.gif)
关于android电话录音问题的详细分析
作者:
老猫
一直以来都是在网络上看别人的文章,老老实实的做潜水员,今天一时兴起,写点东西,希望对大家有所帮助,不要再走同样的弯路。
本文是关于Android下录音问题的分析,网络上都说Android录音时记录下的语音信号都是混音器的信号。
但是都没有给出详细说明为什么是这样。
我们知道Android下进行电话录音的代码很简单:
大致流程如下:
recorder=newMediaRecorder();
//这里mode可以设置为VOICE_UPLINK|VOICE_DOWNLINK|VOICE_CALL
recorder.setAudioSource(mode);
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(recFile.getAbsolutePath());
//准备录音
recorder.prepare();
//启动录音
recorder.start();
//停止录音
recorder.stop();
MediaRecorder.AudioSource中定义了以下常量可以用于recorder.setAudioSource
这里和电话录音相关的有3个常量
Voice_call录制上行线路和下行线路
Voice_uplink录制上行线路,应该是对方的语音
Voice_downlink录制下行线路,应该是我方的语音
网络上关于java层如何调用native代码的介绍很多,这里只做简单介绍。
JAVA中MediaRecorder的方法会掉用本地C++代码,这些代码编译后为libmedia.so,再通过进程间通信机制Binder和MediaServer通信,MediaServer收到请求后,把这些请求转发给opencore。
以下是Android的媒体库框架图,从网络上下载的。
从上图可以看出,客户端调用的本地代码位于libmedia.so中,媒体服务进程调用的代码位于libmediaplayerservice.so中。
libmediaplayerservice.so再调用底层的libopencoreplayer.so完成具体功能。
以下通过代码介绍媒体服务进程如何转发请求到opencore中。
关于客户端mediarecorder如何与媒体服务进程交互请搜索网络,这方面文章很多,这里就不多介绍。
总而言之,客户端的一个mediarecorder对象和服务器端的MediaRecorderClient对象对应,客户端通过mediarecorder发送的请求,通过进程间通信机制最终都会发送到服务端的MediaRecorderClient类中。
我们来看下内部类client的声明,代码位于frameworks\base\media\libmediaplayerservice\MediaRecorderClient.h
classMediaRecorderClient:
publicBnMediaRecorder
{
public:
virtual status_t setCamera(constsp&camera);
virtualstatus_tsetPreviewSurface(constsp&surface);
virtualstatus_tsetVideoSource(intvs);
virtualstatus_tsetAudioSource(intas);
virtualstatus_tsetOutputFormat(intof);
virtualstatus_tsetVideoEncoder(intve);
virtualstatus_tsetAudioEncoder(intae);
virtualstatus_tsetOutputFile(constchar*path);
virtualstatus_tsetOutputFile(intfd,int64_toffset,int64_tlength);
virtualstatus_tsetVideoSize(intwidth,intheight);
virtualstatus_tsetVideoFrameRate(intframes_per_second);
virtualstatus_tsetParameters(constString8¶ms);
virtualstatus_tsetListener(constsp&listener);
virtualstatus_tprepare();
virtualstatus_tgetMaxAmplitude(int*max);
virtualstatus_tstart();
virtualstatus_tstop();
virtual status_treset();
virtualstatus_tinit();
virtualstatus_tclose();
virtualstatus_trelease();
。
。
。
}
可以看到,大部分客户端方法在MediaRecorderClient中都有对应方法。
这样当我们调用客户端的recorder.start();时,最后会调用到MediaRecorderClient类中的start方法。
status_tMediaRecorderClient:
:
start()
{
LOGV("start");
Mutex:
:
Autolocklock(mLock);
if(mRecorder==NULL){
LOGE("recorderisnotinitialized");
returnNO_INIT;
}
returnmRecorder->start(); //转发给mRecorder
}
//这里的mRecorder是在MediaRecorderClient构造函数中创建的。
MediaRecorderClient:
:
MediaRecorderClient(constsp&service,pid_tpid)
{
。
。
。
#ifndefNO_OPENCORE
{
//创建了PVMediaRecorder用于录音
mRecorder=newPVMediaRecorder();
}
#else
{
mRecorder=NULL;
}
#endif
mMediaPlayerService=service;
}
其他的调用也是一样,所有的请求基本都转发给了PVMediaRecorder,这个PVMediaRecorder就是opencore中的对应的录音的类。
这样,我们就直接进入opencore分析,先看看PVMediaRecorder的声明,代码位于frameworks\base\include\media\PVMediaRecorder.h,可以看到,客户端的方法在这里基本都有对应的方法。
classPVMediaRecorder:
publicMediaRecorderBase{
public:
PVMediaRecorder();
virtual~PVMediaRecorder();
virtualstatus_tinit();
virtualstatus_tsetAudioSource(audio_sourceas);
virtualstatus_tsetVideoSource(video_sourcevs);
virtualstatus_tsetOutputFormat(output_formatof);
virtualstatus_tsetAudioEncoder(audio_encoderae);
virtualstatus_tsetVideoEncoder(video_encoderve);
virtualstatus_tsetVideoSize(intwidth,intheight);
virtualstatus_tsetVideoFrameRate(intframes_per_second);
virtualstatus_tsetCamera(constsp&camera);
virtualstatus_tsetPreviewSurface(constsp&surface);
virtualstatus_tsetOutputFile(constchar*path);
virtualstatus_tsetOutputFile(intfd,int64_toffset,int64_tlength);
virtualstatus_tsetParameters(constString8¶ms);
virtualstatus_tsetListener(constsp&listener);
virtualstatus_tprepare();
virtualstatus_tstart();
virtualstatus_tstop();
virtualstatus_tclose();
virtualstatus_treset();
virtualstatus_tgetMaxAmplitude(int*max);
private:
status_tdoStop();
AuthorDriverWrapper*mAuthorDriverWrapper;
PVMediaRecorder(constPVMediaRecorder&);
PVMediaRecorder&operator=(constPVMediaRecorder&);
};
Opencore是一个第3方的库,体系比