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

ARKit应用中AVSpeechSynthesizer报‘Unable to list voice folder’错误,移类外仍无效求解决及替代

解决AVSpeechSynthesizer的“Unable to list voice folder”错误及替代方案

一、排查现有代码的潜在问题

  • 调整合成器声明位置:避免全局声明合成器,把它移到ViewController类内部作为实例属性,防止AVFoundation未完全初始化时创建实例:
import AVFoundation

class YourViewController: UIViewController {
    // 类内部声明合成器实例
    let synthesizer = AVSpeechSynthesizer()

    func testSpeak() {
        let utterance = AVSpeechUtterance(string: "screen has been tapped")
        // 先验证指定语言语音是否可用,避免强行赋值触发错误
        if let voice = AVSpeechSynthesisVoice(language: "en-US") {
            utterance.voice = voice
        }
        synthesizer.speak(utterance)
    }
}
  • 检查设备可用语音:有些设备可能未预装目标语言语音,添加代码查看可用资源:
// 在testSpeak函数内添加,打印所有可用语音
let availableVoices = AVSpeechSynthesisVoice.speechVoices()
availableVoices.forEach { voice in
    print("语音名称:\(voice.name),语言代码:\(voice.language)")
}
  • 确保主线程调用:如果在ARKit的后台回调(如渲染回调)中调用朗读功能,需切换到主线程执行:
DispatchQueue.main.async {
    self.testSpeak()
}

二、替代方案

如果上述方法无效,推荐两种适合少量文本朗读的轻量方案:

  • 使用无障碍播报API:直接调用系统无障碍播报功能,无需手动管理合成器:
import UIKit

func testSpeak() {
    UIAccessibility.post(notification: .announcement, argument: "screen has been tapped")
}
  • 预录制音频播放:若文本固定,提前录制对应音频文件添加到项目,用AVAudioPlayer播放:
import AVFoundation

class YourViewController: UIViewController {
    var audioPlayer: AVAudioPlayer?

    func playPreRecordedAudio() {
        guard let audioURL = Bundle.main.url(forResource: "tap_prompt", withExtension: "mp3") else { return }
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
            audioPlayer?.play()
        } catch {
            print("音频播放失败:\(error.localizedDescription)")
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 19:22:41