实时更改 AVSpeechUtterance 速率
Change AVSpeechUtterance rate in real time
我目前正在开发一个 iOS 应用程序,它使用 AVSynthesizer 将文本转换为语音。
我想做的是,当合成器说话时,可以改变语速,用滑块改变说话的速度。
我在滑块的 IBAction 中这样做:
self.utterance = sender.value
但是合成器不会改变速度。我一直在寻找信息,但我还没有找到任何东西。
我能做什么?提前致谢。
好的,在试用了这个我不知道的很酷的功能之后,我找到了一种改变语速的方法。主要问题是语音当前已由合成器排队,rate
无法更改。对应文档:
/* Setting these values after a speech utterance has been enqueued will have no effect. */
open var rate: Float // Values are pinned between AVSpeechUtteranceMinimumSpeechRate and AVSpeechUtteranceMaximumSpeechRate.
open var pitchMultiplier: Float // [0.5 - 2] Default = 1
open var volume: Float // [0-1] Default = 1
因此解决方法是停止合成器并为其提供经过修剪的字符串的新话语。
import UIKit
import AVFoundation
class ViewController: UIViewController {
var synthesizer: AVSpeechSynthesizer!
var string: String!
var currentRange: NSRange = NSRange(location: 0, length: 0)
@IBAction func sl(_ sender: UISlider) {
synthesizer.stopSpeaking(at: .immediate)
if currentRange.length > 0 {
let startIndex = string.index(string.startIndex, offsetBy: NSMaxRange(currentRange))
let newString = string.substring(from: startIndex)
string = newString
synthesizer.speak(buildUtterance(for: sender.value, with: string))
}
}
func buildUtterance(for rate: Float, with str: String) -> AVSpeechUtterance {
let utterance = AVSpeechUtterance(string: str)
utterance.rate = rate
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
return utterance
}
override func viewDidLoad() {
super.viewDidLoad()
string = "I am currently developing an iOS app that converts text to speech using AVSynthesizer.What I want to do is that while the synthesizer is speaking, utterance rate can be changed and with a slider and the speed of the speaking changes. I am doing this in the IBAction of the slider: self.utterance = sender.value but the synthesizer doesn't change the speed. Ive been looking for information but I haven't found something yet. What can I do? Thanks in advance."
synthesizer = AVSpeechSynthesizer()
synthesizer.delegate = self
synthesizer.speak(buildUtterance(for: AVSpeechUtteranceDefaultSpeechRate, with: string))
}
}
extension ViewController: AVSpeechSynthesizerDelegate {
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
debugPrint(characterRange.toRange())
currentRange = characterRange
}
}
实现AVSpeechSynthesizerDelegate
的delegate方法willSpeakRangeOfSpeechString
,定义synthesizer的delegate为self:synthesizer.delegate = self
在该委托方法中,保存接下来要说的字符范围。
将 IBAction func sl(_ sender: UISlider)
绑定到滑块的事件 touchUpInside。
在那个 IBAction 中,停止说话,并从它会继续的索引中获取当前正在说话的文本的子字符串。
建立新的话语并开始说出来
利润。
swift 3
import UIKit
import AVFoundation
class ViewController: UIViewController{
@IBOutlet weak var sliderVolume: UISlider! //for volume
@IBOutlet weak var sliderRate: UISlider! //for rate
@IBOutlet weak var sliderPitch: UISlider! //for pitch
@IBOutlet weak var txtForSpeak: UITextField!
let speechSynth = AVSpeechSynthesizer()
@IBAction func btnStartToSpeak(_ sender: UIButton) {
let speechUtt = AVSpeechUtterance(string: self.txtForSpeak.text!)
speechUtt.rate = self.sliderRate.value
speechUtt.volume = self.sliderVolume.value
speechUtt.pitchMultiplier = self.sliderPitch.value
self.speechSynth.speak(speechUtt)
}
}
我目前正在开发一个 iOS 应用程序,它使用 AVSynthesizer 将文本转换为语音。
我想做的是,当合成器说话时,可以改变语速,用滑块改变说话的速度。
我在滑块的 IBAction 中这样做: self.utterance = sender.value
但是合成器不会改变速度。我一直在寻找信息,但我还没有找到任何东西。 我能做什么?提前致谢。
好的,在试用了这个我不知道的很酷的功能之后,我找到了一种改变语速的方法。主要问题是语音当前已由合成器排队,rate
无法更改。对应文档:
/* Setting these values after a speech utterance has been enqueued will have no effect. */
open var rate: Float // Values are pinned between AVSpeechUtteranceMinimumSpeechRate and AVSpeechUtteranceMaximumSpeechRate.
open var pitchMultiplier: Float // [0.5 - 2] Default = 1
open var volume: Float // [0-1] Default = 1
因此解决方法是停止合成器并为其提供经过修剪的字符串的新话语。
import UIKit
import AVFoundation
class ViewController: UIViewController {
var synthesizer: AVSpeechSynthesizer!
var string: String!
var currentRange: NSRange = NSRange(location: 0, length: 0)
@IBAction func sl(_ sender: UISlider) {
synthesizer.stopSpeaking(at: .immediate)
if currentRange.length > 0 {
let startIndex = string.index(string.startIndex, offsetBy: NSMaxRange(currentRange))
let newString = string.substring(from: startIndex)
string = newString
synthesizer.speak(buildUtterance(for: sender.value, with: string))
}
}
func buildUtterance(for rate: Float, with str: String) -> AVSpeechUtterance {
let utterance = AVSpeechUtterance(string: str)
utterance.rate = rate
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
return utterance
}
override func viewDidLoad() {
super.viewDidLoad()
string = "I am currently developing an iOS app that converts text to speech using AVSynthesizer.What I want to do is that while the synthesizer is speaking, utterance rate can be changed and with a slider and the speed of the speaking changes. I am doing this in the IBAction of the slider: self.utterance = sender.value but the synthesizer doesn't change the speed. Ive been looking for information but I haven't found something yet. What can I do? Thanks in advance."
synthesizer = AVSpeechSynthesizer()
synthesizer.delegate = self
synthesizer.speak(buildUtterance(for: AVSpeechUtteranceDefaultSpeechRate, with: string))
}
}
extension ViewController: AVSpeechSynthesizerDelegate {
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
debugPrint(characterRange.toRange())
currentRange = characterRange
}
}
实现
AVSpeechSynthesizerDelegate
的delegate方法willSpeakRangeOfSpeechString
,定义synthesizer的delegate为self:synthesizer.delegate = self
在该委托方法中,保存接下来要说的字符范围。
将
IBAction func sl(_ sender: UISlider)
绑定到滑块的事件 touchUpInside。在那个 IBAction 中,停止说话,并从它会继续的索引中获取当前正在说话的文本的子字符串。
建立新的话语并开始说出来
利润。
swift 3
import UIKit
import AVFoundation
class ViewController: UIViewController{
@IBOutlet weak var sliderVolume: UISlider! //for volume
@IBOutlet weak var sliderRate: UISlider! //for rate
@IBOutlet weak var sliderPitch: UISlider! //for pitch
@IBOutlet weak var txtForSpeak: UITextField!
let speechSynth = AVSpeechSynthesizer()
@IBAction func btnStartToSpeak(_ sender: UIButton) {
let speechUtt = AVSpeechUtterance(string: self.txtForSpeak.text!)
speechUtt.rate = self.sliderRate.value
speechUtt.volume = self.sliderVolume.value
speechUtt.pitchMultiplier = self.sliderPitch.value
self.speechSynth.speak(speechUtt)
}
}