音频停止的原因是你只有一个AVAudioPlayer设置,所以当你要求该类播放另一个声音时,你正在用AVAudioPlayer的新实例替换旧实例。你基本上在覆盖它。
你可以创建两个GSAudio类的实例,然后在每个实例上调用playSound,或者将该类作为通用音频管理器,使用audioPlayers字典。
我更喜欢后者选项,因为它可以产生更清晰的代码,并且也更有效率。例如,你可以检查是否已经为该声音制作了播放器,而不是制作一个新的播放器。
无论如何,我重新为你制作了该类,使得它可以同时播放多个声音。它还可以在自身上播放相同的声音(它不会替换前一个声音的实例)。希望有所帮助!
该类是单例模式,因此要访问该类,请使用:
GSAudio.sharedInstance
例如,要播放声音,您需要调用以下函数:
GSAudio.sharedInstance.playSound("AudioFileName")
同时播放多个声音:
GSAudio.sharedInstance.playSounds("AudioFileName1", "AudioFileName2")
或者你可以在某个地方将声音加载到数组中,并调用接受数组的playSounds函数:
let sounds = ["AudioFileName1", "AudioFileName2"]
GSAudio.sharedInstance.playSounds(sounds)
我还添加了一个playSounds函数,它允许你以级联的方式延迟播放每个声音。因此:
let soundFileNames = ["SoundFileName1", "SoundFileName2", "SoundFileName3"]
GSAudio.sharedInstance.playSounds(soundFileNames, withDelay: 1.0)
希望第二个声音(sound2)在第一个声音(sound1)的后面延迟一秒钟播放,接着第三个声音(sound3)在第二个声音(sound2)的后面延迟一秒钟播放等等。
以下是该类:
class GSAudio: NSObject, AVAudioPlayerDelegate {
static let sharedInstance = GSAudio()
private override init() {}
var players = [NSURL:AVAudioPlayer]()
var duplicatePlayers = [AVAudioPlayer]()
func playSound (soundFileName: String){
let soundFileNameURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundFileName, ofType: "aif", inDirectory:"Sounds")!)
if let player = players[soundFileNameURL] {
if player.playing == false {
player.prepareToPlay()
player.play()
} else {
let duplicatePlayer = try! AVAudioPlayer(contentsOfURL: soundFileNameURL)
duplicatePlayer.delegate = self
duplicatePlayers.append(duplicatePlayer)
duplicatePlayer.prepareToPlay()
duplicatePlayer.play()
}
} else {
do{
let player = try AVAudioPlayer(contentsOfURL: soundFileNameURL)
players[soundFileNameURL] = player
player.prepareToPlay()
player.play()
} catch {
print("Could not play sound file!")
}
}
}
func playSounds(soundFileNames: [String]){
for soundFileName in soundFileNames {
playSound(soundFileName)
}
}
func playSounds(soundFileNames: String...){
for soundFileName in soundFileNames {
playSound(soundFileName)
}
}
func playSounds(soundFileNames: [String], withDelay: Double) {
for (index, soundFileName) in soundFileNames.enumerate() {
let delay = withDelay*Double(index)
let _ = NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: #selector(playSoundNotification(_:)), userInfo: ["fileName":soundFileName], repeats: false)
}
}
func playSoundNotification(notification: NSNotification) {
if let soundFileName = notification.userInfo?["fileName"] as? String {
playSound(soundFileName)
}
}
func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {
duplicatePlayers.removeAtIndex(duplicatePlayers.indexOf(player)!)
}
}