Android系统提供的录音接口有两种,MediaRecord和AudioRecord,AudioRecord录制的是未经过压缩的pcm格式音频数据,MediaRecord则可以设置编码器,录音压缩后的音频数据,同时录制出来的文件可以直接经过mediaplayer播放,
当然MediaRecord接口底层也是使用AudioRecord的接口通过audioflinger从底层拿到数据。举例来看看两种接口如何录音,
使用mediarecord:
mediaRecorder mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 设置输出格式为3gp
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
// 设置声音解码AMR_NB
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// 媒体录制器准备
mRecorder.prepare();
// 开始录制
使用AudioRecord在此省略了
录音是否成功首先设置的参数需要设备支持,采样率,位深,通道数等。一般AudioRecord满足参数要求,基本都能录制成功,由于Mediarecord还有涉及编码这一层,所以还需要编码器参数支持,看上面的例子实际是没有设置采样率的,这样一般会有一个编码器的默认采样率。以android P为例可以查看media_profiles_V1_0.xml里声明的编码器支持参数,在我的平台上这个文件在/vendor/etc/路径下
我们可以看到上图例子中设置的AMR_NB编码只支持8K,如果底下设备不支持8K这里就有问题了,如果hal层做的比较好的话会直接提示一个错误,参数不支持。笔者遇到过一个项目,设备hal是.a的形式包在primary hal里没有参数检查,而且不管上层以什么采样率去录音,底层都以16000的数据往上抛,所以碰到一个一录音就莫名其妙crash的问题,记录以下以后也少遇到一些坑了:
针对这个问题,底层设备固定好只能是16000那么就只好修改上层,录音时指定采样率为16000,同时修改下编码格式为amrwb,因为amrwb是支持16000的,问题得以解决