声音通过SKAction而不是通过AVAudioPlayer播放

时间:2017-02-11 18:09:11

标签: swift sprite-kit swift2

我在游戏中播放声音时遇到了一个棘手的问题,但似乎无法通过AVAudioPlayer获得任何输出。最初这被设置为一个类,但是当它没有工作时,我尝试硬编码声音输出只是为了检查那里是否有问题。它仍然没有工作,我尝试了一些不同的文件来排除有问题的音频文件或格式。正在检索URL,但audioPlayer似乎没有输出任何声音。

我已经阅读了一些关于类似问题的线索并且摆弄了系统声音设置,但它没有任何区别。有人建议模拟器在某些情况下不能输出声音,但我不相信这就是这种情况。

let myFile = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("gong", ofType: "wav")!)
    print ("URL data: \(myFile)")
    do{
        let audioPlayer = try AVAudioPlayer(contentsOfURL:myFile)
        audioPlayer.prepareToPlay()
        audioPlayer.play()    
    }catch {
        print("Error playing sound")
    }

然而这很好:

  self.runAction(SKAction.playSoundFileNamed("gong", waitForCompletion: false))

我需要AVAudioPlayer的功能,因为我希望能够在循环时启动停止并控制声音的音量。我使用的是XCode 7.3.1和Swift 2.2。

有什么想法吗?

非常感谢, 千瓦

2 个答案:

答案 0 :(得分:1)

谈到 Swift 2 ,我认为你应该尝试不同的方法来获取网址:

import AVFoundation

func playMusic(filename: String) {
    let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
    if (url == nil) {
        print("Could not find file: \(filename)")
        return
    }
    do { backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: url!, fileTypeHint: nil) }
    catch let error as NSError { print(error.description) }
    if let player = backgroundMusicPlayer {
        player.volume = 1
        player.numberOfLoops = -1
        player.prepareToPlay()
        player.play()
    }
}

答案 1 :(得分:0)

我想添加一个帮助我的答案。 AVAudioPlayer的{​​{1}}方法是异步的,所以我实际上找到了播放声音文件的最佳方法,而不会在第一次加载到内存时遇到延迟,只是异步调用它:

SWIFT 2

play()

SWIFT 3

import AVFoundation

var audioPlayer: AVAudioPlayer?

init() {

    let soundURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("FileName", ofType: "wav")!)
    if let soundURL = soundURL {

        do {
            self.audioPlayer = try AVAudioPlayer(contentsOfURL: soundURL)
        } catch let error as NSError {
            print(error.description)
        }
    } else {
        // Handle situation where URL isn't found
        print("Sound file URL not found")
    }

}

func playSound() {
    guard let audioPlayer = audioPlayer else { return }
    // Now we can play the sound asynchronously - which will eliminate any lag upon initial play
    let qualityOfServiceClass = QOS_CLASS_BACKGROUND
    let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
    dispatch_async(backgroundQueue, {
        audioPlayer.play()
    })

}

这样做的想法是将某种类型的SoundManager类合并到您的模型中。我通常创建一个这样的类,对于我在整个应用程序中需要的每个声音都有一个import AVFoundation var audioPlayer: AVAudioPlayer? init() { let soundURL = URL(fileURLWithPath: Bundle.main.path(forResource: "FileName", ofType: "wav")!) if let soundURL = soundURL { do { self.audioPlayer = try AVAudioPlayer(contentsOf: soundURL) } catch let error { print(error.description) } } else { // Handle situation where URL isn't found print("Sound file URL not found") } } func playSound() { guard let audioPlayer = audioPlayer else { return } // Now we can play the sound asynchronously - which will eliminate any lag upon initial play DispatchQueue.global().async { audioPlayer.play() } } ,我可以在加载ViewController时实例化它 - 它将根据它自己的AVAudioPlayer方法初始化各个audioPlayers 。然后我可以使用自己的播放方法播放每个文件。如果您有一堆不同的声音,它也可以帮助您使用init()来组织不同的文件,并且有一个自定义enum方法可以播放作为请求传入的文件。