我正在使用Sprite Kit开发适用于iOS 9+的游戏,最好使用Swift库。
目前我正在使用Singleton预装我的音频文件,每个音频文件都连接到一个单独的AVAudioPlayer实例。
这是一个简短的代码 - 剪切以获得想法:
import SpriteKit
import AudioToolbox
import AVFoundation
class AudioEngine {
static let sharedInstance = AudioEngine()
internal var sfxPing: AVAudioPlayer
private init() {
self.sfxPing = AVAudioPlayer()
if let path = NSBundle.mainBundle().pathForResource("ping", ofType: "m4a") {
do {
let url = NSURL(fileURLWithPath:path)
sfxPing = try AVAudioPlayer(contentsOfURL: url)
sfxPing.prepareToPlay()
} catch {
print("ERROR: Can't load ping.m4a audio file.")
}
}
}
}
在应用启动期间初始化此Singleton。在游戏循环中,我只需调用以下行来播放特定的音频文件:
AudioEngine.sharedInstance.sfxPing.play()
这基本上有效,但在播放文件时我总是会出现故障,并且我的iPad Air上的帧速率从60.0降到56.0。
有人知道如何使用AVAudioPlayer修复此性能问题吗?
我还看了第三方图书馆,即:
要求:
您能否根据我的要求推荐上述任何库,或使用上述代码指出问题?
更新
播放短音:
self.runAction(SKAction.playSoundFileNamed("sfx.caf", waitForCompletion: false))
确实提高了帧速率。 I exported the audio files with Audiacity to the .caf format (Apple's Core Audio Format).但是在教程中,它们使用“Signed 32-bit PCM
”编码导出,导致我的情况下音频播放受到干扰。使用任何其他编码选项(32-bit float
,U-Law
,A-Law
等。)对我来说很好。
为什么要使用caf
格式?因为与m4a
等压缩格式相比,它没有压缩,因此加载到内存中的速度更快,CPU开销更少。对于在短时间间隔内播放很多的短音效,这是有道理的,并且对于消耗几千字节的短音频文件,磁盘使用不会受到太大影响。对于较大的音频文件,如环境音乐和背景音乐,使用压缩格式(mp3
,m4a
)显然是更好的选择。
答案 0 :(得分:3)
根据您的问题,如果您开发适用于iOS 9+的游戏,则可以使用新的iOS 9库 SKAudioNode (official Apple doc):
var backgroundMusic: SKAudioNode!
例如,您可以将其添加到didMoveToView()
:
if let musicURL = NSBundle.mainBundle().URLForResource("music", withExtension: "m4a") {
backgroundMusic = SKAudioNode(URL: musicURL)
addChild(backgroundMusic)
}
您还可以用来播放简单的效果:
let beep = SKAudioNode(fileNamed: "beep.wav")
beep.autoplayLooped = false
self.addChild(beep)
最后,如果你想改变音量:
beep.runAction(SKAction.changeVolumeTo(0.4, duration: 0))
<强>更新强>:
我发现您更新了有关AVAudioPlayer
和SKAction
的问题。我已经为我的iOS8 +兼容游戏测试了它们。
关于AVAudioPlayer
,我个人使用我基于旧SKTAudio制作的自定义库。
我看到你的代码,关于AVAudioPlayer init,我的代码是不同的,因为我使用:
@available(iOS 7.0, *)
public init(contentsOfURL url: NSURL, fileTypeHint utiString: String?)
我不知道fileTypeHint
是否有所作为,所以请尽量让我知道你的考试。
您的代码的优势:
使用基于AVAudioPlayer
的共享实例音频管理器,您可以控制音量,随时随地使用您的经理,确保与iOS8的兼容性
您的代码的缺点: 每当你播放声音并想要播放另一种声音时,前一段声音就会被打破,特别是如果你发布了背景音乐。
如何解决?根据此SO post运行良好而没有问题似乎AVFoundation
仅限于4个AVAudioPlayer
属性可实例化,因此您可以执行此操作:
您可以构建一个方法来切换3声音效果以查看是否被占用:
if player.playing
并使用下一个免费播放器。通过这种解决方法,您可以始终正确地播放声音,甚至是背景音乐。