让AVAudioPlayer一次播放多个声音

我试图获得多个声音文件在AVAudioPlayer实例上播放,但是当一个声音播放时,另一个停止。 我一次只能听到一个以上的声音。 这是我的代码:

import AVFoundation class GSAudio{ static var instance: GSAudio! var soundFileNameURL: NSURL = NSURL() var soundFileName = "" var soundPlay = AVAudioPlayer() func playSound (soundFile: String){ GSAudio.instance = self soundFileName = soundFile soundFileNameURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundFileName, ofType: "aif", inDirectory:"Sounds")!) do{ try soundPlay = AVAudioPlayer(contentsOfURL: soundFileNameURL) } catch { print("Could not play sound file!") } soundPlay.prepareToPlay() soundPlay.play () } } 

任何人都可以请告诉我如何获得多个声音文件一次玩吗? 任何帮助深表感谢。

非常感谢,凯

audio停止的原因是因为您只有一个AVAudioPlayer设置,因此当您要求该类播放另一个声音时,您正在用新的AVAudioPlayer实例replace旧的实例。 你基本上覆盖它。

您可以创buildGSAudio类的两个实例,然后在每个实例上调用playSound,或者使该类成为使用audioPlayers字典的通用audiopipe理器。

我更喜欢后面的选项,因为它允许更干净的代码,也更有效率。 你可以查看你之前是否已经为这个声音制作了一个播放器,而不是以一个新的播放器为例。

无论如何,我重新为你制作课程,以便一次播放多种声音。 它也可以播放相同的声音(它不会取代以前的声音)希望它有帮助!

该类是一个单身人士,所以要访问类的使用:

 GSAudio.sharedInstance 

例如,播放一个声音,你会打电话给:

 GSAudio.sharedInstance.playSound("AudioFileName") 

并一次播放一些声音:

 GSAudio.sharedInstance.playSounds("AudioFileName1", "AudioFileName2") 

或者你可以加载数组中的声音,并调用接受数组的playSounds函数:

 let sounds = ["AudioFileName1", "AudioFileName2"] GSAudio.sharedInstance.playSounds(sounds) 

我还添加了一个playSoundsfunction,可以让您以级联方式延迟每个声音的播放。 所以:

  let soundFileNames = ["SoundFileName1", "SoundFileName2", "SoundFileName3"] GSAudio.sharedInstance.playSounds(soundFileNames, withDelay: 1.0) 

在sound1之后会播放sound2,然后sound3会在sound2之后播放一秒

这是class级:

 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] { //player for sound has been found if player.playing == false { //player is not in use, so use that one player.prepareToPlay() player.play() } else { // player is in use, create a new, duplicate, player and use that instead let duplicatePlayer = try! AVAudioPlayer(contentsOfURL: soundFileNameURL) //use 'try!' because we know the URL worked before. duplicatePlayer.delegate = self //assign delegate for duplicatePlayer so delegate can remove the duplicate once it's stopped playing duplicatePlayers.append(duplicatePlayer) //add duplicate to array so it doesn't get removed from memory before finishing duplicatePlayer.prepareToPlay() duplicatePlayer.play() } } else { //player has not been found, create a new player with the URL if possible 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) { //withDelay is in seconds 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)!) //Remove the duplicate player once it is done } } 

我创build了一个帮助库,简化了在Swift中播放声音。 它创buildAVAudioPlayer的多个实例,以允许同时多次播放相同的声音。 你可以从Github上下载或者用Cocoapods导入。

这里是链接: SwiftySound

用法很简单:

 Sound.play(file: "sound.mp3") 

所有的答案都是张贴的代码页面; 它不需要那么复杂。

 // Create a new player for the sound; it doesn't matter which sound file this is let soundPlayer = try AVAudioPlayer( contentsOf: url ) soundPlayer.numberOfLoops = 0 soundPlayer.volume = 1 soundPlayer.play() soundPlayers.append( soundPlayer ) // In an timer based loop or other callback such as display link, prune out players that are done, thus deallocating them checkSfx: for player in soundPlayers { if player.isPlaying { continue } else { if let index = soundPlayers.index(of: player) { soundPlayers.remove(at: index) break checkSfx } } }