In my app I have a behavior where it can happen that 2 AVSpeech synthesizers are playing at the same time and would therefore overlap. In this case, is there a way to cancel all voice output currently being played as soon as a new voice output is started? Thanks very much! This is my code:
func makeVoiceOutput(_ text: String) {
let spech = AVSpeechUtterance(string: text)
spech.voice = AVSpeechSynthesisVoice(language: Locale.current.languageCode)
let synth = AVSpeechSynthesizer()
synth.speak(spech)
}
CodePudding user response:
The AVSpeechSynthesizer
documentation https://developer.apple.com/documentation/avfaudio/avspeechsynthesizer/ says:
If the synthesizer is speaking, the synthesizer adds utterances to a queue and speaks them in the order it receives them.
So you should add your speech texts to an instance of AVSpeechSynthesizer
that you create once, and not create a new one every time in your func. That should lead to queueing the spoken texts one after another.
Alternatively using isSpeaking
and stopSpeaking
you can also stop the current speech output.
struct ContentView: View {
let synth = AVSpeechSynthesizer() // create once
@State private var input = ""
var body: some View {
Form {
TextField("Text", text: $input)
Button("Speak") {
makeVoiceOutput(input)
}
Button("Stop") {
stopVoiceOutput()
}
}
}
func makeVoiceOutput(_ text: String) {
let spech = AVSpeechUtterance(string: text)
spech.voice = AVSpeechSynthesisVoice(language: Locale.current.languageCode)
// let synth = AVSpeechSynthesizer()
synth.speak(spech)
}
func stopVoiceOutput() {
synth.stopSpeaking(at: .immediate)
}
}