ben*_*ish 4 text-to-speech delay ios swift
我正在尝试让iOS文本语音合成器“说”短语列表,这些短语之间存在可变的延迟。例如,我可能要说“你好”,然后等待5秒钟,然后“有人在吗?”,然后等待10秒钟,然后说“你好?” ...等等。
我在下面做了一个简单的例子,说明了我要做什么。我知道语音合成器正在讲话,其他语音被添加到队列中并按照接收顺序进行讲话。
我尝试了许多方法来实现循环中的此延迟。使用打印语句测试延迟可以确认它们是否有效,但是它们似乎干扰了text-speach-function功能,该功能说的是第一个短语,但要等到for循环完成后再说其余的内容。我认为这些类型的任何延迟都可以工作,因为我假设语音合成器是事件驱动的。
我希望能提供一些帮助,或者至少能对它为什么无法工作有所了解。谢谢!
这是示例代码:iPhone 6模拟器,Xcode 7.3
import UIKit
import AVFoundation
class ViewController: UIViewController {
let speechSynthesizer = AVSpeechSynthesizer()
var phraseArray: [String] = ["One", "Two", "Three", "Four", "Five", "Six", "Seven"]
override func viewDidLoad() {
super.viewDidLoad()
for phrase in phraseArray{
let speechUtterance = AVSpeechUtterance(string: phrase)
speechSynthesizer.speakUtterance(speechUtterance)
//"delay()" goes here. It needs to be a variable length delay.
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试过的一些延迟方法:
将类设置为语音合成器的委托,并运行while循环,直到合成器完成。
基于时间的延迟: referenceDate = NSDate() while(NSDate().timeIntervalSinceDate(referenceDate) < 0.5) {}
我已经尝试过从堆栈中“延迟”解决方案,就像这样: 循环中的快速延迟
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
睡觉()
这样的事情怎么样:
import UIKit
import AVFoundation
func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
class ViewController: UIViewController {
let speechSynthesizer = AVSpeechSynthesizer()
override func viewDidLoad() {
super.viewDidLoad()
speak([("Hello", 5.0), ("Is there anyone there?", 10.0), ("Hello?", 0.0)])
}
func speak(_ phrases: [(phrase: String, wait: Double)]) {
if let (phrase, wait) = phrases.first {
let speechUtterance = AVSpeechUtterance(string: phrase)
speechSynthesizer.speak(speechUtterance)
let rest = Array(phrases.dropFirst())
if !rest.isEmpty {
delay(wait) {
self.speak(rest)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
笔记:
speak。一个元组对包含一个要说的短语和一个等待说下一个短语的延迟。speakspeak在等待延迟之后,从数组中获取第一项,说出短语,然后将数组的其余部分(如果不为空)传递给其他人。delay是@matt编写的,来自这里。由于最后一个延迟没有任何用处,因此您可以将其转过来,并在延迟后说出第一个短语。
func speak(_ phrases: [(wait: Double, phrase: String)]) {
if let (wait, phrase) = phrases.first {
delay(wait) {
let speechUtterance = AVSpeechUtterance(string: phrase)
self.speechSynthesizer.speak(speechUtterance)
let rest = Array(phrases.dropFirst())
if !rest.isEmpty {
self.speak(rest)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以这样使用:
// Wait 5 seconds before starting...
speak([(5.0, "I'm sorry Dave."), (2.0, "I can't do that.")])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1360 次 |
| 最近记录: |