【发布时间】:2017-12-07 03:40:16
【问题描述】:
我有一个类似西蒙的记忆游戏,播放一系列音调,用户尝试重复这些音调。问题是我不时听到可怕的噼啪声。它可能是在几个音符或多达二十个音符之后。声音都是两秒长的 wav 文件。我循环播放十个播放器,这样所有声音都不会被剪裁。 (我尝试了多达 50 个,但没有任何帮助。)我还尝试实现 audioPlayerDidFinishPlaying,以便在声音完成后停止播放器,但这也无济于事。最后,我添加了prepareToPlay() - 遗憾的是,没有区别。
一个可能相关也可能不相关的有趣问题是,在大约 15 个音符的序列之后,音频停止一起工作。应用继续正常运行,但没有任何声音。
这是代码的音频部分:
func playSound(_ soundID: Int) {
var soundName = ""
switch soundID {
case 0:
soundName = "beep1"
case 1:
soundName = "beep2"
case 2:
soundName = "beep3"
case 3:
soundName = "beep4"
case 4:
soundName = "swish3"
default:
soundName = "clank"
}
guard let url = Bundle.main.url(forResource: soundName, withExtension: "wav") else { return }
do {
buttonSound.insert(try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue), at: playerIndex)
buttonSound[playerIndex].prepareToPlay()
buttonSound[playerIndex].delegate = self
if playerIndex < 10 {
buttonSound[playerIndex].play()
playerIndex += 1
} else {
buttonSound[playerIndex].play()
playerIndex = 0
}
} catch {
// error
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if flag {
player.stop()
}
}
/******** 更新*********/
根据我遇到的一个过时的示例,我将 AVAudioPlayer 创建移到了它自己的类中……某处。它解决了15音后完全切断音频的问题,但是裂纹和爆裂声仍然存在!我还尝试重新录制声音,但没有成功。
这是根据需要创建 AVAudioPlayers 的类:
import UIKit
import AVFoundation
private var players: [AVAudioPlayer] = []
class AVAudioPlayerPool: NSObject {
class func playerWithURL(url: URL) -> AVAudioPlayer? {
let availablePlayers = players.filter { (player) -> Bool in
return player.isPlaying == false && player.url == url
}
if let playerToUse = availablePlayers.first {
playerToUse.prepareToPlay()
return playerToUse
}
do {
let newPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
players.append(newPlayer)
newPlayer.prepareToPlay()
return newPlayer
} catch {
return nil
}
}
}
播放声音很简单:
func playSound(_ soundID: Int) {
var soundName = ""
switch soundID {
case 0:
soundName = "tt1"
case 1:
soundName = "tt2"
case 2:
soundName = "tt3"
case 3:
soundName = "tt4"
case 4:
soundName = "swish3"
default:
soundName = "clank"
}
guard let url = Bundle.main.url(forResource: soundName, withExtension: "wav") else { return }
let player = AVAudioPlayerPool.playerWithURL(url: url)
player?.play()
}
如果有人有任何想法 - 即使只是下一步,您也可以尝试......
【问题讨论】:
-
如何在后台队列中播放文件?主线程可能正忙于处理您的游戏,这可能会导致您遇到爆裂声
-
我尝试将其移出主线程 - 仍然很脆。不过谢谢你的建议。
-
你用过 OALSimpleAudio 吗? github.com/kstenerud/ObjectAL-for-iPhone我在我当前的游戏项目中使用它,它有很多不同的声音。它是一个 Objective-C 代码,但使用桥接头很容易添加到 swift 项目中。如果您需要帮助,请告诉我
-
@Woof,我很欣赏这个建议,但是,这只是一个简单的学习项目。我真的很想弄清楚 AVAudioPlayer。如果这是一个实际项目,我会在几周前继续前进。谢谢!
标签: ios swift avaudioplayer