12

I am using a SKAudioNode() to play background music in my game. I have a play/pause function and everything is working fine until I plug in my headphones. There is no sound at all and when I call the pause/play function I get this error

AVAudioPlayerNode.mm:333: Start: required condition is false: _engine->IsRunning() com.apple.coreaudio.avfaudio', reason: 'required condition is false: _engine->IsRunning()

Does anyone knows what this means?

Code:

import SpriteKit

class GameScene: SKScene {

let loop = SKAudioNode(fileNamed: "gameloop.mp3")
let play = SKAction.play()
let pause = SKAction.pause()
var isPlaying = Bool()

override func didMoveToView(view: SKView) {  
    loop.runAction(play)
    isPlaying = true
    self.addChild(loop)
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    _ = touches.first as UITouch!

    for _ in touches {
        if isPlaying {
            loop.runAction(pause)
            isPlaying = false
        } else {
            loop.runAction(play)
            isPlaying = true
        } 
    }
}
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Cherrypig
  • 370
  • 1
  • 2
  • 12
  • Possible duplicate of [AVAudioEngine crashes when plug headphones in or out](http://stackoverflow.com/questions/26728250/avaudioengine-crashes-when-plug-headphones-in-or-out) – Chris Slowik Feb 26 '16 at 22:19
  • AVAudioEngineConfigurationChangeNotification was no help to me :( I found that question before – Cherrypig Feb 26 '16 at 22:27
  • Damn. Are you running on a simulator? I seem to recall running into a similar issue recently.. – Chris Slowik Feb 26 '16 at 22:34
  • no, I am testing on my device – Cherrypig Feb 26 '16 at 22:38
  • could you explain the order you are doing things? Start app,music plays, plug headphones in, tap screen crash? – Knight0fDragon Feb 27 '16 at 16:00
  • You are going to be my new hero, Knight :) starting app - hearing sound - pluggin in headphones - no sound on headphones - touching screen twice - crash – Cherrypig Feb 27 '16 at 16:06
  • works fine for me, what version of iOS – Knight0fDragon Feb 27 '16 at 16:58
  • really, hmm. I am building on 9.2.1. do you hear the music while headphones are pluged in? – Cherrypig Feb 27 '16 at 17:14
  • yes, I am using an iPad mini 2 on 9.2.1, no crashing. Also if you need me to respond faster, do @name so it notifies a person – Knight0fDragon Feb 27 '16 at 21:01
  • I've found it takes apple a few iterations of spritekit to get these new features working properly =/ a lot of the time they seem a little half baked – hamobi Feb 28 '16 at 13:38
  • @Knight0fDragon I guess there is no problem on ipads, only on iphones :( I found this post https://forums.developer.apple.com/thread/27980#jive-2401624518966197692552 – Cherrypig Feb 28 '16 at 14:18
  • Does that code fix it for you? I would test but i need my phone to stay in ios8 for testing – Knight0fDragon Feb 28 '16 at 14:20
  • @Knight0fDragon Thx for your help, I posted my workaround without using `SKAudioNode()` – Cherrypig Feb 29 '16 at 09:30
  • @Cherrypig It is a shame that SKAudioNode is currently broken like this. Still, I hope (and hope dies last lol) that there is a solution for this and I would like to start a bounty on this question. It is viewed only 34 times so far, and I just want to give it one more chance. Let me know if you agree. – Whirlwind Mar 04 '16 at 17:07
  • 1
    @Whirlwind This would be great! Thank you. Hopefully someone knows a solution :) – Cherrypig Mar 04 '16 at 18:01
  • @Cherrypig No responses so far...I forgot to mention that you should probably uncheck your accepted answer, because it can confuse people and make them think that issue is solved. Still there are three more days (one day + grace period) so you may try to un-accept your answer, and accept it later if question remain unanswered... – Whirlwind Mar 10 '16 at 20:52

2 Answers2

2

I was not able fix it, but by using AVAudioPlayer() I found a good workaround. Thank you all for supporting me!

import SpriteKit
import AVFoundation

class GameScene: SKScene {    
    var audioPlayer = AVAudioPlayer()  

    override func didMoveToView(view: SKView) {        
        initAudioPlayer("gameloop.mp3")        
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {        
        _ = touches.first as UITouch!
        for _ in touches {
            toggleBackgroundMusic()            
        }        
    }

    func initAudioPlayer(filename: String) {        
        let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
        guard let newURL = url else {
            print("Could not find file: \(filename)")
            return
        }
        do {
            audioPlayer = try AVAudioPlayer(contentsOfURL: newURL)
            audioPlayer.numberOfLoops = -1
            audioPlayer.prepareToPlay()
            audioPlayer.play()
        } catch let error as NSError {
            print(error.description)
        }        
    }

    func toggleBackgroundMusic() {        
        if audioPlayer.playing {
            audioPlayer.pause()
        } else {
            audioPlayer.play()
        }        
    }    
}
Cherrypig
  • 370
  • 1
  • 2
  • 12
2

SKScene has a property named audioEngine that is stopped in certain circumstances. If you´re using ReplayKit for example, playing a recorded gameplay movie in the RPPreviewController hi-jacks the audio and stops it, so when you dismiss it, the audioEngine is no longer running.

I had this issue and solved it by doing a simple check and starting the audioEngine again. Try this:

if !self.audioEngine.isRunning {
    do {
        try self.audioEngine.start()
    } catch {
        //handle error
    }
}
Lucifer
  • 71
  • 1
  • 3