Bick
Bick

Reputation: 763

How to display song currenttime and duration by using AVAudioPlayerNode

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.

Upvotes: 6

Views: 8990

Answers (6)

dengApro
dengApro

Reputation: 4008

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

Upvotes: 9

Brian Becker
Brian Becker

Reputation: 41

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

Upvotes: 0

Kegham K.
Kegham K.

Reputation: 1614

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
       }

}

Upvotes: 5

Tomte
Tomte

Reputation: 1339

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!

Upvotes: 8

Thorsten Karrer
Thorsten Karrer

Reputation: 1365

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.

Upvotes: 14

Bick
Bick

Reputation: 763

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.

Upvotes: 3

Related Questions