AVAudioEngine 寻找歌曲的时间

8

我正在使用AVAudioPlayerNode播放一首歌曲,并尝试使用UISlider控制其时间,但我无法弄清楚如何使用AVAUdioEngine寻找时间。


1
我已经等了几个月的答案,一直在拖延。我知道它涉及到获取播放器节点的lastRenderTime,并从中减去或加上时间。不过让它从那个时间开始播放是比较困难的。 - Paul Lehn
2个回答

19

经过许多尝试和错误,我认为我终于弄清楚了。

首先,您需要计算文件的采样率。为此,请获取AudioNode的最后渲染时间:

var nodetime: AVAudioTime  = self.playerNode.lastRenderTime
var playerTime: AVAudioTime = self.playerNode.playerTimeForNodeTime(nodetime)
var sampleRate = playerTime.sampleRate

然后,将您的采样率乘以新时间(以秒为单位)。这将为您提供您想要启动播放器的歌曲的确切帧:

var newsampletime = AVAudioFramePosition(sampleRate * Double(Slider.value))

接下来,您需要计算音频文件中剩余的帧数:

var length = Float(songDuration!) - Slider.value
var framestoplay = AVAudioFrameCount(Float(playerTime.sampleRate) * length)

最后,停止你的节点,安排新的音频片段,然后再次启动你的节点!

playerNode.stop()

if framestoplay > 1000 {
   playerNode.scheduleSegment(audioFile, startingFrame: newsampletime, frameCount: framestoplay, atTime: nil,completionHandler: nil)
}

playerNode.play()
如果您需要更详细的说明,我在这里写了一个简短的教程:http://swiftexplained.com/?p=9

1
非常感谢您的帮助!我终于明白了事情是如何运作的! - luciansvnc
你从哪里获取了songDuration? - Ohmnastrum
1
未来的读者最好从 playerNode.outputFormat(forBus: 0).sampleRate 获取采样率。 - hhanesand
我有一些编码错误,其他逻辑错误导致它没有工作,抱歉 Paul。 - Arpit B Parekh
1
链接已经失效,但您可以在此找到它: https://web.archive.org/web/20150918000438/http://swiftexplained.com/?p=9 然而,在 Paul 的回答中已经包含了其中的所有内容。 - Brett
显示剩余3条评论

3

对于未来的读者,最好获取采样率使用以下代码:

playerNode.outputFormat(forBus: 0).sampleRate

在转换为AVAudioFramePosition时要注意,它是一个整数,而采样率是一个双精度浮点数。如果不对结果进行四舍五入,则可能会得到不良结果。

P.S. 上述答案假设您播放的文件与播放器的输出格式具有相同的采样率,这可能是真实的也可能不是。


我尝试了上面的答案,但它对我不起作用。我在函数之前和之后打印了currentTime,结果显示有问题。能否请您帮忙?这是我的问题 - mahdi
天啊!我已经折腾了这段代码几个小时,但是一直无法让它正常工作。我加入了很多打印语句来确保数字的正确性,结果自己都快疯了!最终我终于让它正常工作了,因为无论你是否有一个正在播放的playerNode,你必须在调用playerNode.scheduleSegment()方法之前调用playerNode.stop()方法,然后它才会播放。我省略了对playerNode.stop()的调用,因为我想在指定时间开始播放音轨。哎呀!这真是我的一场灾难!感谢您提供的代码示例! - SouthernYankee65

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接