AVAudioEngine与AVAudioPlayer启用setVoiceProcessingEnabled后音量低及报错问题
AVAudioEngine结合SFSpeechRecognition时的错误与音量问题解决
问题场景与现象
- 使用
AVAudioEngine作为SFSpeechRecognition的输入源,AVAudioPlayer负责声音输出 - 按照WWDC2019 Session 510的说明,在
AVAudioInputNode和AVAudioOutputNode上都调用了setVoiceProcessingEnabled(true)以消除扬声器到麦克风的回授 - 当
speechRecognitionEnabled设为YES时,Xcode抛出错误:
throwing 18,446,744,073,709,551,615 from AU (0x13bf98dd0): auou/vpio/appl, render err: 18,446,744,073,709,551,615
- 节点初始化无报错,功能看似正常,但即使调高系统音量,输出音量仍极低
- 尝试过带混音节点和不带混音节点的多种
AVAudioEngine配置,均无法获得正常音量输出
解决方案
1. 修正Voice Processing的启用范围
Voice Processing是专门为输入节点设计的音频处理功能,不要在AVAudioOutputNode上启用它。输出节点启用该功能会导致音频路由冲突,进而触发渲染错误(你看到的大数字错误码实际是kAudioUnitErr_FailedInitialization的无符号表示,即-1)。
修改代码,仅在输入节点启用:
// 正确做法:只给输入节点开启Voice Processing audioEngine.inputNode.setVoiceProcessingEnabled(true) // 移除对outputNode的setVoiceProcessingEnabled调用 // audioEngine.outputNode.setVoiceProcessingEnabled(true) // 删掉这行
2. 修复输出音量过低问题
方案A:调整AVAudioPlayer的音量与AudioSession配置
- 确保
AVAudioPlayer的volume属性设置为合理值(比如1.0) - 配置
AVAudioSession为播放+录音模式,并允许混音:
do { let session = AVAudioSession.sharedInstance() try session.setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers, .defaultToSpeaker]) try session.setActive(true) } catch { print("AudioSession配置失败: \(error)") }
defaultToSpeaker会强制音频从扬声器输出,避免默认使用听筒导致音量低;mixWithOthers确保不会阻塞其他音频输出。
方案B:改用AVAudioEngine的输出节点替代AVAudioPlayer
如果必须结合AVAudioEngine使用,直接将音频文件通过AVAudioFile读取后连接到输出节点,这样可以更好地与引擎的路由整合:
let audioFile = try AVAudioFile(forReading: audioURL) let playerNode = AVAudioPlayerNode() audioEngine.attach(playerNode) // 连接playerNode到输出节点,可添加混音器调整音量 let mixer = audioEngine.mainMixerNode audioEngine.connect(playerNode, to: mixer, format: audioFile.processingFormat) audioEngine.connect(mixer, to: audioEngine.outputNode, format: audioFile.processingFormat) // 调整混音器音量 mixer.outputVolume = 1.0 playerNode.scheduleFile(audioFile, at: nil) try audioEngine.start() playerNode.play()
3. 避免Speech Recognition与音频输出的路由冲突
当SFSpeechRecognition启动时,系统会优先占用音频输入资源,此时需要确保输出路由不会被强制切换到听筒。可以在启动识别前再次确认AudioSession配置:
func startSpeechRecognition() { do { let session = AVAudioSession.sharedInstance() try session.setCategory(.playAndRecord, mode: .voiceChat, options: .defaultToSpeaker) try session.setActive(true) // 启动SFSpeechRecognition任务... } catch { print("启动识别前配置失败: \(error)") } }
mode: .voiceChat会自动优化语音通话场景的音频处理,同时配合defaultToSpeaker保证输出音量。
内容的提问来源于stack exchange,提问作者sleep9
相关产品推荐
相关产品推荐

