Bram Grooten
Bram Grooten

Reputation: 53

How do I continuously check if AVAudioplayer is done playing in Swift?

I made a simple app that plays audio. Now I want to automatically change the "Pause" button to "Play" when the audio is done playing. How do I check for this? Here is the code:

import UIKit
import AVFoundation

class ViewController: UIViewController {
@IBOutlet weak var PausePlay: UIButton!
var BackgroundAudio = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("M.I.A.-DoubleBubbleTrouble", ofType: "mp3")!), error: nil)

override func viewDidLoad() {
    super.viewDidLoad()        
    BackgroundAudio.play()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

@IBAction func Stop(sender: AnyObject) {
    if(BackgroundAudio.playing) {
    BackgroundAudio.stop()
    BackgroundAudio.currentTime = 0
    PausePlay.setTitle("Play", forState: .Normal)
    } else {
        BackgroundAudio.currentTime = 0
    }
}

@IBAction func Restart(sender: AnyObject) {
    if(BackgroundAudio.playing==false){
        PausePlay.setTitle("Pause", forState: .Normal)
    }
    BackgroundAudio.stop()
    BackgroundAudio.currentTime = 0
    BackgroundAudio.play()
}

@IBAction func PausePlay(sender: AnyObject) {
    if(BackgroundAudio.playing){
        BackgroundAudio.stop()
        PausePlay.setTitle("Play", forState: UIControlState.Normal)
    } else {
        BackgroundAudio.play()
        PausePlay.setTitle("Pause", forState: .Normal)
    }
}

if (BackgroundAudio.playing == false) {
PausePlay.setTitle("Play", forState: .Normal)
}   
}

That last if-statement should be inside a function, but then how do I (continuously) call that function?

Upvotes: 2

Views: 3861

Answers (2)

MartianMartian
MartianMartian

Reputation: 1849

so many duplicated questions...here's my duplicated answer:

import UIKit
import AVFoundation
import MediaPlayer


class ViewController: UIViewController,AVAudioPlayerDelegate {

    var player: AVAudioPlayer = AVAudioPlayer()

    @IBAction func play(_ sender: UIButton) {
        player.play()
        player.currentTime=14*60-10
        print(player.currentTime)
    }
    @IBAction func pause(_ sender: UIButton) {
        player.pause()
    }
    @IBAction func replay(_ sender: UIButton) {
        player.currentTime=0
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        do{
            let audioPath = Bundle.main.path(forResource: "elon", ofType: "mp3")
            player = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: audioPath!))
            player.prepareToPlay()
            player.delegate = self
        }
        catch{
            print(error)
        }
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool){
        print(flag)
        print("here")
        if flag == true{

        }
    }


}

Upvotes: 1

Chris Slowik
Chris Slowik

Reputation: 2879

You don't have to continually check - you should instead implement the AVAudioPlayerDelegate protocol in your View Controller: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioPlayerDelegateProtocolReference/index.html#//apple_ref/occ/intfm/AVAudioPlayerDelegate/audioPlayerDidFinishPlaying:successfully:

See: audioPlayerDidFinishPlaying:successfully:. I think you'll find it does exactly the opposite of what you want to do, which is actually the correct way. This way, your player will simply call the "end" function that you define.

Upvotes: 5

Related Questions