在Android中实现音频录制功能需要根据不同的使用场景选择合适的API。以下是完整的实现方案解析,包含关键API对比、具体实现步骤和优化建议:
1. 音频录制API选型
API | 最低版本 | 延迟 | 音质支持 | 适用场景 |
---|---|---|---|---|
MediaRecorder | API 1 | 高 | 自适应 | 简单录音(输出压缩文件) |
AudioRecord | API 3 | 中 | 原始PCM | 实时处理/自定义编码 |
MediaCodec + AudioRecord | API 16 | 中 | 可配置 | 高效硬编(AAC/Opus) |
AAudio | API 26 | 极低 | 高保真 | 专业低延迟录音 |
2. 核心实现方案
方案一:MediaRecorder(快速实现)
// 配置录音参数
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioSamplingRate(44100); // 44.1kHz
recorder.setAudioEncodingBitRate(128000); // 128kbps
recorder.setOutputFile(outputFile.getAbsolutePath());
// 开始录音
try {
recorder.prepare();
recorder.start();
} catch (IOException e) {
e.printStackTrace();
}
// 停止录音
recorder.stop();
recorder.release();
特点:
-
自动完成PCM→AAC/AMR编码
-
输出可直接播放的标准音频文件
-
不支持实时音频处理
方案二:AudioRecord + MediaCodec(进阶实现)
// 1. 配置AudioRecord获取原始PCM
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
sampleRate,
channelConfig,
audioFormat,
minBufferSize * 2); // 双缓冲
// 2. 配置MediaCodec进行AAC编码
MediaCodec codec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectLC);
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
// 3. 启动录制线程
audioRecord.startRecording();
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
while (isRecording) {
// 读取PCM数据
int inputBufferIndex = codec.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
ByteBuffer buffer = inputBuffers[inputBufferIndex];
int readSize = audioRecord.read(buffer, minBufferSize);
codec.queueInputBuffer(inputBufferIndex, 0, readSize, 0, 0);
}
// 获取编码后的AAC数据
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = codec.dequeueOutputBuffer(bufferInfo, 10000);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
writeToFile(outputBuffer); // 写入MP4文件
codec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = codec.dequeueOutputBuffer(bufferInfo, 0);
}
}
优势:
-
可实时处理PCM数据(如降噪、变声)
-
灵活控制编码参数
-
比MediaRecorder更低的资源占用
3. 关键优化技术
音频焦点管理
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
am.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
stopRecording(); // 来电时自动暂停
}
}
}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
低延迟配置(Android 8.0+)
// 使用AAudio实现
AAudioStreamBuilder builder = new AAudioStreamBuilder();
builder.setDirection(AAudioStreamBuilder.DIRECTION_INPUT);
builder.setPerformanceMode(AAudioStreamBuilder.PERFORMANCE_LOW_LATENCY);
builder.setSharingMode(AAudioStreamBuilder.SHARING_EXCLUSIVE);
AAudioStream stream = builder.build();
stream.requestStart();
// 读取音频数据回调
stream.setDataCallback((stream, audioData) -> {
processAudioData(audioData); // 实时处理
});
后台录制保活
<!-- AndroidManifest.xml -->
<service
android:name=".RecordingService"
android:foregroundServiceType="microphone"
android:exported="false"/>
// 启动前台服务
startForeground(NOTIFICATION_ID, buildNotification(),
ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
4. 常见问题解决方案
问题1:录音失真
-
原因:采样率/比特率配置不当
-
修复:
// 检查设备支持的真实采样率 AudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); // 使用最接近的2的幂次方值(如44100→48000)
问题2:文件无法播放
-
修复:添加AAC ADTS头
byte[] adtsHeader = new byte[7]; addADTStoPacket(adtsHeader, packetLen); // 填充头信息 outputStream.write(adtsHeader); outputStream.write(aacData);
问题3:高功耗
-
优化:动态调整采样率
if (BatteryManager.isPowerSaveMode()) { sampleRate = 16000; // 省电模式降低质量 }
5. 平台兼容性处理
// 检查录音权限
if (ContextCompat.checkSelfPermission(this, RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{RECORD_AUDIO}, REQUEST_CODE);
}
// 处理不同厂商的麦克风差异
if (Build.MANUFACTURER.equals("Xiaomi")) {
// 小米设备需特殊处理
audioSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
}
6. 推荐架构设计
录音模块分层架构:
[Audio Input] → [Audio Processing] → [Encoding] → [Storage]
↑ ↑ ↑
[设备麦克风] [降噪/增益算法] [AAC/Opus编码]
通过合理选择API组合(如AudioRecord+Opus编码),可实现延迟<50ms的专业级录音应用。对于语音社交类APP,建议优先考虑AAudio方案以获得最佳实时性。