Reputation: 441
Im using the code below to read random sentences at a random time. However I run into the problem when a random sentence is called to be read while the previous sentence is still being spoken by the AVSpeechSynthesizer, making the second sentence not spoken. What I am asking is, how can I get the second sentence to be spoken after the first sentence is finished being spoken??
Any import would be appreciated. Cheers
Heres my code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var myTimer = Timer()
let string = ["what kind of car do you have?", "do you like the beach?","did you bring a towel?","There are big waves today"]
var randomTimer = Int()
@objc func speakToMe(){
let random = Int.random(in: 0...3)
randomTimer = Int.random(in: 0...2)
print(randomTimer)
print(string[random])
let utterance = AVSpeechUtterance(string: string[random])
utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
utterance.rate = 0.1
let synthesizer = AVSpeechSynthesizer()
synthesizer.speak(utterance)
}
override func viewDidLoad() {
super.viewDidLoad()
speakToMe()
myTimer = Timer.scheduledTimer(timeInterval: TimeInterval(randomTimer), target: self, selector: #selector(ViewController.speakToMe), userInfo: nil, repeats: true)
}
}
Upvotes: 1
Views: 1621
Reputation: 71854
You can simply use AVSpeechSynthesizerDelegate
for that and you can remove timer from your code.
And to use AVSpeechSynthesizerDelegate
first you need to confirm your view controller with AVSpeechSynthesizerDelegate
like shown below:
class ViewController: UIViewController, AVSpeechSynthesizerDelegate {
next thing is you need to add
synthesizer.delegate = self
in your viewDidLoad
method. and you need to declare
let synthesizer = AVSpeechSynthesizer()
outside the methods and inside the class.
And you can use randomElement
property to find random element from string
array.
And your final code will look like:
import UIKit
import AVFoundation
class ViewController: UIViewController, AVSpeechSynthesizerDelegate {
let string = ["what kind of car do you have?", "do you like the beach?","did you bring a towel?","There are big waves today"]
let synthesizer = AVSpeechSynthesizer()
override func viewDidLoad() {
super.viewDidLoad()
synthesizer.delegate = self
speakToMe()
}
@objc func speakToMe(){
let utterance = AVSpeechUtterance(string: string.randomElement()!)
utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
utterance.rate = 0.1
synthesizer.speak(utterance)
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
speakToMe()
}
}
EDIT:
Since you are using only 4 elements in your array there will be possibilities to repeat same sentence many time when you take random string for it so you can add one more logic here which will prevent it.
Update your speakToMe
function like below:
@objc func speakToMe(){
var randomStr = string.randomElement()!
while previousStr == randomStr {
randomStr = string.randomElement()!
}
previousStr = randomStr
let utterance = AVSpeechUtterance(string: randomStr)
utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
utterance.rate = 0.1
synthesizer.speak(utterance)
}
And declare var previousStr = ""
outside the function.
Upvotes: 2