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

Swift中SpeechSynthesizer遇句号后接数字时无自然停顿问题求助

解决AVSpeechSynthesizer在句号后紧跟数字时无自然停顿的问题

这确实是AVSpeechSynthesizer处理英文文本时一个挺头疼的小问题——它的内置文本解析逻辑会把句号后跟数字的结构误判为同一句话,跳过了本该有的自然停顿。下面给你几个实用的解决方案:

方案1:拆分文本为多个Utterance,手动控制停顿

最直接的方式是把原文本拆成独立的语句片段,通过设置postUtteranceDelay来控制两个片段之间的停顿时长,完全贴合自然说话的节奏:

let synthesizer = AVSpeechSynthesizer()
let session = AVAudioSession.sharedInstance()
do {
    try session.setCategory(.playback, options: .duckOthers)
    try session.setActive(true)
} catch {
    print(error.localizedDescription)
}

// 拆分语句,分别创建Utterance
let firstUtterance = AVSpeechUtterance(string: "Hello everyone.")
firstUtterance.voice = AVSpeechSynthesisVoice(language: "en-US")
firstUtterance.rate = AVSpeechUtteranceDefaultSpeechRate
firstUtterance.postUtteranceDelay = 0.5 // 可根据需求调整,0.5秒是接近自然停顿的时长

let secondUtterance = AVSpeechUtterance(string: "2 minutes to go.")
secondUtterance.voice = AVSpeechSynthesisVoice(language: "en-US")
secondUtterance.rate = AVSpeechUtteranceDefaultSpeechRate

// 依次添加到合成器播放队列
synthesizer.speak(firstUtterance)
synthesizer.speak(secondUtterance)

方案2:使用SSML标记语言精确控制语音节奏

如果你需要处理更复杂的文本结构(比如多种停顿、语调变化),可以用SSML(语音合成标记语言)来明确指定停顿。AVSpeechSynthesizer从iOS 13开始支持SSML格式,用<break>标签就能精准控制停顿时长:

let synthesizer = AVSpeechSynthesizer()
let session = AVAudioSession.sharedInstance()
do {
    try session.setCategory(.playback, options: .duckOthers)
    try session.setActive(true)
} catch {
    print(error.localizedDescription)
}

// 用SSML包装文本,添加500毫秒的停顿
let ssmlText = """
<speak>
Hello everyone.<break time="500ms"/> 2 minutes to go.
</speak>
"""

// 使用SSML初始化Utterance(注意处理错误)
do {
    let utterance = try AVSpeechUtterance(ssml: ssmlText)
    utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
    utterance.rate = AVSpeechUtteranceDefaultSpeechRate
    synthesizer.speak(utterance)
} catch {
    print("SSML格式错误:\(error.localizedDescription)")
}

问题根源小解析

AVSpeechSynthesizer的英文文本解析器会对标点后的内容做语义判断,当句号紧跟数字时,它可能误将数字识别为前一句的补充信息(比如类似“Chap. 2”这种章节编号的格式),从而跳过了句号对应的停顿规则。所以我们需要通过手动拆分或SSML标记的方式,强制告诉合成器这里需要停顿。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:26:28