Fredo
Fredo

Reputation: 173

AVAudioPlayer using array to queue audio files - Swift

I am looking for a way to simply play audio files one after another. AVAudioPlayer using an array seems to be the best solution. In fact, I was able to play the first element of the array using Sneak's recommendations found on this page : Here.

But I don't understand where and how to write the second call to AVAudioPlayer in order to play the second file?

The "audioPlayerDidFinishPlaying" function is not reacting. Why?

Thanks for watching.

import Cocoa
import AVFoundation

var action = AVAudioPlayer()
let path = Bundle.main.path(forResource: "test.aif", ofType:nil)!
let url = URL(fileURLWithPath: path)
let path2 = Bundle.main.path(forResource: "test2.aif", ofType:nil)!
let url2 = URL(fileURLWithPath: path2)
let array1 = NSMutableArray(array: [url, url2])

class ViewController: NSViewController
{
    @IBOutlet weak var LanceStop: NSButton!

    override func viewDidLoad()
    {
        super.viewDidLoad()

        do
        {
            action = try AVAudioPlayer(contentsOf: array1[0] as! URL)
            action.numberOfLoops = 0
            action.prepareToPlay()
            action.volume = 1
        }catch{print("error")}
    }
...
@IBAction func Lancer(_ sender: NSButton)
    {
        if action.isPlaying == true
        {
            action.stop()
            action.currentTime = 0.0
            LanceStop.title = "Lancer"
        }
        else
        {
            action.play()
            LanceStop.title = "Stopper"
        }
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
    {
        if flag == true
        {
            LanceStop.title = "Lancer"
        }
    }
}

Upvotes: 1

Views: 3112

Answers (2)

Fredo
Fredo

Reputation: 173

Changed Code...

class ViewController: NSViewController, AVAudioPlayerDelegate
{

    @IBOutlet weak var LanceStop: NSButton!

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }
    override var representedObject: Any?
    {
        didSet
        {
        // Update the view, if already loaded.
        }
    }

    func playAudioFile(_ index: Int)
    {
        do
        {
            action = try AVAudioPlayer(contentsOf: array1[index] as! URL)
            action.delegate = self
            action.numberOfLoops = 0
            action.prepareToPlay()
            action.volume = 1
            action.play()
        }
        catch{print("error")}
    }

    @IBAction func Lancer(_ sender: NSButton)
    {
      playAudioFile(0)
    }


    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
    {
        if flag == true
        {
            playAudioFile(1)
        }
    }

}

Upvotes: 0

Hussain Shabbir
Hussain Shabbir

Reputation: 14995

But I don't understand where and how to write the second call to
AVAudioPlayer in order to play the second file?

So in order to play the second file, you need to write one method where you will need to initialize the audioplayer and invoke the same method inside audioplayer delegate method audioPlayerDidFinishPlaying like this:-

func playAudioFile(_ index: Int) {
  do
{
  action = try AVAudioPlayer(contentsOf: array1[index] as! URL)
  action.numberOfLoops = 0
  action.prepareToPlay()
  action.volume = 1
 } catch{print("error")
}

 func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
     //This delegate method will called once it finished playing audio file.
    //Here you can invoke your second file. You can declare counter variable 
   //and increment it based on your file and stop playing your file acordingly.
  counter = counter + 1
  playAudioFile(counter)
}

Note:- Set Audioplayer delegate to your ViewController in order to get invoke audioPlayerDidFinishPlaying method like this.

action.delegate = self

Upvotes: 1

Related Questions