Ошибка AVSpeechSynthesizer: AVSpeechUtterance не должен ставиться в очередь дважды - PullRequest
0 голосов
/ 04 декабря 2018

Я немного застрял.

Вот мой код:

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
    }
}

Согласно документации AVSpeechSynthesizer.stopSpeaking(at:):

Остановка синтезатораотменяет любую дальнейшую речь;В отличие от того, когда синтезатор приостановлен, речь не может быть возобновлена ​​с того места, где она остановилась. Все высказывания, которые еще предстоит произнести, удаляются из очереди синтезатора .

Я всегда получаю сообщение об ошибке (AVSpeechUtterance не должен ставиться в очередь дважды), когда я вставляю AVSpeechUtterance в AVSpeechSynthesizer очередь.Но это должно прекратиться в соответствии с док.

1 Ответ

0 голосов
/ 09 мая 2019

При остановке проигрывателя высказывания определенно удаляются из очереди.

Однако в вашей функции moveBackward вы вставляете еще один AVSpeechUterrance в playQueue[0], полный массив которого представляет очередь проигрывателя.

Предполагая, что остановки происходят с currentIndex = 2, следующие снимки подтверждают, что один и тот же объект дважды вводится в очередь :

  • Копировать backedQueue[1] это копия playQueue[1] (тот же адрес памяти) .enter image description here

  • Вставить backedQueue[1] в playQueue[0] (прежнее playQueue[1] становится новым playQueue[2]) .enter image description here

К сожалению, как указывает система, AVSpeechUtterance не должен ставиться в очередь дважды , и это именно то, что вы здесь делаете:объекты в индексах playQueue 0 и 2 имеют один и тот же адрес памяти .

Последний цикл после вставки нового объекта в индекс 0 просит синтезатор речи поместить все высказывания в свою новую очередь... и два из них одинаковы.

Вместо копирования playedQueue в backedQueue (оба содержат одинаковые адреса памяти для своих объектов) ИЛИ добавляя одинаковыевысказывание в обоих массивах, я предлагаю создать различные экземпляры высказываний , которые будут выглядеть следующим образом:

    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не должен ставиться в очередь дважды .

...