首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVSpeechSynthesizer错误:不能将AVSpeechUtterance排队两次

AVSpeechSynthesizer错误:不能将AVSpeechUtterance排队两次
EN

Stack Overflow用户
提问于 2018-12-04 06:14:09
回答 1查看 850关注 0票数 2

我被卡住了一点。

这是我的代码:

代码语言:javascript
复制
let speaker = AVSpeechSynthesizer()
var playQueue = [AVSpeechUtterance]() // current queue
var backedQueue = [AVSpeechUtterance]() // queue backup

...

func moveBackward(_ currentUtterance:AVSpeechUtterance) {
    speaker.stopSpeaking(at: .immediate)
    let currentIndex = getCurrentIndexOfText(currentUtterance)
    // out of range check was deleted
    let previousElement = backedQueue[currentIndex-1]
    playQueue.insert(previousElement, at: 0)
    for utterance in playQueue {
        speaker.speak(utterance) // error here
    }
}

根据docs AVSpeechSynthesizer.stopSpeaking(at:)

停止合成器将取消任何进一步的语音;当合成器暂停时,无法在停止时恢复语音。任何尚未说出的话语都会从合成器的队列中删除。

当我在AVSpeechUtterance队列中插入一个AVSpeechUtterance时,我总是得到错误(AVSpeechUtterance不会被排队两次)。但根据医生的说法应该停下来。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-09 08:11:30

当停止玩家时,话语肯定会从队列中删除。

但是,在moveBackward函数中,您在playQueue[0]插入另一个AVSpeechUterrance,其完整数组表示播放机队列。

假设停止发生在currentIndex = 2中,下面的快照证明了同一个对象在队列中被注入了两次

  • 复制backedQueue[1],即playQueue[1]的副本(相同的内存地址)。

  • 插入backedQueue[1] at playQueue[0] (前playQueue[1]成为新的playQueue[2]__)。

不幸的是,正如系统所指出的,AVSpeechUtterance不能排队两次,这正是您在这里要做的: playQueue索引0和2的对象具有相同的内存地址

在索引0处插入新对象后的最后一个循环要求语音合成器将所有语句放入其所有新队列中.其中两个人是一样的。

与其将playedQueue复制到backedQueue (两个数组中都包含相同的内存地址)或在两个数组中附加相同的语句,我建议创建不同的语音实例,如下所示:

代码语言:javascript
复制
    for i in 1...5 {

        let stringNb = "number " + String(i) + " of the speech synthesizer."
        let utterance = AVSpeechUtterance(string: stringNb)
        playQueue.append(utterance)

        let utteranceBis = AVSpeechUtterance(string: stringNb)
        backedQueue.append(utteranceBis)
    }

按照这条建议,您不应该遇到错误,AVSpeechUtterance不应该被排队两次。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53606746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档