我正在尝试构建一个在不同时间播放多个音频(wav)文件的应用程序。这些 wav 文件可能具有不同的长度以及开始和结束时间。我想在音频播放时获取播放时间进度。
从我见过的所有不同的教程和指南来看,当您只播放一个音频文件时,这是非常简单的,因为您可以从该 AVAudioPlayerNode 获取
,但在我的实例中,我需要能够支持 1+ 个剪辑在不同(最有可能是并发)时间开始和结束,因此我无法使用一个 lastRenderTime
AVAudioPlayerNode
来获取 lastRenderTime
,因此我需要从不同的 AVAudioNode
(例如引擎的默认输出节点)获取 lastRenderTime
。
我已尝试这样做,但 outputNode
的 lastRenderTime
中没有明确的 0
时间。
我还尝试在播放之前将类/实例变量设置为 engine.outputNode.lastRenderTime
,然后使用它作为一种 anchor 来确定某些内容已经播放了多长时间,但是outputNode
的 lastRenderTime
中没有明确的 0
时间,因此这似乎有些不准确。
var engine = AVAudioEngine()
var mixer = AVAudioMixerNode()
var playerNodes = [AVAudioPlayerNode]()
func prepare() {
engine.attach(mixer)
engine.connect(mixer, to: engine.outputNode, format: nil)
// Create playernode and add to playerNodes
for node in playerNodes {
engine.attach(node)
engine.connect(node, to: mixer, format: nil)
}
try! engine.start()
}
func play() {
for node in playerNodes {
// schedule file/segment/buffer
node.play(at: startTimeForNode)
}
}
如果我有 3 个两秒音频文件,它们在前一个音频文件后一秒开始(并且彼此一起播放),当我按下播放时,我会期望整体播放的样本或毫秒准确时间,而不是每个音频的播放时间文件。我不确定在哪里获取 lastRenderTime
或如何使用 AVAudioTime
以便在所有剪辑播放时获得实时播放时间,但是并非专门针对每个剪辑。
最佳答案
您尝试过使用计时器吗?例如(使用您的节点):
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {[unowned self] timer in
for node in playerNodes {
let nodeTime = node.lastRenderTime!
let playerTime = node.playerTime(forNodeTime: nodeTime)!
let secs = Double(playerTime.sampleTime) / playerTime.sampleRate
print(secs)
}
这是有效的解决方案:https://gist.github.com/standinga/f79232adb15e1f867ad1637f47c61003
关于ios - 获取多个 AVAudioPlayerNode 的播放进度/时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54312904/