How to know when an AVSpeechUtterance has finished, so as to continue app activity?

拟墨画扇 提交于 2019-12-08 10:38:12

问题


When an AVSpeechUtterance is speaking, I want to wait until it's finished before doing something else.

There is a property of AVSpeechSynthesizer that's seemingly indicative of when speech is occuring:

isSpeaking

As stupid and simple as this question might sound, I'm wondering how do I use/check this property to wait until speech has concluded before going on?

ALTERNATIVELY:

There's a delegate, that I'm also clueless as to how to use, which has an ability to do something when an utterance has finished:

AVSpeechSynthesizerDelegate

There's an answer, here, that says to use this. But that doesn't help me because I don't know how to use a Delegate.

UPDATE:

This is how I setup my speaking class:

import AVFoundation

class CanSpeak: NSObject, AVSpeechSynthesizerDelegate {

    let voices = AVSpeechSynthesisVoice.speechVoices()
    let voiceSynth = AVSpeechSynthesizer()
    var voiceToUse: AVSpeechSynthesisVoice?

    override init(){
        voiceToUse = AVSpeechSynthesisVoice.speechVoices().filter({ $0.name == "Karen" }).first
    }

    func sayThis(_ phrase: String){
        let utterance = AVSpeechUtterance(string: phrase)
        utterance.voice = voiceToUse
        utterance.rate = 0.5
        voiceSynth.speak(utterance)
    }
}

UPDATE 2: Wrongheaded workaround...

using the above mentioned isSpeaking property, in the gameScene:

voice.sayThis(targetsToSay)

    let initialPause = SKAction.wait(forDuration: 1.0)
    let holdWhileSpeaking = SKAction.run {
        while self.voice.voiceSynth.isSpeaking {print("STILL SPEAKING!")}
    }
    let pauseAfterSpeaking = SKAction.wait(forDuration: 0.5)
    let doneSpeaking = SKAction.run {print("TIME TO GET ON WITH IT!!!")}

run(SKAction.sequence(
    [   initialPause,
        holdWhileSpeaking,
        pauseAfterSpeaking,
        doneSpeaking
    ]))

回答1:


Delegate pattern is one of the most common used design pattern in object-oriented programming, it's not as hard as it seems. For your case, you can simply let your class (a game scene) to be a delegate of the CanSpeak class.

protocol CanSpeakDelegate {
   func speechDidFinish()
}

Next set AVSpeechSynthesizerDelegate to your CanSpeak class, declare CanSpeakDelegate and then use AVSpeechSynthesizerDelegate delegate function.

class CanSpeak: NSObject, AVSpeechSynthesizerDelegate {

   let voices = AVSpeechSynthesisVoice.speechVoices()
   let voiceSynth = AVSpeechSynthesizer()
   var voiceToUse: AVSpeechSynthesisVoice?

   var delegate: CanSpeakDelegate!

   override init(){
      voiceToUse = AVSpeechSynthesisVoice.speechVoices().filter({ $0.name == "Karen" }).first
      self.voiceSynth.delegate = self
   }

   func sayThis(_ phrase: String){
      let utterance = AVSpeechUtterance(string: phrase)
      utterance.voice = voiceToUse
      utterance.rate = 0.5
      voiceSynth.speak(utterance)
   }

   func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
      self.delegate.speechDidFinish()
   }
}

Lastly in your game scene class, simply conform to CanSpeakDelegate and set it as the delegate of your CanSpeak class.

class GameScene: NSObject, CanSpeakDelegate {

   let canSpeak = CanSpeak()

   override init() {
      self.canSpeak.delegate = self
   }

   // This function will be called every time a speech finishes
   func speechDidFinish() {
      // Do something
   }
}



回答2:


Sets up delegate to your AVSpeechSynthesizer instance.

voiceSynth.delegate = self

Then, implements didFinish method as below:

func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, 
                  didFinish utterance: AVSpeechUtterance) {
    // Implements here.
}



回答3:


Try AVSpeechSynthesizerDelegate with method:

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance;


来源:https://stackoverflow.com/questions/40856037/how-to-know-when-an-avspeechutterance-has-finished-so-as-to-continue-app-activi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!