App Crash during toggle between Speaker to bluetooth headphone.

We have developed iOS app using WebRTC and ARKit for the video communication. We have the option to toggle between headphone and speaker.

We are facing an app crash when bluetooth headphone is connected and the user tries to toggle between speaker and headphone continuously.

Also while toggle between speaker and headphone it throws log in console

ARSessionDelegate is retaining 11 ARFrames. This can lead to future camera frames being dropped.

Following is the crash : Fatal Exception: com.apple.coreaudio.avfaudio required condition is false: nil == owningEngine || GetEngine() == owningEngine

Following are the code snippet :

func headphoneOn() -> Bool {
     audioSession.lockForConfiguration()
     var bluetoothPort : AVAudioSessionPortDescription? = nil
     var headphonePort : AVAudioSessionPortDescription? = nil
     var inbuiltMicPort : AVAudioSessionPortDescription? = nil
     
     if let availableInputs = AVAudioSession.sharedInstance().availableInputs {
       for inputDevice in availableInputs {
         if inputDevice.portType == .builtInMic {
          inbuiltMicPort = inputDevice
        } else if inputDevice.portType == .headsetMic || inputDevice.portType == .headphones {
          headphonePort = inputDevice
        } else if inputDevice.portType == .bluetoothHFP || inputDevice.portType == .bluetoothA2DP || inputDevice.portType == .bluetoothLE {
          bluetoothPort = inputDevice
        }
      }
    }
     
     do {
       try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
       if let bluetoothPort = bluetoothPort {
         try audioSession.setPreferredInput(bluetoothPort)
         try audioSession.setMode(AVAudioSession.Mode.voiceChat.rawValue)
         audioSession.unlockForConfiguration()
         return true
      } else if let headphonePort = headphonePort {
         try audioSession.setPreferredInput(headphonePort)
         try audioSession.setMode(AVAudioSession.Mode.voiceChat.rawValue)
         audioSession.unlockForConfiguration()
         return true
      } else if let inbuiltMicPort = inbuiltMicPort {
         try audioSession.setMode(AVAudioSession.Mode.default.rawValue)
         try audioSession.setPreferredInput(inbuiltMicPort)
         audioSession.unlockForConfiguration()
         return true
      } else {
         audioSession.unlockForConfiguration()
         return false
      }
       
    } catch let error as NSError {
       debugPrint("#configureAudioSessionToSpeaker Error \(error.localizedDescription)")
       audioSession.unlockForConfiguration()
       return false
    }
     
  }

func speakerOn() -> Bool {
     audioSession.lockForConfiguration()
     var inbuiltSpeakerPort : AVAudioSessionPortDescription? = nil
     
     if let availableInputs = AVAudioSession.sharedInstance().availableInputs {
       for inputDevice in availableInputs {
         if inputDevice.portType == .builtInSpeaker {
          inbuiltSpeakerPort = inputDevice
        }
      }
    }
     do { ///Audio Session: Set on Speaker
       if let inbuiltSpeakerPort = inbuiltSpeakerPort {
         try audioSession.setPreferredInput(inbuiltSpeakerPort)
      }
       try audioSession.setMode(AVAudioSession.Mode.videoChat.rawValue)
       try audioSession.overrideOutputAudioPort(.speaker)
       audioSession.unlockForConfiguration()
       return true
       
    } catch let error as NSError {
       debugPrint("#configureAudioSessionToSpeaker Error \(error.localizedDescription)")
       audioSession.unlockForConfiguration()
       return false
       
    }
  }

Any help will be appreciated to solve this crash issue.

Replies

Hello,

This error can occur when you attach a node to one engine, and then try attaching it to another engine, for example:

            audioEngine.attach(playerNode)
            otherEngine.attach(playerNode) // fatal error: "required condition is false: nil == owningEngine || GetEngine() == owningEngine"

So, it seems that you have at least one scenario where this sort of thing can happen in your app.

I am working on an application that uses RealityKit and AVAudioSession for audio calls, and I too am having the same owningEngine == nil crash. It has been a nightmare for a few months now...