You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS16下AVSpeechSynthesizer缓冲写入报错-66686的技术求助

解决iOS16下AVSpeechSynthesizer write方法结合AVAudioPlayerNode的-66686错误

错误码说明

-66686 对应AudioQueue的kAudioQueueErr_InvalidRunState,表示尝试向处于无效运行状态的音频队列入队缓冲。iOS16后AVSpeechSynthesizer的write方法内部音频队列的状态管理逻辑有变更,导致之前的适配逻辑失效。

针对性解决步骤

  • 确保AVAudioPlayerNode状态正确:在向playerNode入队缓冲前,必须保证playerNode已启动(调用playerNode.play()),且处于活跃状态。避免在playerNode未启动或已停止时尝试入队缓冲。
  • 同步缓冲入队的线程:将缓冲入队操作(playerNode.scheduleBuffer(_:completionHandler:))移至音频引擎的渲染线程执行,可通过AVAudioEngine.mainMixerNode.installTap(onBus:bufferSize:format:)的回调线程处理,或使用DispatchQueue.global(qos: .userInitiated)同步执行,避免跨线程状态竞争。
  • 调整write方法的参数配置:调用write(_:toBuffer:maxPacketCount:startTime:completionHandler:)时,确保startTime设置为AVSpeechSynthesisVoice.startTimeImmediate,且缓冲的格式与playerNode的输入格式完全匹配(采样率、通道数、编码格式)。

更优的缓冲播放替代方案

如果上述方法无法解决问题,可改用以下方案:

  • 直接基于AVAudioEngine捕获合成音频:放弃write方法,通过AVSpeechSynthesizer的delegate方法(speechSynthesizer(_:didStart:)等)配合AVAudioEngine的输入节点捕获合成音频,实时处理后再通过输出节点播放。这种方式更符合iOS16的音频框架设计逻辑。
  • 预合成音频文件再播放:使用write(_:toFile:format:completionHandler:)将合成音频写入临时文件,再通过AVAudioPlayer或AVAudioPlayerNode播放文件。这种方式避开了实时缓冲入队的状态问题,稳定性更高,适合对实时性要求不高的场景。

测试发现空回调也会生成错误日志,说明该错误源于系统内部AVSpeechSynthesizer的音频队列状态管理,而非自定义回调的处理逻辑,因此优先调整音频播放节点的状态和操作时机。

内容的提问来源于stack exchange,提问作者nishith Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:21:29