The AVSpeechSynthesizer works well if I don't try to stop it. After stopping and restarting, the next utterance begins where the last ended. Eg "Hello World" and "Hello Earth". When I stop the first one after "Hello", the next one will be spoken just as "Earth". Want I want is the full sentence. So:
Actual:
What I want:
.
class TextToSpeechService: NSObject, AVSpeechSynthesizerDelegate {
let synthesizer: AVSpeechSynthesizer = AVSpeechSynthesizer()
var wasStopped: Bool = false
init () {
super.init()
self.synthesizer.delegate = self
}
public func start (text: String, completion: @escaping (Result<Void, TextToSpeechError>) -> Void) {
self.setAudioPreferences()
self.wasStopped = false
let hasLanguage = AVSpeechSynthesisVoice.speechVoices().first(where: { $0.language == "de-DE" }) != nil
if (hasLanguage) {
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(identifier: "com.apple.ttsbundle.siri_Helena_de-DE_compact")
self.synthesizer.speak(utterance)
} else {
print("LANGUAGE NOT AVAILABLE")
}
}
public func stop () {
self.wasStopped = true
self.synthesizer.stopSpeaking(at: .immediate)
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
if !wasStopped {
print("success speaking")
}
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
if !wasStopped {
print("success speaking")
}
}
func setAudioPreferences () {
do {
let session = AVAudioSession.sharedInstance()
try session.setCategory(AVAudioSession.Category.playback, options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])
} catch let error {
print("audioSession properties weren't set. Error: \(error.localizedDescription)")
}
}
}
Calls (shortened)
let textToSpeechService = TextToSpeechService()
textToSpeechService.start(text: "Hello World")
// after word "Hello"
textToSpeechService.stop()
textToSpeechService.start(text: "Hello Earth")
Is it possible to reset the speechSynthesizer?
I had the same issue ...
At the moment you can use a "hack" - changing the stop method as below:
public func stop () {
self.wasStopped = true
self.synthesizer.stopSpeaking(at: .immediate)
let utterance = AVSpeechUtterance(string: "")
self.synthesizer.speak(utterance)
self.synthesizer.stopSpeaking(at: .immediate)
}
The text to speech service was just a part of the problem. I also have a speech recognizer and I always set the audio preferences.
Wrong 🚫
TTS:
try session.setCategory(AVAudioSession.Category.playback, options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])
STT:
try session.setCategory(AVAudioSession.Category.record, options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])
Right ✅
Now, I do this only once on init and for both:
try session.setCategory(AVAudioSession.Category.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.