Android实现录音功能汇总

Android实现录音功能汇总

神马笔记新的版本准备加入录音功能。

一、目标

神马笔记加入录音功能做技术储备。

二、录音效果比较

比较了MediaRecorder和AudioRecord的录音效果,尝试了音乐和人声。

最终的结论是二者差别不大,没有太明显的区别。

毕竟底层的实现是一样的,只是对PCM数据的处理有些许差别。

  • 音源
参数名 参数值
歌曲 身骑白马-黄小琥
输出设备 坚果 Pro2
输入设备 荣耀畅玩7
录音方式 两部手机并排录音
  • 参数
参数名 参数值
OutputFormat MediaRecorder.OutputFormat.MPEG_4
AudioEncoder MediaRecorder.AudioEncoder.AAC
AudioChannels 1
AudioSamplingRate 44100
AudioEncodingBitRate 128000
  • 比较结果
录音方式 开源项目 结果
MediaRecorder dkim0419 / SoundRecorder 平分秋色
AudioRecord google / ringdroid 不相伯仲

三、MediaRecorder

MediaRecorder 相关参数和方法一览。

  • AudioSource
常量 描述
AUDIO_SOURCE_INVALID
DEFAULT
MIC 麦克风
VOICE_UPLINK
VOICE_DOWNLINK
VOICE_CALL
CAMCORDER
VOICE_RECOGNITION
VOICE_COMMUNICATION
REMOTE_SUBMIX
UNPROCESSED
RADIO_TUNER
HOTWORD
  • OutputFormat
常量 描述
DEFAULT
THREE_GPP
MPEG_4
RAW_AMR
AMR_NB
AMR_WB
AAC_ADIF
AAC_ADTS
OUTPUT_FORMAT_RTP_AVP
MPEG_2_TS
WEBM
  • AudioEncoder
常量 描述
DEFAULT
AMR_NB
AMR_WB
AAC
HE_AAC
AAC_ELD
VORBIS
  • 其他参数设置
方法 描述
setAudioChannels(int numChannels)
setAudioEncodingBitRate(int bitRate)
setAudioSamplingRate(int samplingRate) 建议:16000
setOutputFile(String path)
setOutputFile(File file)
setOutputFile(FileDescriptor fd)
setOnErrorListener(OnErrorListener l)
setOnInfoListener(OnInfoListener listener)

四、参考文章

文章 描述
Android录制音频的三种方式 1. 第三方应用
2. MediaRecorder
3. AudioRecord
Android 录音MediaRecorder到AudioRecord 比较了2种录音的实现方式,并提供了WAV转AAC的实现方式。
体积这么小而且这么方便,很大的一个缺点,也是我放弃的理由,就是录下的音质不太好,总感觉被什么笼罩着在。
Android实时获取音量(单位:分贝) 介绍了录音时2种方式获取实时音量
MediaRecorder和AudioRecord录音与MediaPlayer和AudioTrack播放区别 MediaRecorder与AudioRecord在底层代码是一致的,只是MediaRecorder提供了更高层的封装。
MediaRecorder和AudioRecord的区别和联系
音频采样位数,采样率,比特率

五、开源项目

开源项目 实现方式 描述
google / ringdroid AudioRecord Ringdroid is an Android application for recording and editing sounds, and creating ringtones, directly on the handset.

Supported file formats right now include:

MP3
AAC/MP4 (including unprotected iTunes music)
WAV
3GPP/AMR (this is the format used when you record sounds directly on the handset)
OGG
mkjihu / AudioWaveViewEdit AudioRecord 讀取手機上有的音檔
滑動自訂 裁剪音檔區間
可錄音暫停後繼續錄音
錄音同時繪製波型圖

使用google / ringdroid核心代码,并增强之
Arjun-sna / Android-AudioRecorder-App AudioRecord 完整的录音应用。
cokuscz / audioWaveCanvas AudioRecord 录音并实时绘制波形图。
dkim0419 / SoundRecorder MediaRecorder
renhui / AudioDemo MediaRecorder 演示了使用AudioRecord录音,并保存为wav文件。
developerHaoz / SoundRecorderUtils MediaRecorder 封装成Service
lassana / continuous-audiorecorder MediaRecorder 支持暂停
gelitenight / WaveView 绘制波浪动画
Jay-Goo / WaveLineView 波浪线动画
google / ExoPlayer 播放器,不包含录音

六、同时使用MediaRecorder和AudioRecord

相同的代码在不同设备表现不一致。

结果不可控,不要同时使用。

  • MediaRecorder first
设备 版本 结果
荣耀畅玩7 8.1 Media分贝值:15.563025007672874
Audio分贝值:-Infinity
Media分贝值:26.848453616444125
Audio分贝值:-Infinity
Media分贝值:33.25515663363148
Audio分贝值:-Infinity
……
红米6 Pro 9.0 Media分贝值:27.60422483423212
Audio分贝值:28.706397912918934
Media分贝值:37.14664992862537
Audio分贝值:30.6302592206421
Media分贝值:38.276277047674334
Audio分贝值:28.778489726586123
……
  • AudioRecord first
设备 版本 结果
荣耀畅玩7 8.1 E/MediaRecorder: start failed: -38
java.lang.IllegalStateException
红米6 Pro 9.0 Audio分贝值:31.155938717202027
Media分贝值:33.06425027550687
Audio分贝值:32.32133729412097
Media分贝值:38.276277047674334
Audio分贝值:32.98663099227764
Media分贝值:40.506117305295405
……

七、调用第三方应用录音

  • 启动第三方应用
1
2
3
4
5
6
7
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);

try {
startActivityForResult(intent, REQUEST_RECORDER);
} catch (Exception e) {

}
  • 处理结果
1
2
3
4
5
6
7
8
9
10
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK && REQUEST_RECORDER == requestCode){
uri = data.getData();
}


}
设备 结果 截图
Android模拟器 ActivityNotFoundException
荣耀畅玩7 content://media/external/audio/media/2979
红米6 Pro content://media/external/file/125654

八、调研过程回顾

  • Android实现录音的3种方式
  1. 使用Intent调用第三方应用
  2. MediaRecorder
  3. AudioRecord

考虑到可能不存在第三方录音应用,以及录音应用的多样性。为保存用户体验的一致性,排除第三方应用的方式。

  • MediaRecorder和AudioRecord比较
MediaRecorder AudioRecord
录音效果 平分秋色 不相伯仲
音源数据 没有,转码后直接保存到文件。 PCM数据,需要自己转码。
可以使用MediaCodec进行编码解码,详情参考google / ringdroid
音频编码 设置即可 需要自己实现
缓存 无需关心 需要自己处理,或者直接将PCM数据写入文件
  • 结论

鉴于二者的录音效果并没有明显区别。

考虑神马笔记的使用场景,并不会对过程中的音频数据进行处理,而只关心最终的录音结果。

因此,MediaRecorder已经足够使用。

未来如果需要处理音频数据,可以使用MediaCodec进行编码解码,或者使用Native方式。

九、Finally

以实无有法。得阿耨多罗三藐三菩提。 是故然灯佛与我授记。作是言。 汝于来世。当得作佛。号释迦牟尼。