Android Studio录制音频时如何消除麦克风拾取的扬声器声音?
解决播放音频同时录制麦克风时的回声问题
你遇到的核心问题是播放的音频被麦克风拾取,且使用AcousticEchoCanceler时崩溃,下面是针对性的解决方案:
一、崩溃原因排查
你之前的代码崩溃大概率是因为传入AcousticEchoCanceler.create()的id无效——MediaRecorder的音频会话ID需要在prepare()之后才能生成,提前传入错误ID会导致创建的aec实例为null,设置enabled时触发空指针异常。
二、修正后的Kotlin实现
1. 正确初始化录制端并启用回声消除
// 配置MediaRecorder参数 mediaRecorder?.apply { setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION) // 优先用通话级音频源,自带基础降噪 setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS) setAudioEncoder(MediaRecorder.AudioEncoder.AAC) setAudioSamplingRate(48000) setAudioEncodingBitRate(128000) setOutputFile(fileLoc) prepare() // 必须先执行prepare,才能获取有效音频会话ID } // 获取录制会话ID val audioSessionId = mediaRecorder?.audioSessionId ?: -1 // 初始化并启用回声消除器(加空判断避免崩溃) if (AcousticEchoCanceler.isAvailable() && audioSessionId != -1) { AcousticEchoCanceler.create(audioSessionId)?.let { aec -> aec.enabled = true } } // 启动录制 mediaRecorder?.start()
2. 播放端配套配置(关键)
要让回声消除器正常工作,播放音频的会话需要和录制会话关联,确保消除器能拿到播放数据用于抵消:
// 定义匹配录制场景的音频属性 val audioAttributes = AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build() // 构建AudioTrack时传入录制会话ID val audioTrack = AudioTrack( audioAttributes, AudioFormat.Builder() .setSampleRate(48000) .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setChannelMask(AudioFormat.CHANNEL_OUT_MONO) .build(), bufferSize, // 根据你的音频文件计算合适的缓冲区大小 AudioTrack.MODE_STREAM, audioSessionId // 和录制共用同一个会话ID ) // 启动播放 audioTrack.play()
三、额外注意事项
- 权限检查:确保已动态申请
RECORD_AUDIO和MODIFY_AUDIO_SETTINGS权限(Android 6.0及以上必须动态申请)。 - 设备兼容性:
AcousticEchoCanceler并非所有Android设备都支持,必须通过isAvailable()判断后再使用。 - 参数统一:录制和播放的采样率、声道数尽量保持一致,能提升回声消除效果。
内容的提问来源于stack exchange,提问作者swaroop bappanad
相关产品推荐
相关产品推荐

