简体   繁体   English

iOS,迅速:立即播放背景音乐和音效

[英]iOS, swift: play background music and sound effects without delay

I am trying to create a game in iOS without using SpriteKit. 我试图在不使用SpriteKit的情况下在iOS中创建游戏。 I am stuck in getting the sound effects to play in a timely manner. 我一直无法及时播放声音效果。 I've been using the following code which I have found online and the background music plays great. 我一直在使用以下代码,这些代码是我在网上找到的,背景音乐播放效果很好。 However, when I use the "playSoundEffect" method it plays ok the first time but then starts to lag behind and becomes out of sync. 但是,当我使用“ playSoundEffect”方法时,它第一次播放正常,但随后开始滞后并变得不同步。 I guess that happens because it initializes an AVAudioPlayer every time. 我猜想是因为它每次都会初始化AVAudioPlayer。 Anyone have a good idea in how to play sound effects in a timely manner, while also playing background music? 在及时播放声音效果的同时,还播放背景音乐的人有一个好主意吗? Thanks! 谢谢!

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)")
}

}

You could using AVPlayer to play your sound file. 您可以使用AVPlayer播放声音文件。 Keep one player, but change its AVPlayerItem to a new item when you need to play a new sound. 保留一个播放器,但在需要播放新声音时将其AVPlayerItem更改为新项目。 It might be faster than recreating the player every time. 它可能比每次重新创建播放器都要快。

While AVAudioPlayer / AVPlayer is the simplest option, it will not give you the shortest delay or perfect synchronization when playing audio files. 虽然AVAudioPlayer / AVPlayer是最简单的选项,但是在播放音频文件时,它不会给您最短的延迟或完美的同步。 You should look into Audio Queues or Audio Units within Core Audio for more accurate sound playback. 您应该查看Core Audio中的 Audio Queue或Audio Units,以获得更准确的声音播放。

The problem is that you are playing the second sound effect before the first one is finished. 问题是您要在第一个音效完成之前播放第二个音效。 You are killing the reference to the first when you set the new AVAudioPlayer to your soundEffectPlayer variable and the first will stop playing. 当您将新的AVAudioPlayer设置为soundEffectPlayer变量时,您将终止对第一个的引用,并且第一个将停止播放。

If you don't mind loosing the availability of controlling the volume of the sound you could use this: 如果您不介意失去控制音量的可用性,则可以使用以下方法:

var mySound: SystemSoundID = 0
AudioServicesCreateSystemSoundID(url, &mySound)
// Play
AudioServicesPlaySystemSound(mySound)

Otherwise you can use AVAudioPlayer if you add each sound that you create into an array, keeping the reference. 否则,如果将创建的每个声音添加到数组中,并保留引用,则可以使用AVAudioPlayer Then you can delete it when the sound is done by implementing AVAudioPlayer delegate. 然后,当实现声音后,可以通过实现AVAudioPlayer委托将其删除。

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)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何播放/停止背景音乐和音效? - How to Play/Stop background music and sound effects? 有了iOS上的html5音频限制,是否可以同时播放背景音乐和声音效果? - With html5 audio limitations on iOS, is it possible to play background music and sound effects at the same time? 有没有办法暂停背景音乐(例如spotify)然后播放声音文件,然后在ios应用程序中再次播放背景音乐? - Is there a way of pausing background music(such as spotify) then play a sound file, then play the background music again in an ios application? 如何在不停止播放音乐的情况下在 swift 中播放声音? - How can I play a sound in swift without stopping the playing music? 使用AVAudioPlayer在后台播放声音而不停止ipod音乐 - Play sound in background using AVAudioPlayer without stopping ipod music iPod的背景音乐音量混合了声音效果 - Background iPod music Volume mixed with sound effects 在iOS的背景音乐中播放音乐 - Play music in background in ios iOS如何在后台播放音乐声音并暂停当前正在播放的音乐应用 - IOS How to play music sound in background and pause current playing music app iOS swift流媒体应用程序无法在后台模式播放音乐 - iOS swift streaming app does not play music in background mode 我想在不停止另一个应用程序后台播放的音乐的情况下制作音效 - I want to make sound effects without stopping the music playing in the background in another app
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM