Michael Contreras Michael Contreras - 3 months ago 13
Swift Question

Trying to press one button then play audios in sequence or random

I am trying to press one button and the audio file plays one after another.

Here is my code below. I press play button and both sounds play at the same time.
I am trying to press play button and the sound starts and stop then the other sound file starts and stops. One button pressed for 2 sound files to press is my goal. Thank you

I am trying this in a loop but it is not working.

import UIKit
import AVFoundation

class ViewController: UIViewController {

@IBOutlet weak var sliderValue: UISlider!

var player:AVAudioPlayer = AVAudioPlayer()
var player1:AVAudioPlayer = AVAudioPlayer()

@IBAction func play(_ sender: AnyObject) {
player.play()
player1.play()
}

@IBAction func pause(_ sender: AnyObject) {
player.pause()
}
@IBAction func stop(_ sender: AnyObject) {
player.stop()
player.currentTime = 0
}
@IBAction func sliderChanged(_ sender: AnyObject) {
player.volume = sliderValue.value
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let audioPath = Bundle.main.path(forResource: "sound1", ofType: "mp3")!
let audioPath1 = Bundle.main.path(forResource: "sound2", ofType: "mp3")!
do {
try player = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath))
try player1 = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath1))

} catch{
//Process Error here
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Answer

Of course you can't do it in a loop!

The correct way to play a sound file after another is to use the AVAudioPlayerDelegate.

In your view controller, conform to AVAudioPlayerDelegate:

class YourViewController: UIViewController, AVAudioPlayerDelegate {
    // ...
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer,
                         successfully flag: Bool) {

    }
}

As you can see, I added an audioPlayerDidFinishPlaying method to the controller.

So you want to play player first, then player1, right?

In viewDidLoad, add this line:

player.delegate = self

And in the method I just added, write:

player1.play()

And the other IBAction methods should be changed a little:

@IBAction func play(_ sender: AnyObject) {
       player.play()
}

@IBAction func pause(_ sender: AnyObject) {
    if player.isPlaying {
        player.pause()
    } else if player1.isPlaying {
        player1.pause()
    }

}
@IBAction func stop(_ sender: AnyObject) {
    if player.isPlaying {
        player.stop()
    } else if player1.isPlaying {
        player1.stop()
    }
}
@IBAction func sliderChanged(_ sender: AnyObject) {
    player.volume = sliderValue.value 
    player1.volume = sliderValue.value
}
Comments