iOS,swift:无延迟播放背景音乐和音效
Posted
技术标签:
【中文标题】iOS,swift:无延迟播放背景音乐和音效【英文标题】:iOS, swift: play background music and sound effects without delay 【发布时间】:2014-11-18 16:10:04 【问题描述】:我正在尝试在不使用 SpriteKit 的情况下在 ios 中创建游戏。 我坚持让音效及时播放。我一直在使用我在网上找到的以下代码,并且背景音乐播放得很好。但是,当我使用 “playSoundEffect”方法第一次播放正常,但随后开始滞后并变得不同步。我猜这是因为它每次都初始化一个 AVAudioPlayer 。 任何人都知道如何及时播放音效,同时播放背景音乐?谢谢!
import AVFoundation
public class SKTAudio: NSObject, AVAudioPlayerDelegate
public var backgroundMusicPlayer: AVAudioPlayer?
public var soundEffectPlayer: AVAudioPlayer?
private var mainLoopFileName:String!
let randomSong = Int(arc4random_uniform(3))
switch randomSong
//case 0: return "Test.mp3"
//case 1: return "Test2.mp3"
case 0: return "SneakySnitch.mp3"
case 1: return "FasterDoesIt.mp3"
case 2: return "MonkeysSpinningMonkeys.mp3"
default:
break
return "SneakySnitch.mp3"
public class func sharedInstance() -> SKTAudio
return SKTAudioInstance
public func playBackgroundMusic()
let filename = mainLoopFileName
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
if (url == nil)
println("Could not find file: \(filename)")
return
var error: NSError? = nil
backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
if let player = backgroundMusicPlayer
player.numberOfLoops = 0
player.delegate = self
player.prepareToPlay()
player.play()
else
println("Could not create audio player: \(error!)")
public func pauseBackgroundMusic()
if let player = backgroundMusicPlayer
if player.playing
player.pause()
public func resumeBackgroundMusic()
if let player = backgroundMusicPlayer
if !player.playing
player.play()
public func playSoundEffect(filename: String)
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
if (url == nil)
println("Could not find file: \(filename)")
return
var error: NSError? = nil
soundEffectPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
if let player = soundEffectPlayer
player.numberOfLoops = 0
player.prepareToPlay()
player.play()
else
println("Could not create audio player: \(error!)")
// MARK: AVAudioPlayerDelegate
public func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool)
println("finished playing \(flag)")
delay(5.0,
self.playBackgroundMusic()
)
public func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!)
println("\(error.localizedDescription)")
【问题讨论】:
【参考方案1】:您可以使用 AVPlayer 播放您的声音文件。保留一个播放器,但在需要播放新声音时将其AVPlayerItem
更改为新项目。这可能比每次都重新创建播放器要快。
虽然AVAudioPlayer
/AVPlayer
是最简单的选项,但它不会在播放音频文件时给您最短的延迟或完美的同步。您应该查看Core Audio 内的音频队列或音频单元,以获得更准确的声音播放。
【讨论】:
【参考方案2】:问题是您在第一个音效完成之前播放第二个音效。当您将新的 AVAudioPlayer
设置为您的 soundEffectPlayer
变量时,您正在杀死对第一个的引用,第一个将停止播放。
如果您不介意失去控制音量的可用性,您可以使用这个:
var mySound: SystemSoundID = 0
AudioServicesCreateSystemSoundID(url, &mySound)
// Play
AudioServicesPlaySystemSound(mySound)
否则,您可以使用AVAudioPlayer
,如果您将创建的每个声音添加到数组中,并保留引用。然后你可以通过实现AVAudioPlayer
delegate在声音结束时将其删除。
func playSound()
let path : NSString? = NSBundle.mainBundle().pathForResource("sound", ofType: "wav")!
let url = NSURL(fileURLWithPath: path!)
var error : NSError?
let sound = AVAudioPlayer(contentsOfURL: url, error: &error)
sound.delegate = self
sound.volume = 0.5
self.soundsEffectsArray.addObject(sound)
sound.prepareToPlay()
sound.play()
func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool)
self.soundsEffectsArray.removeObject(player)
【讨论】:
以上是关于iOS,swift:无延迟播放背景音乐和音效的主要内容,如果未能解决你的问题,请参考以下文章