Причина аудио останавливается, потому что у вас есть только один AVAudioPlayer установлен, поэтому, когда вы попросите класс, чтобы играть другой звук, который вы в настоящее время заменить старый экземпляр с новым экземпляром AVAudioPlayer. Вы переписываете его в основном.
Вы можете создать два экземпляра класса GSAudio, а затем вызвать playSound для каждого из них или сделать класс универсальным аудио-менеджером, который использует словарь аудиоплеер.
Я предпочитаю последний вариант, поскольку он позволяет использовать более чистый код и также более эффективен. Вы можете проверить, действительно ли вы уже сделали плеер для звука, вместо того, чтобы, например, создать нового игрока.
В любом случае, я переделал для вас свой класс, чтобы он воспроизводил сразу несколько звуков. Он также может воспроизводить один и тот же звук над собой (он не заменяет предыдущий экземпляр звука) Надеюсь, это поможет!
Класс одноэлементно, поэтому для доступа к использованию класса:
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] { //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
}
}
Вы когда-нибудь предлагали мой класс? –
@OlivierWilkinson Я действительно пробовал ваш класс, и это хорошо, если вы хотите запустить оба звука одновременно, но я хочу, чтобы при воспроизведении второго звука я не хочу, чтобы он внезапно останавливал звук, который уже играет. Спасибо за вашу помощь –
Я не уверен, что понимаю проблему. –