深入浅出安卓AudioRecord
一、AudioRecord是什么?
想象AudioRecord就像你手机里的"录音笔",专门用来录制原始音频数据。和手机自带的录音APP不同,它提供的是"原材料"(PCM数据),而不是"成品"(MP3/WAV文件)。你可以对这些原材料进行加工处理,比如:
- 实时语音识别
- 音频特效处理
- 语音通话应用
- 声音分析(如分贝检测)
二、录音的基本流程
1. 配置录音参数 - 相当于设置录音笔
// 常用参数配置
int sampleRate = 44100; // 采样率(CD音质)
int channelConfig = AudioFormat.CHANNEL_IN_MONO; // 单声道
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 16位深度
// 计算最小缓冲区大小
int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
参数解释:
- 采样率:每秒采集多少次声音(Hz),越高音质越好但体积越大
- 声道配置:单声道(CHANNEL_IN_MONO)或立体声(CHANNEL_IN_STEREO)
- 音频格式:一般用16位的PCM(ENCODING_PCM_16BIT)
2. 创建AudioRecord对象 - 买录音笔
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, // 使用麦克风
sampleRate,
channelConfig,
audioFormat,
minBufferSize * 2 // 实际缓冲区大小(建议是最小值的2倍)
);
注意:
- 需要检查录音权限(
Manifest.permission.RECORD_AUDIO
) - Android 6.0+需要动态申请权限
3. 开始录音 - 按下录音键
audioRecord.startRecording();
4. 读取音频数据 - 获取录音内容
byte[] audioData = new byte[minBufferSize];
while (isRecording) {
int readResult = audioRecord.read(audioData, 0, minBufferSize);
// 处理audioData(可以保存、传输或实时处理)
}
5. 停止和释放 - 关闭录音笔
audioRecord.stop();
audioRecord.release(); // 非常重要!释放资源
三、关键问题与解决方案
1. 为什么录音有杂音/声音小?
可能原因:
- 缓冲区大小不合适
- 没有使用合适的音频源
解决方案:
// 尝试使用VOICE_RECOGNITION音频源(针对语音优化)
new AudioRecord(
MediaRecorder.AudioSource.VOICE_RECOGNITION,
sampleRate,
channelConfig,
audioFormat,
bufferSize
);
2. 如何保存为WAV文件?
PCM是原始数据,需要加WAV头才能播放:
// 添加WAV文件头的方法
private void writeWavHeader(FileOutputStream out, long totalAudioLen) throws IOException {
long totalDataLen = totalAudioLen + 36;
byte[] header = new byte[44];
// 标准的WAV文件头填充代码...
out.write(header);
}
3. 实时处理音频数据(示例:实时音量计算)
while (isRecording) {
int readResult = audioRecord.read(audioData, 0, bufferSize);
double sum = 0;
for (int i = 0; i < readResult; i += 2) {
short sample = (short)((audioData[i+1] << 8) | audioData[i]);
sum += sample * sample;
}
double rms = Math.sqrt(sum / (readResult/2)); // 均方根值
updateVolumeUI(rms); // 更新UI显示音量
}
四、进阶技巧
1. 音频源类型选择
音频源常量 | 用途 |
---|---|
MIC | 主麦克风 |
VOICE_COMMUNICATION | 语音通话(会启用降噪) |
VOICE_RECOGNITION | 语音识别优化 |
CAMCORDER | 相机关联的麦克风 |
2. 低延迟配置(Android 8.0+)
// 在创建AudioRecord前设置低延迟模式
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioManager.setProperty("android.media.property.OUTPUT_FRAMES_PER_BUFFER", "256");
// 使用高性能采样率
int sampleRate = 48000; // 专业音频设备常用采样率
3. 处理音频焦点(避免和其他APP冲突)
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
am.requestAudioFocus(
focusChange -> { /* 处理焦点变化 */ },
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN
);
五、常见坑与填坑指南
-
报错:startRecording() failed - invalid operation
- 检查是否已经调用了
prepare()
或release()
- 确认权限已获取
- 检查是否已经调用了
-
录音数据全是0
- 检查麦克风是否被其他应用占用
- 尝试不同的音频源(如VOICE_RECOGNITION)
-
延迟太高
- 减小缓冲区大小(但不能小于getMinBufferSize返回值)
- 使用低延迟配置(见第四节)
-
不同手机效果差异大
- 测试主流机型
- 提供设置选项让用户调整采样率/缓冲区
六、完整示例代码框架
public class AudioRecorder {
private AudioRecord audioRecord;
private boolean isRecording;
private Thread recordingThread;
public void startRecording(File outputFile) {
// 1. 配置参数
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufferSize = AudioRecord.getMinBufferSize(...);
// 2. 创建AudioRecord
audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
sampleRate,
channelConfig,
audioFormat,
minBufferSize * 2
);
// 3. 开始录音
audioRecord.startRecording();
isRecording = true;
// 4. 启动数据读取线程
recordingThread = new Thread(() -> {
FileOutputStream fos = new FileOutputStream(outputFile);
writeWavHeader(fos, 0); // 先写入空头
byte[] buffer = new byte[minBufferSize];
while (isRecording) {
int bytesRead = audioRecord.read(buffer, 0, buffer.length);
fos.write(buffer, 0, bytesRead);
// 可以在这里添加实时处理逻辑
}
// 录音结束,更新WAV头
updateWavHeader(fos);
fos.close();
});
recordingThread.start();
}
public void stopRecording() {
isRecording = false;
try {
recordingThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
audioRecord.stop();
audioRecord.release();
}
}
七、总结
AudioRecord使用三步走:
- 准备阶段:配置参数 → 创建对象
- 运行阶段:开始录音 → 循环读取数据
- 收尾阶段:停止录音 → 释放资源
关键要点:
- 录音参数要根据实际需求调整(不是越高越好)
- 记得检查权限和释放资源
- PCM数据需要处理才能播放(加WAV头或转码)
- 实时处理时注意性能问题
就像专业录音师需要了解设备特性一样,用好AudioRecord需要理解它的参数和行为。现在,你可以开始打造自己的音频处理APP了!