Search code examples
swiftswift2avaudioplayer

Swift 2: AVAudioPlayers to play multiple sounds at once


So hey

I've been searching around, trying to find a way to solve this, but there's basically no solutions to this yet.

I desperately need a way to instantiate and play a sound whenever I want, without it cutting out any other sounds. I know that AVAudioPlayer can only play one sound at a time, so I'm trying to figure out how to make a dynamic array of AVAudioPlayers that I can add to any time I need to play a sound. My current code, that I got from a different answer on this site, is this:

func Sound(sound: String) {
    do {
        if let bundle = NSBundle.mainBundle().pathForResource(sound, ofType: "wav") {
            let alertSound = NSURL(fileURLWithPath: bundle)
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
            try AVAudioSession.sharedInstance().setActive(true)
            try audioPlayer = AVAudioPlayer(contentsOfURL: alertSound)
            audioPlayer.prepareToPlay()
            audioPlayer.play()
        }
    } catch {
        print(error)
    }


}

Which, unfortunately, does not work. It plays a sound, but stops any other sound from playing.

I've also tried the code from here, but I'm having the same problem the asker is having, and there's no solution.

Basically, I just need a code snippet that's up to date with Swift 2, that lets me play a sound without it cutting out ANY other sounds that are playing. Even if it's the same sound effect twice.


Solution

  • This question sounds more like you don't quite have a grasp on Swift data structures, but here's a simple snippet to get you on your way:

    import UIKit
    import AVFoundation
    
    class ViewController: UIViewController {
    
        var arrayOfPlayers = [AVAudioPlayer]()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            sound("tester")
            let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC)))
            dispatch_after(delayTime, dispatch_get_main_queue()) {
                self.sound("tester")
            }
    
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func sound(sound: String) {
            do {
                if let bundle = NSBundle.mainBundle().pathForResource(sound, ofType: "wav") {
                    let alertSound = NSURL(fileURLWithPath: bundle)
                    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
                    try AVAudioSession.sharedInstance().setActive(true)
                    let audioPlayer = try AVAudioPlayer(contentsOfURL: alertSound)
                    arrayOfPlayers.append(audioPlayer)
                    arrayOfPlayers.last?.prepareToPlay()
                    arrayOfPlayers.last?.play()
                }
            } catch {
                print(error)
            }
    
    
        }
    
    }