1

I'm using an AVAudioPlayerNode attached to an AVAudioEngine to play a sound.

to get the current time of the player I'm doing this:

extension AVAudioPlayerNode {
var currentTime: TimeInterval {
    get {
        if let nodeTime: AVAudioTime = self.lastRenderTime, let playerTime: AVAudioTime = self.playerTime(forNodeTime: nodeTime) {
            return Double(playerTime.sampleTime) / playerTime.sampleRate
        }
        return 0
    }
 }

}

I have a slider that indicates the current time of the audio. When the user changes the slider value, on .ended event I have to change the current time of the player to that indicated in the slider. To do so:

extension AVAudioPlayerNode {

func seekTo(value: Float, audioFile: AVAudioFile, duration: Float) {
    if let nodetime = self.lastRenderTime{
        let playerTime: AVAudioTime = self.playerTime(forNodeTime: nodetime)!
        let sampleRate = self.outputFormat(forBus: 0).sampleRate
        let newsampletime = AVAudioFramePosition(Int(sampleRate * Double(value)))
        let length = duration - value
        let framestoplay = AVAudioFrameCount(Float(playerTime.sampleRate) * length)
        self.stop()

        if framestoplay > 1000 {
            self.scheduleSegment(audioFile, startingFrame: newsampletime, frameCount: framestoplay, at: nil,completionHandler: nil)
        }
    }
    self.play()
}

However, my function seekTo is not working correctly(I'm printing currentTime before and after the function and it shows always a negative value ~= -0.02). What is the wrong thing I'm doing and can I find a simpler way to change the currentTime of the player?

mahdi
  • 149
  • 12
  • you can use it in simple way by use slider and define a timer and if you want handle tap and drag seek its better define tap gesture and use slider action. – Masoud Roosta May 29 '19 at 08:58
  • Thanks for your try @masoud but you did not answer my question. What u said is already implemented. But what I want is, after changing the slider value, how can i change the current time of the player. – mahdi May 29 '19 at 09:02
  • Any solution how to change current time ??? – Sham Dhiman Jul 05 '19 at 07:14
  • @ShamDass not ye, if u found anything please answer this question – mahdi Jul 05 '19 at 07:17

1 Answers1

0

I ran into same issue. Apparently the framestoplay was always 0, which happened because of sampleRate. The value for playerTime.sampleRate was always 0 in my case.

So,

let framestoplay = AVAudioFrameCount(Float(playerTime.sampleRate) * length)

must be replaced with

let framestoplay = AVAudioFrameCount(Float(sampleRate) * length)
Nina
  • 1,579
  • 2
  • 21
  • 51
  • Could you please take a look at this question https://stackoverflow.com/q/69632925/5709159 – Sirop4ik Oct 20 '21 at 10:55
  • @AlekseyTimoshchenko Sorry, I have not encountered such issue before. Maybe if you link a sample working project to your question, you may receive more response. – Nina Oct 20 '21 at 11:13