我正在尝试显示语音的字幕以及播放的音频。虽然我设法做到了这一点,但我觉得这不是应该做的事情,这就是为什么我不得不寻求帮助,因为我没有在互联网上找到任何类似的问题
基本上,我想在非常特定的时刻显示17个句子,这就是为什么我使用延迟创建循环,这在本文下面给出。这些句子只是放置在我的View Controller底部的标签( @IBOutlet weak var introDisplay:UILabel!),每次延迟都会更改文本。我真的没有更好的想法,除了 currentTime 之外我还没有找到任何具体的AVFoundation功能,但是当我尝试使用它时它似乎没有任何效果。我创建的是:
for i in 1...17
{
switch i
{
case 1:
displaySentence.text = "SENTENCE 1"
case 2:
DispatchQueue.main.asyncAfter(deadline: .now() + 3.48)
{
self.introDisplay.text = "SENTENCE 2"
}
case 3:
DispatchQueue.main.asyncAfter(deadline: .now() + 5.00)
{
self.introDisplay.text = "SENTENCE 3"
}
case 4:
DispatchQueue.main.asyncAfter(deadline: .now() + 7.00)
{
self.introDisplay.text = "SENTENCE 4"
}
//... and so on up to 17th case and default
现在,问题是字幕工作一直很好,直到字幕开始显示失败的最后。应该在特定时间显示一个句子而不是该特定句子,此时显示下一个句子(即使下一个句子设置了不同的延迟时间)。当我尝试对这些延迟进行更改时,无论是后期还是更早,都没有效果......
我希望你能理解上面的所有内容并且它不是完全的傻瓜
答案 0 :(得分:0)
@ aleksy-
我认为您在指定间隔后呈现不同文本的方法很复杂。您目前正在紧密循环中执行 DispatchQueue.main.asyncAfter 。操作系统将优化这种上下文切换,因此会导致丢弃一些文本呈现。
如果只是在一定间隔后呈现不同文本的问题,请尝试以下方法。在这里,我只是用1/60(通常被认为是一个很好的FPS渲染)间隔来触发重复计时器。根据经过的时间间隔,应选择相关文本进行渲染。完成后,请确保停止计时器。
func stopRendering()->Void
{
self.renderingTimer?.invalidate()
}
func startRenderingEngine()->Void
{
let timerStartDate = Date.init(timeIntervalSinceNow:0)
self.renderingTimer = Timer.scheduledTimer(withTimeInterval: 1/60.0, repeats: true) { (timer) in
let elapsedTime:Int = Int(abs(timerStartDate.timeIntervalSinceNow))
switch elapsedTime
{
case 1:
self.introDisplay.text = "SENTENCE 1"
case 3:
self.introDisplay.text = "SENTENCE 2"
case 5:
self.introDisplay.text = "SENTENCE 3"
case 8:
self.introDisplay.text = "SENTENCE 4"
case 12:
self.introDisplay.text = "SENTENCE 4"
case 15:
self.introDisplay.text = "SENTENCE 5"
default:
if(elapsedTime>16)
{
self.introDisplay.text = "Finished rendering !"
self.stopRendering()
}
}
}
}
注意:这里避免了上下文切换,因为在主线程中触发了计时器。