Search code examples
arraysswiftmacosaudioavaudioplayer

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"
        }
    }
}

Solution

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