Search code examples
iosswiftavaudioplayer

How to really stop audio from playing in swift


In my app I have a timer. When the user starts the timer it plays a bell audio clip. This audio clip rings (resonates) for a few seconds. The user can restart the timer at any time and when they do, it's supposed to play the bell audio clip again.

What's happening is that if the bell audio is still playing when the restart is tapped it does not play the bell audio again due to this overlap. I thought adding code to .stop() it and then .play() it again would do the trick, but it did not work. Instead it seems like the restart button is acting like a pause/play button, you can hear the bell audio clip resonating when you tap the button.

I think I need some way to "clear out" any playing audio from the AVAudioPlayer() but I can't figure out how to do that (and searching the internet hasn't helped).

Here is my code:

@IBAction func RestartTimerBtn(_ sender: Any) {

        timer.invalidate() // kills the past timer so it can be restarted

        // stop the bell audio so it can be played again (usecase: when restarting right after starting bell)
        if audioPlayer_Bell.isPlaying == true{
            audioPlayer_Bell.stop()
            audioPlayer_Bell.play()
        }else {
            audioPlayer_Bell.play()
        }
    }

Solution

  • From the AVAudioPlayer.stop docs (emphasis mine):

    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.

    Instead, consider leveraging the currentTime property to skip backwards to the beginning of your sound before playing it again:

    @IBAction func RestartTimerBtn(_ sender: Any) {
    
        timer.invalidate() // kills the past timer so it can be restarted
    
        if audioPlayer_Bell.isPlaying == true{
            audioPlayer_Bell.stop()
            audioPlayer_Bell.currentTime = 0
            audioPlayer_Bell.play()
        }else {
            audioPlayer_Bell.play()
        }
    }