Reputation: 854
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
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
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
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