使用App Intents启动语音识别触发IsFormatSampleRateAndChannelCountValid错误
问题解决:App Intent启动Speech Framework时的音频格式错误
核心原因
Siri处理App Intent期间会占用麦克风,且强制使用特定音频格式(通常为16kHz单声道),你当前代码设置的音频格式与此冲突,导致installTap触发格式验证失败。单纯异步调用无法解决,因为Siri的音频会话优先级更高,需先适配其格式或等待Siri释放音频会话。
具体修复步骤
1. 适配Siri兼容的音频格式
放弃硬编码采样率和声道数,强制设置为Siri兼容的格式:
// 替换原格式创建代码,使用16kHz单声道格式 let compatibleFormat = AVAudioFormat(standardFormatWithSampleRate: 16000, channels: 1)!
或更稳妥地基于输入节点默认格式调整:
guard let inputNode = audioEngine.inputNode else { return } let inputFormat = inputNode.inputFormat(forBus: 0) // 转换为Siri兼容的16kHz单声道格式 let compatibleFormat = AVAudioFormat(standardFormatWithSampleRate: 16000, channels: 1)!
2. 等待Siri释放音频会话
在App Intent处理逻辑中,延迟初始化AudioEngine,给Siri足够时间释放麦克风:
import AVFoundation func handle(intent: ListenIntent) async throws -> IntentResult { // 配置并激活音频会话(需确保Info.plist已添加麦克风权限描述) let session = AVAudioSession.sharedInstance() try await session.setCategory(.record, mode: .default, options: .duckOthers) try await session.setActive(true, options: .notifyOthersOnDeactivation) // 延迟1秒等待Siri释放麦克风(可根据实际情况调整时长) try await Task.sleep(nanoseconds: 1_000_000_000) // 再启动语音识别流程 startSpeechRecognition() return .result() }
3. 保证Speech请求与AudioEngine格式一致
创建SFSpeechAudioBufferRecognitionRequest时,传入与AudioEngine相同的格式:
let recognitionRequest = SFSpeechAudioBufferRecognitionRequest() recognitionRequest.shouldReportPartialResults = true // 同步音频设置 recognitionRequest.audioSettings = audioEngine.inputNode.inputFormat(forBus: 0).settings
关键注意事项
- 必须在Info.plist中添加
NSMicrophoneUsageDescription和NSSpeechRecognitionUsageDescription权限描述,否则权限请求会失败。 - App Intent的处理在后台队列执行,需将AudioEngine和Speech相关操作放在主线程或合适队列中(可通过
DispatchQueue.main.async包裹)。 - 测试时优先通过Intent Widget触发,避免Siri实时占用麦克风干扰调试。
内容的提问来源于stack exchange,提问作者tamaramaria
相关产品推荐
相关产品推荐

