我试图让多个声音文件在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 () } }
有人可以告诉我如何一次播放多个声音文件,以帮助我吗?任何帮助深表感谢。
非常感谢,凯
音频停止的原因是因为您仅设置了一个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)
将在sound1之后播放sound2,然后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] { //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 } }