Reputation: 2322
I have implemented text-to-speech in my app and it works fine with the code I currently use. Basically an algo creates a text, and then if the user clicks on the UIButton the text is being spoken.
Challenge: I want to enable the same UIButton to pause the synthesizer, if the button has already been tapped (i.e. text is currently being spoken) and then resume speaking where it left off, if the button is being tapped again.
I know there are a few functions in the AVFoundation Reference but I am unable to implement them correctly.
Does anyone know how to do this in Swift?
import UIKit
import AVFoundation
@IBOutlet var generatedText: UILabel!
@IBAction func buttonSpeakClicked(sender: UIButton){
var mySpeechSynthesizer:AVSpeechSynthesizer = AVSpeechSynthesizer()
var mySpeechUtterance:AVSpeechUtterance = AVSpeechUtterance(string:generatedText.text)
mySpeechUtterance.rate = 0.075
mySpeechSynthesizer .speakUtterance(mySpeechUtterance)
}
Upvotes: 12
Views: 6824
Reputation: 836
Here how you can achieve this
First create a class variable of AVSpeechSynthesizer and initialize it
let synth = AVSpeechSynthesizer()
This is the button click method ( for playing the audio, or pausing it if it is already playing
@IBAction func onAVButtonClicked(_ sender: Any) {
if synth.isSpeaking {
// when synth is already speaking or is in paused state
if synth.isPaused {
synth.continueSpeaking()
}else {
synth.pauseSpeaking(at: AVSpeechBoundary.immediate)
}
}else{
// when synth is not started yet
let string = attrStr.string
let utterance = AVSpeechUtterance(string: string)
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
synth.speak(utterance)
}
}
Upvotes: 2
Reputation: 2365
In Main.storyboard
, make two UIElements
:
UITextView
from which the text will be read.UIButton
to play, pause, and resume reading the text.Create an outlet
from the UITextView
to the @IBOutlet
and an action
from the UIButton
to the @IBAction
in the code below. The following code is a working example, and should be your ViewController.swift
:
import UIKit
import AVFoundation
class ViewController: UIViewController {
// Synth object
let synth = AVSpeechSynthesizer()
// Utterance object
var theUtterance = AVSpeechUtterance(string: "")
// Text element that the synth will read from.
@IBOutlet weak var textView: UITextView!
// Function that starts reading, pauses reading, and resumes
// reading when the UIButton is pressed.
@IBAction func textToSpeech(_ sender: UIButton) {
// The resume functionality
if (synth.isPaused) {
synth.continueSpeaking();
}
// The pause functionality
else if (synth.isSpeaking) {
synth.pauseSpeaking(at: AVSpeechBoundary.immediate)
}
// The start functionality
else if (!synth.isSpeaking) {
// Getting text to read from the UITextView (textView).
theUtterance = AVSpeechUtterance(string: textView.text)
theUtterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
theUtterance.rate = 0.5
synth.speak(theUtterance)
}
}
// Standard function
override func viewDidLoad() {
super.viewDidLoad()
}
// Standard function
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Upvotes: 4
Reputation: 857
AVSpeechSynthesizer Class Reference
Have you tried these methods?
- pauseSpeakingAtBoundary:
and - continueSpeaking
And these are some properties, (paused
and speaking
) that can help you determine the state of the synthesizer.
Code like this should work: mySpeechSynthesizer.pauseSpeakingAtBoundary(AVSpeechBoundary.Immediate)
Upvotes: 8