Avaudioengine Crashes When Plug Headphones in or Out

AVAudioEngine crashes when plug headphones in or out

You need to register to the AVAudioEngineConfigurationChangeNotification notification and do the necessary steps to update the output node.

SKAudioNode() crashes when plugging in/out headphones

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

AVAudioEngine uses wrong format when bluetooth headset plugged in

After my failed bounty I wrote to Apple DTS, and got a wonderful response (including the code sample below that I translated from Objective-C).

The function below will connect to the default audio device in output-only mode, instead of the inout/output mode that is the default behavior. Remember to call it before engine start!

func setOutputDeviceFor(_ engine: AVAudioEngine) -> Bool {
var addr = AudioObjectPropertyAddress(
mSelector: kAudioHardwarePropertyDefaultOutputDevice,
mScope: kAudioObjectPropertyScopeGlobal,
mElement: kAudioObjectPropertyElementMaster)

var deviceID: AudioObjectID = 0
var size = UInt32(MemoryLayout.size(ofValue: deviceID))
let err = AudioObjectGetPropertyData(
AudioObjectID(kAudioObjectSystemObject),
&addr,
0,
nil,
&size,
&deviceID)

if (noErr == err && kAudioDeviceUnknown != deviceID) {
do {
try engine.outputNode.auAudioUnit.setDeviceID(deviceID)
} catch {
print(error)
return false
}
return true
} else {
print("ERROR: couldn't get default output device, ID = \(deviceID), err = \(err)")
return false
}
}

AVAudioEngine not posting notification in SpriteKit

The original Cocoa name of the notification is AVAudioEngineConfigurationChangeNotification, but the Swift constant is called AVAudioEngineConfigurationChange. Therefore you can handle the notification by using either:

let notificationName = Notification.Name("AVAudioEngineConfigurationChangeNotification")

or

let notificationName = Notification.Name.AVAudioEngineConfigurationChange

Your selector should then be called when plugging-in/unplugging headphones.

This appears to only be a partial solution for SpriteKit audio flakiness. I tried the following inside the notification handler:

try? self.audioEngine.start() 

I was able to stop the crash, but my SKAudioNode wouldn't make any sound after the plug/unplug event, until the process was restarted.



Related Topics



Leave a reply



Submit