6

I'm making an audio player using AVAudioPlayerNode and playing a song with some effect (delay, pitch change, rate change etc) works, but I'm stuck on displaying song current time and duration. AVAudioPlayerNode seems not have like AVAudioPlayer.currentTime or .duration.

I'd really appreciate if you can help me to display currenttime and duration by using AVAudioPlayerNode.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Bick
  • 743
  • 2
  • 8
  • 18

6 Answers6

14

For the current time, this is what I use:

- (NSTimeInterval)currentTimeInSeconds
{
    AVAudioTime *nodeTime = self.playerNode.lastRenderTime;
    AVAudioTime *playerTime = [self.playerNode playerTimeForNodeTime:nodeTime];

    NSTimeInterval seconds = (double)playerTime.sampleTime / playerTime.sampleRate; 
    return seconds;
}

In addition to the render time in an abstract time base, the player node offers conversion of this time into its own playback timeline via playerTimeForNodeTime. Also respects pausing etc.

Thorsten Karrer
  • 1,345
  • 9
  • 19
8

Here it is in swift:

private func currentTime() -> NSTimeInterval {
    if let nodeTime: AVAudioTime = myAvAudioPlayer.lastRenderTime, playerTime: AVAudioTime = myAvAudioPlayer.playerTimeForNodeTime(nodeTime) {
       return Double(Double(playerTime.sampleTime) / playerTime.sampleRate)
    }
    return 0
}

Just replace myAvAudioPlayer with your AVAudioPlayerNode!

Happy coding!

Tomte
  • 1,331
  • 12
  • 19
5

For the duration of the AVAudioPlayerNode SWIFT 4:

func durationOfNodePlayer(_ fileUrl: URL) -> TimeInterval {
    do {

        let file = try AVAudioFile(forReading: fileUrl)
        let audioNodeFileLength = AVAudioFrameCount(file.length)
        return Double(Double(audioNodeFileLength) / 44100) //Divide by the AVSampleRateKey in the recorder settings

       } catch {

          return 0
       }

}
Kegham K.
  • 1,589
  • 22
  • 40
5

Swift 5:

duration time, using AVAudioPlayrtNode's AVAudioFile

extension AVAudioFile{

    var duration: TimeInterval{
        let sampleRateSong = Double(processingFormat.sampleRate)
        let lengthSongSeconds = Double(length) / sampleRateSong
        return lengthSongSeconds
    }

}

according to WWDC 2014: whats new in core audio , mins 54


Then currentTime:

extension AVAudioPlayerNode{

    var current: TimeInterval{
        if let nodeTime = lastRenderTime,let playerTime = playerTime(forNodeTime: nodeTime) {
            return Double(playerTime.sampleTime) / playerTime.sampleRate
        }
        return 0
    }
}

Thanks @Brian Becker

dengApro
  • 3,848
  • 2
  • 27
  • 41
3

For the duration, .length property of AVAudioFile worked. I divided the number of sample frames in the file by the sample rates(44100hz).

For the currenttime, tentatively I use UISlider.value and synthesize the value with the sample frames.

Bick
  • 743
  • 2
  • 8
  • 18
0

Something like this should give you that ability...

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
    }
}