ios - 获取多个 AVAudioPlayerNodes 的播放进度/时间
问题描述
我正在尝试构建一个在不同时间播放多个音频(wav)文件的应用程序。这些 wav 文件可能都有不同的长度以及开始和结束时间。我想在音频播放时获得播放时间进度。
从我见过的所有不同的教程和指南中,当你只播放一个音频文件时,这非常简单,因为你可以从中得到lastRenderTime
,AVAudioPlayerNode
但在我的例子中,我需要能够支持 1+剪辑在不同的(很可能是同时的)时间开始和结束,所以我不能用一个AVAudioPlayerNode
来获取lastRenderTime
from,所以我需要lastRenderTime
从不同AVAudioNode
的地方获取,比如引擎的默认输出节点。
我试过这样做,但's中没有明确0
的时间。outputNode
lastRenderTime
我还尝试engine.outputNode.lastRenderTime
在播放之前将类/实例变量设置为正确,然后将其用作一种锚点来确定播放了多长时间,但's中没有明确0
的时间,所以这似乎有点不准确。outputNode
lastRenderTime
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
推荐阅读
- jquery - 像画布中的垂直弧线一样的文本
- java - 如何在 Spring Security 中通过电子邮件而不是用户名登录
- javascript - 如何在产品列表仍在 prestashop 中加载时显示加载图像
- mysql - 在所有列mysql上添加唯一约束的成本是多少
- python - 在数据框条目中搜索字符串并将其复制 python
- asp.net - 如何使用 LINQ 从 Datatable 中获取过滤后的数据集
- ms-access - 使用 Select Distinct 并编辑第二列中的输出
- c# - 类库自动添加到 Visual Studio 7.5.2 mac os X 中的其他项目
- html - google siganute 使一张图片有两个链接
- selenium - 无法识别元素