Swift - Have an audio repeat, but it plays in inte

2019-08-29 00:49发布

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

1条回答
男人必须洒脱
2楼-- · 2019-08-29 01:01

Just do it the easy, official way, instead. From the documentation of the numberOfLoops property:

Set any negative integer value to loop the sound indefinitely until you call the stop method.

But your actual problem is almost certainly because you're stopping playback a little early:

The stop method does not reset the value of the currentTime property to 0. In other words, if you call stop during playback and then call play, playback resumes at the point where it left off.

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.)

查看更多
登录 后发表回答