【问题标题】:iOS, swift: play background music and sound effects without delayiOS,swift:无延迟播放背景音乐和音效
【发布时间】: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)")
}

}

【问题讨论】:

    标签: ios audio swift avfoundation soundeffect


    【解决方案1】:

    您可以使用 AVPlayer 播放您的声音文件。保留一个播放器,但在需要播放新声音时将其AVPlayerItem 更改为新项目。这可能比每次都重新创建播放器要快。

    虽然AVAudioPlayer/AVPlayer 是最简单的选项,但它不会在播放音频文件时给您最短的延迟或完美的同步。您应该查看Core Audio 内的音频队列或音频单元,以获得更准确的声音播放。

    【讨论】:

      【解决方案2】:

      问题是您在第一个音效完成之前播放第二个音效。当您将新的 AVAudioPlayer 设置为您的 soundEffectPlayer 变量时,您正在杀死对第一个的引用,第一个将停止播放。

      如果您不介意失去控制音量的可用性,您可以使用这个:

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

      否则,您可以使用AVAudioPlayer,如果您将创建的每个声音添加到数组中,并保留引用。然后你可以通过实现AVAudioPlayerdelegate在声音结束时将其删除。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-02
        • 1970-01-01
        • 1970-01-01
        • 2015-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-22
        相关资源
        最近更新 更多