I have multiple audio files that I want to play continuously and be able to control it with UISlider
. I was using AVAudioPlayer
but there was problem with gaps between each tracks. So I found AVQueuePlayer
and now there are no gaps. But now I have problem with set AVQueuePlayer
to right asset and time to play when UISlider
value changed.
I have different duration of each tracks and I want to slider have same slice for each track so I get maximum duration of biggest track and then get acceleration for each track. Here is how I update slider when AVQueuePlayer is playing:
func updateSliderProgress() {
var value: Float = 0
if let track = tracks[self.playingIndex] {
value = Float(self.playingIndex) * self.maximumDuration + Float(CMTimeGetSeconds(audioQueuePlayer.currentTime())) * track.acceleration
}
playerSlider.setValue(value, animated: false)
}
And here is notification when AVPlayerItem did end:
func playerItemDidReachEnd(sender: AnyObject) {
self.playingIndex++
...
}
It's working and UISlider is correctly progressing. But I have problem with other way:
@IBAction func playerSliderValueChanged(sender: AnyObject) {
let seconds = Double(self.getSeekTime(self.playerSlider.value))
audioQueuePlayer.seekToTime(CMTimeMakeWithSeconds(seconds, 1000))
}
Function seekToTime
is inherit from AVPlayer
and it sets time just for current track, right? So is it possible to change current AVPlayerItem
(by index or something like that) and then apply time in that item? I found just method advanceToNextItem
but I was hoping in more functions with changing current item.
So for now only solution which comes to my mind is that each time user uses slider I create new AVQueuePlayer
use advanceToNextItem
to set right track and then use seekToTime
to get to correct time. Is there better solution?