【问题标题】:How can I make small 1-5 second pauses in text to speech speaking a String in Swift?如何在 Swift 中说出字符串时在文本到语音中进行 1-5 秒的小停顿?
【发布时间】:2019-04-14 11:38:36
【问题描述】:

我正在尝试使用 Swift 中的 AVFoundation Text to Speech 功能说出一个自定义字符串,该字符串会根据参数发生变化。如何实现单词之间的停顿?

假设这是我的字符串:

var spokenSentence = "I like Toast with lots of Butter, but banana is nice"

如何让 TTS 在“Butter”后暂停 3 秒?

这是我关于 TTS 的代码:

var spokenSentence = "I like Toast with lots of Butter, but banana is nice"
let synth = AVSpeechSynthesizer()
var utterance = AVSpeechUtterance(string: spokenSentence)

以后

synth.speak(utterance)

在 MacOS 上的 swift 之外我听说你可以使用 [[slnc 1000]] Swift 中有没有类似的功能?

【问题讨论】:

  • 我认为没有办法,我建议将此作为增强请求提交给 Apple。曾经可以让语音合成器服从各种元命令(你甚至可以让它唱歌),但现在已经不可能了。
  • 你可以引入自己的延迟,比如I did here

标签: swift avfoundation text-to-speech


【解决方案1】:

似乎AVSpeechUtterance 具有preUtteranceDelaypostUtteranceDelay 之类的属性。您可以通过编写一些预处理代码来利用这些功能:

extension AVSpeechSynthesizer {
    func speekWithDelay(_ text: String) {
        let pattern = #"([^{]*)(?:\{([0-9]+(?:\.[0-9]+))\})?"#
        let regex = try! NSRegularExpression(pattern: pattern)
        let matches = regex.matches(in: text, options: .anchored, range: NSRange(0..<text.utf16.count))
        for match in matches {
            let utteranceText = text[Range(match.range(at: 1), in: text)!]
            let utterance = AVSpeechUtterance(string: String(utteranceText))
            if let range = Range(match.range(at: 2), in: text) {
                let delay = TimeInterval(text[range])!
                utterance.postUtteranceDelay = delay
            }
            speak(utterance)
        }
    }
}

将其用作:

let synth = AVSpeechSynthesizer()

@IBAction func speakButtonPressed(_ sender: Any) {
    let spokenSentence = "I like Toast with lots of Butter,{3} but banana is nice"
    synth.speekWithDelay(spokenSentence)
}

请记住,AVSpeechSynthesizer 的实例需要保留在强引用中,直到说出最后一个话语,因此您最好将其保留为实例属性。

【讨论】:

  • 不幸的是,当我尝试这段代码时,当我在字符串中有一个 {} 时,它在“Butter”之后停止说话。我也收到以下错误消息: [AudioHAL_Client] HALC_ProxyIOContext.cpp:1399:IOWorkLoop: HALC_ProxyIOContext::IOWorkLoop: failed to send the final message to server, Error: 0x10000003 2019-04-14 16:28:09.091519+0200 myproject [ 18457:474227] [AudioHAL_Client] HALB_IOThread.cpp:251:_Start: HALB_IOThread::_Start: 已经有一个线程 2019-04-14 16:28:09.158372+0200 myproject[18457:474242] [aqme] 1396: AQDefaultDevice:由于重新配置挂起而放弃 I/O 周期 (1)
  • @Pilot_Tim,感谢您的报告,但这在我的测试项目中没有发生,它在我的环境中按预期工作。如果您可以提供更多信息来重现您所显示的问题,我会检查它。
猜你喜欢
  • 1970-01-01
  • 2016-09-10
  • 2019-05-13
  • 2016-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
相关资源
最近更新 更多