Varkarrus Varkarrus - 7 months ago 74
Swift Question

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.

Answer

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


    }

}