AVAudioEngine seek the time of the song

谁说我不能喝 提交于 2019-12-03 08:44:17

After MUCH trial and error I think I have finally figured this out.

First you need to calculate the sample rate of your file. To do this get the last render time of your AudioNode:

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

Then, multiply your sample rate by the new time in seconds. This will give you the exact frame of the song at which you want to start the player:

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

Next, you are going to want to calculate the amount of frames there are left in the audio file:

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

Finally, stop your node, schedule the new segment of audio, and start your node again!

playerNode.stop()

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

playerNode.play()

If you need further explanation I wrote a short tutorial here: http://swiftexplained.com/?p=9

For future readers, probably better to get the sample rate as :

playerNode.outputFormat(forBus: 0).sampleRate

Also take care when converting to AVAudioFramePosition, as it is an integer, while sample rate is a double. Without rounding the result, you may end up with undesirable results.

P.S. The above answer assumes that the file you are playing has the same sample rate as the output format of the player, which may or may not be true.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!