Swift开发:录制音频时如何屏蔽系统播放的音频?
解决AVAudioRecorder录制时拾取播放音乐的问题
可以实现让录制器忽略正在播放的音乐,核心是利用AVAudioSession的回声消除(AEC)和降噪功能,调整会话配置即可,以下是具体方案:
关键原理
当使用.playAndRecord会话类别时,搭配特定模式(如.videoRecording或.voiceChat),系统会自动启用回声消除功能——它能识别并抵消从扬声器播放出来的音频,避免被麦克风拾取。但你的现有配置里的.mixWithOthers选项会破坏这个功能,因为该选项允许其他音频与你的应用音频混合,导致系统无法准确获取播放的音频流来执行回声消除。
代码修改
1. 调整音频会话配置
修改handleAudioSessionCategory函数,移除.mixWithOthers选项,并为无耳机场景启用带回声消除的模式:
private func handleAudioSessionCategory(areHeadphonesConnected: Bool) { do { let session = AVAudioSession.sharedInstance() if areHeadphonesConnected { // 耳机连接时,使用videoRecording模式(自带降噪) try session.setCategory(.playAndRecord, mode: .videoRecording) } else { // 无耳机时,用voiceChat或videoRecording模式,启用默认扬声器,不要加mixWithOthers try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker, .allowBluetooth]) } try session.setActive(true) } catch { print("音频会话配置失败: \(error.localizedDescription)") } }
2. 增强录制器的语音处理(可选)
iOS 10及以上版本,可以开启AVAudioRecorder的语音处理功能,进一步强化降噪和回声消除:
do { audioRecorder = try AVAudioRecorder(url: audioFileURL!, settings: settings) audioRecorder?.isVoiceProcessingEnabled = true // 启用语音处理 audioRecorder?.record() } catch { finishRecordingAudio(success: false) }
3. 移除不必要的会话选项
确保不要使用.mixWithOthers,因为它会让系统无法独占音频路径,导致回声消除失效。如果必须让其他音乐继续播放,那回声消除无法工作(因为系统无法追踪其他应用的音频流),这种情况下只能通过第三方音频处理库来做降噪,但复杂度会高很多。
注意事项
- 测试时确保设备支持回声消除:大部分iOS设备(iPhone、iPad)都支持,但部分老旧设备可能有限制。
- 不要用
try?忽略错误,捕获错误能帮你排查会话配置失败的问题。
内容的提问来源于stack exchange,提问作者Sotiris Kaniras
相关产品推荐
相关产品推荐

