@@ -118,13 +118,23 @@ class StreamInCallManager: RCTEventEmitter {
118118
119119 if ( defaultAudioDevice == . speaker) {
120120 // defaultToSpeaker will route to speaker if nothing else is connected
121- intendedOptions = [ . allowBluetooth , . defaultToSpeaker]
121+ intendedOptions = [ . allowBluetoothHFP , . defaultToSpeaker]
122122 } else {
123123 // having no defaultToSpeaker makes sure audio goes to earpiece if nothing is connected
124- intendedOptions = [ . allowBluetooth ]
124+ intendedOptions = [ . allowBluetoothHFP ]
125125 }
126126 }
127127
128+ // STEP 1: Configure iOS native audio session FIRST (this does the pre-warming so that webrtc worker thread isnt stalled on audio unit initialisation)
129+ let nativeSession = AVAudioSession . sharedInstance ( )
130+ do {
131+ try nativeSession. setCategory ( intendedCategory, mode: intendedMode, options: intendedOptions)
132+ try nativeSession. setActive ( true )
133+ log ( " configureAudioSession: Native AVAudioSession configured successfully " )
134+ } catch {
135+ log ( " configureAudioSession: Failed to configure native session: \( error. localizedDescription) " )
136+ }
137+
128138 // START: set the config that webrtc must use when it takes control
129139 let rtcConfig = RTCAudioSessionConfiguration . webRTC ( )
130140 rtcConfig. category = intendedCategory. rawValue
@@ -133,6 +143,7 @@ class StreamInCallManager: RCTEventEmitter {
133143 RTCAudioSessionConfiguration . setWebRTC ( rtcConfig)
134144 // END
135145
146+
136147 // START: compare current audio session with intended, and update if different
137148 let session = RTCAudioSession . sharedInstance ( )
138149 let currentCategory = session. category
@@ -180,12 +191,14 @@ class StreamInCallManager: RCTEventEmitter {
180191
181192 @objc ( setForceSpeakerphoneOn: )
182193 func setForceSpeakerphoneOn( enable: Bool ) {
183- let session = AVAudioSession . sharedInstance ( )
184- do {
185- try session. overrideOutputAudioPort ( enable ? . speaker : . none)
186- try session. setActive ( true )
187- } catch {
188- log ( " Error setting speakerphone: \( error) " )
194+ audioSessionQueue. async {
195+ let session = AVAudioSession . sharedInstance ( )
196+ do {
197+ try session. overrideOutputAudioPort ( enable ? . speaker : . none)
198+ try session. setActive ( true )
199+ } catch {
200+ self . log ( " Error setting speakerphone: \( error) " )
201+ }
189202 }
190203 }
191204
0 commit comments