Android中实现音频录制功能

在Android中实现音频录制功能需要根据不同的使用场景选择合适的API。以下是完整的实现方案解析,包含关键API对比、具体实现步骤和优化建议:


1. 音频录制API选型

API最低版本延迟音质支持适用场景
MediaRecorderAPI 1自适应简单录音(输出压缩文件)
AudioRecordAPI 3原始PCM实时处理/自定义编码
MediaCodec + AudioRecordAPI 16可配置高效硬编(AAC/Opus)
AAudioAPI 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方案以获得最佳实时性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值