关于android电话录音问题的详细分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于android电话录音问题的详细分析

作者:老猫

一直以来都是在网络上看别人的文章,老老实实的做潜水员,今天一时兴起,写点东西,希望对大家有所帮助,不要再走同样的弯路。

本文是关于Android下录音问题的分析,网络上都说Android录音时记录下的语音信号都是混音器的信号。但是都没有给出详细说明为什么是这样。

我们知道Android下进行电话录音的代码很简单:

大致流程如下:

recorder = new MediaRecorder();

//这里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.A udioSource中定义了以下常量可以用于

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

class MediaRecorderClient : public BnMediaRecorder

{

public:

virtual status_t setCamera(const sp& camera);

virtual status_t setPreviewSurface(const sp& surface);

virtual status_t setVideoSource(int vs);

virtual status_t setAudioSource(int as);

virtual status_t setOutputFormat(int of);

virtual status_t setVideoEncoder(int ve);

virtual status_t setAudioEncoder(int ae);

virtual status_t setOutputFile(const char* path);

virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);

virtual status_t setVideoSize(int width, int height);

virtual status_t setVideoFrameRate(int frames_per_second);

virtual status_t setParameters(const String8& params);

virtual status_t setListener(const sp& listener);

virtual status_t prepare();

virtual status_t getMaxAmplitude(int* max);

virtual status_t start();

virtual status_t stop();

virtual status_t reset();

virtual status_t init();

virtual status_t close();

virtual status_t release();

。。。

}

可以看到,大部分客户端方法在MediaRecorderClient中都有对应方法。这样当我们调用客户端的recorder.start();时,最后会调用到MediaRecorderClient类中的start方法。status_t MediaRecorderClient::start()

{

LOGV("start");

Mutex::Autolock lock(mLock);

if (mRecorder == NULL) {

LOGE("recorder is not initialized");

return NO_INIT;

}

return mRecorder->start(); //转发给mRecorder

}

//这里的mRecorder是在MediaRecorderClient构造函数中创建的。

MediaRecorderClient::MediaRecorderClient(const sp& service, pid_t pid) {

。。。

#ifndef NO_OPENCORE

{

//创建了PVMediaRecorder用于录音

mRecorder = new PVMediaRecorder();

}

#else

{

mRecorder = NULL;

}

#endif

mMediaPlayerService = service;

}

其他的调用也是一样,所有的请求基本都转发给了PVMediaRecorder,这个PVMediaRecorder就是opencore 中的对应的录音的类。

相关文档
最新文档