In Swift, I play a song, it plays at the viewDidLoad. It is 16 seconds long, and it plays all 16 seconds. I want it to repeat forever. I made an NSTimer
where every 16 seconds, it plays the song. But, it plays 16 seconds when the app loads, stops for 16 seconds, plays, etc.
The line println("just doing some dandy debugging here.")
does print every 16 seconds.
How is this fixed?
CODE:
//these var's are created on the top of the file.
var soundTimer: NSTimer = NSTimer()
var audioPlayer2 = AVAudioPlayer()
var soundTwo = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("sound", ofType: "wav"))
//this stuff is in the viewDidLoad function.
audioPlayer2 = AVAudioPlayer(contentsOfURL: soundTwo, error: nil)
audioPlayer2.prepareToPlay()
audioPlayer2.play()
soundTimer = NSTimer.scheduledTimerWithTimeInterval(16, target: self, selector: Selector("soundTimerPlayed"), userInfo: nil, repeats: true)
func soundTimerPlayed() {
println("just doing some dandy debugging here.")
audioPlayer2.stop()
audioPlayer2.prepareToPlay()
audioPlayer2.play()
}
Just do it the easy, official way, instead. From the documentation of the
numberOfLoops
property:But your actual problem is almost certainly because you're stopping playback a little early:
What's happening is that you're stopping the sound playback just a little before the actual end of the sample—your timer is set to just too short a time. The first time the timer is triggered, the "play" is playing the tiny amount of quiet or silent sound that's left at the end, and then stopping. The next time, the currentTime has been reset because the sample has successfully reached the end of playback, so on the next timer interval, after another 16 seconds, playback starts successfully from the beginning. And repeat.
As Jack observes in his comment, this is why there's a delegate callback to give you a kick when the playback has actually finished, but I'd still just set numberOfLoops and not bother with the complicated stuff, if you only need the sound to loop indefinitely.
(If you desperately want to repeat on your exact timer event, then just set currentTime to 0 before you play it again.)