Android MediaRecorder采样率和噪声问题

9
我在使用Android的MediaRecorder录制麦克风声音到.m4a文件(AAC-LC,MPEG-4容器)时遇到了问题。从API 18开始,默认采样率从44.1或48 kHz(取决于设备)降至仅8 Hz。如果我使用MediaRecorder.setAudioSamplingRate指定采样率,则会使用指定的采样率,但录音中会出现很多奇怪的噪音。
在LogCat中,有时会发生以下警告:
(1) 标签:AudioSource 文本:AudioRecord报告溢出
(2) 标签:AudioFlinger 文本:RecordThread:缓冲区溢出
以下是代码:
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioChannels(2);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioSamplingRate(48000);   // if not specified, defaults to 8kHz, if specified 44.1 or 48 kHz, lots of noise
recorder.setOutputFile("test.m4a");

try {
    recorder.prepare();
    recorder.start();

} catch (IOException ioe) {
    Log.e(TAG, "IOException", ioe);
} catch (IllegalStateException ise) {
    Log.e(TAG, "IllegalStateException", ise);
} catch (Exception e) {
    Log.e(TAG, "Exception", e);
}

非常感谢您的帮助。


尝试使用不同的编码器和比特率(22050、16000)。在Android文档的“媒体格式”中列出了各种编解码器。 - Robert Rowntree
@Squonk - 谢谢。同意mp4更容易受到这个问题的影响。我希望有人能知道这个问题的原因,以及如何使用Android进行高质量录制 :) - user4672580
@Justin:你尝试过使用 setAudioEncodingBitRate(...) 进行实验吗? - Squonk
@Robert - 尝试过flac,非常好用,可惜我需要的是m4a而不是flac,但这进一步让我认为MediaRecorder有漏洞。 - user4672580
使用MediaRecorder时遇到了相同的问题。修复或改进有任何更新吗? - MiaN KhaLiD
显示剩余7条评论
2个回答

3
经过长时间的研究和尝试,我制定了最佳的工作解决方案:
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setAudioEncodingBitRate(384000);
mRecorder.setAudioSamplingRate(44100);

1
如果有一种方法可以查询设备的真实硬件采样率,那么您就可以明智地选择44100与48000,而不必查看从应用https://play.google.com/store/apps/details?id=com.levien.audiobuffersize编译的列表http://audiobuffersize.appspot.com/。 - karora
哇,这是一个很长的列表!如果有人能找到那个代码就好了!或者,有人可以创建一个包含每个样本率的模型设备数组的库,根据启动应用程序的手机从数组中设置它? - Ali Obeid

2

您可以像您所做的那样设置 SamplingRate,也可以设置 EncodingBitRate,但您已经省略了它。

我使用以下设置能够实现高质量的录音:

    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
    mRecorder.setAudioSamplingRate(48000);
    mRecorder.setAudioEncodingBitRate(384000);

这将使用每个样本8位进行编码,这很可能超出大多数设备麦克风可用的质量。


但是这会发出非常嘈杂的声音,就像超高的声音。 - Ali Obeid
我完全没有那种经历,而且我已经在相当多的设备上使用了这段代码。也许有些设备存在问题?你尝试过调整 (a) 48000 到 44100 和/或 (b) 384000 到 160000 吗? - karora
嗯,也许吧..但请看我的回答,它是100%工作的! - Ali Obeid
是的,有些硬件可能比48000更好地支持44100。几年前在Linux上我经常看到这种情况,但我认为现在它应该已经成为了遥远的记忆。你使用的是什么硬件? - karora
这里有一些关于选择采样率的有趣信息:https://developer.android.com/ndk/guides/audio/sampling-audio.html - karora
对我来说,我正在Galaxy Note 4、Grand Prime和Samsung A5(2017)上进行测试,它工作得非常完美。 - Ali Obeid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接