如何让语音合成器一个接一个地说出一堆话语?

How to make speech synthesiser speak a bunch of utterances, one after another?

我正在构建一个应用程序,它将逐一朗读存储在播放列表中的 sentences/words。播放列表和其中的项目都存储在核心数据中。

我在故事板中添加了一个 play/stop 按钮。这是它的事件处理程序:

@IBAction func playClick(sender: UIBarButtonItem) {
    if isPlaying {
        synthesizer.stopSpeakingAtBoundary(.Immediate)
        isPlaying = false
        sender.image = UIImage(named: "play")
    } else {
        sender.image = UIImage(named: "stop")
        isPlaying = true
        for string in playlist.utterrances! {
            let utterance = UserSettings.getPrefUtterance((string as! Utterance).string!)
            utterance.postUtteranceDelay = 2
            synthesizer.speakUtterance(utterance)
        }
        isPlaying = false
        sender.image = UIImage(named: "play")
    }
}

isPlaying(类型Bool),synthesizer(类型AVSpeechSynthesizer)和playlist(类型Playlists,实体描述)是class级变量。

我认为这里的代码很清楚。首先,我决定按钮是停止还是启动合成器。如果是后者,循环遍历播放列表中的项目并合成它们。然后切换图像并变异isPlaying

但是当我 运行 应用程序并按下按钮时,什么也没有发生。没有声音,没有图像变化,什么都没有。我认为这是因为方法中的最后两行,所以我删除了它们。这一次,按钮的图像发生了变化,但仍然没有声音。

我想这一定是因为我告诉合成器在最后一句话说完之前就开始说话了。或者我需要知道合成器何时停止说话并开始另一个话语。

"But why don't you just join the strings and synthesise it just for once?",你问了。因为我想在播放列表中的每个项目之间有两秒的延迟!

问题:

如何逐个播放播放列表中的内容? (中间有明显的延迟)

我需要使用哪些字符来创建 AVSpeechUtterance 以便它可以暂停一段明显的时间?

最好的方法是使用 AVSpeechSynthesizerDelegate

它有一个方法...speechSynthesizer(_:didFinishSpeechUtterance:) 话语结束时调用。

您可以跟踪当前正在说的话语,当代理人收到发言结束通知时开始下一个话语。

如果您希望它们仅在单击按钮时播放,则在代表收到通知 didStartSpeechUtterance 时禁用按钮,然后在 didFinish... 上启用按钮。