AlexWoe
AlexWoe

Reputation: 854

AVAudioEngine & AVAudioPlayerNode didFinish method like AVAudioPlayer

Is there any possibility to identify if the AVAudioEngine did finish its played sound? In the past I used the AVAudioPlayer's function:

func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {
    // Code after finished the played sound
}

Now I need some effects, but there is no func of AVAudioEnginge provided that identifies the end of the played sound.

I searched a lot, but unfortunately I found only this func in the documentation of AVAudioEngine:

var running: Bool { get }

My current solution will be to check the "running" boolean, if it's false the player is not playing anymore. Does somebody know a better solution for AVAudioEngine? Thank you very much!

Upvotes: 4

Views: 3247

Answers (3)

hotdogsoup.nl
hotdogsoup.nl

Reputation: 2321

The accepted answer seems to call the completionHandler as soon as SCHEDULING is finished, not as soon as playing the audio file is finished.

As per iOS 11.0+ / macOS 10.13+ use:

self.player.scheduleBuffer(buffer, completionCallbackType: .dataPlayedBack completionHandler: {
    print("Complete")
})

Upvotes: 1

user4812000
user4812000

Reputation: 1053

I attach an AVAudioPlayerNode to my engine

player = AVAudioPlayerNode()

    let file = try! AVAudioFile(forReading: url)
    let buffer = AVAudioPCMBuffer(PCMFormat: file.processingFormat, frameCapacity: AVAudioFrameCount(file.length))

    do {
        print("read")
        try file.readIntoBuffer(buffer)
    } catch _ {
    }

engine.attachNode(player)
engine.connect(player, to: engine.mainMixerNode, format: nil)

self.player.scheduleBuffer(buffer, completionHandler: {
    print("Complete")
})

        engine.prepare()
    do {
        try engine.start()
    } catch _ {
        print("Play session Error")
    }

    player.play()

I hope that helps!

Upvotes: 3

Saerdn
Saerdn

Reputation: 228

I also used a NSTimer as I haven't found any other solution/delegate. But it's fired only once and starts right after the audiofile ends (that means, the very first parameter "seconds" has the value of the duration of the audiofile). The selector is my "custom delegate" function.

Upvotes: 2

Related Questions