Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ENGDESK-37644): Fix CallKit speaker button inconsistency #158

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 91 additions & 2 deletions TelnyxRTC/Telnyx/TxClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,51 @@ public class TxClient {
self.serverConfiguration = TxServerConfiguration()
self.configure()
sessionId = UUID().uuidString.lowercased()

// Start monitoring audio route changes
setupAudioRouteChangeMonitoring()
}

private func setupAudioRouteChangeMonitoring() {
NotificationCenter.default.addObserver(
self,
selector: #selector(handleAudioRouteChange),
name: AVAudioSession.routeChangeNotification,
object: nil)
}

@objc private func handleAudioRouteChange(notification: Notification) {
guard let userInfo = notification.userInfo,
let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else {
return
}

let session = AVAudioSession.sharedInstance()
let currentRoute = session.currentRoute

// Check if we have any output ports
guard let output = currentRoute.outputs.first else {
return
}

Logger.log.i(message: "Audio route changed: \(output.portType), reason: \(reason)")

switch reason {
case .categoryChange, .override, .routeConfigurationChange:
// Update speaker state based on current output
let isSpeaker = output.portType == .builtInSpeaker
speakerOn = isSpeaker

// Notify UI of the change
NotificationCenter.default.post(
name: NSNotification.Name("AudioRouteChanged"),
object: nil,
userInfo: ["isSpeakerOn": isSpeaker]
)
default:
break
}
}

// MARK: - Connection handling
Expand Down Expand Up @@ -257,6 +302,12 @@ public class TxClient {
call.hangup()
}
self.calls.removeAll()

// Remove audio route change observer
NotificationCenter.default.removeObserver(self,
name: AVAudioSession.routeChangeNotification,
object: nil)

socket?.disconnect(reconnect: false)
delegate?.onSocketDisconnected()
}
Expand Down Expand Up @@ -627,21 +678,59 @@ extension TxClient {
public func setEarpiece() {
do {
let audioSession = AVAudioSession.sharedInstance()
let rtcAudioSession = RTCAudioSession.sharedInstance()

rtcAudioSession.lockForConfiguration()
defer {
rtcAudioSession.unlockForConfiguration()
}

// Configure audio session for earpiece output
try audioSession.overrideOutputAudioPort(.none)
try rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord,
options: [.allowBluetooth, .allowBluetoothA2DP, .mixWithOthers])

// Update speaker state
speakerOn = false

// Post notification for UI update
NotificationCenter.default.post(name: NSNotification.Name("AudioRouteChanged"),
object: nil,
userInfo: ["isSpeakerOn": false])

Logger.log.i(message: "Earpiece mode enabled successfully")
} catch let error {
Logger.log.e(message: "Error setting Earpiece \(error)")
Logger.log.e(message: "Error setting Earpiece: \(error)")
}
}

/// Select the speaker as the audio output
public func setSpeaker() {
do {
let audioSession = AVAudioSession.sharedInstance()
let rtcAudioSession = RTCAudioSession.sharedInstance()

rtcAudioSession.lockForConfiguration()
defer {
rtcAudioSession.unlockForConfiguration()
}

// Configure audio session for speaker output
try audioSession.overrideOutputAudioPort(.speaker)
try rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord,
options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP, .mixWithOthers])

// Update speaker state
speakerOn = true

// Post notification for UI update
NotificationCenter.default.post(name: NSNotification.Name("AudioRouteChanged"),
object: nil,
userInfo: ["isSpeakerOn": true])

Logger.log.i(message: "Speaker mode enabled successfully")
} catch let error {
Logger.log.e(message: "Error setting Speaker \(error)")
Logger.log.e(message: "Error setting Speaker: \(error)")
}
}
}
Expand Down
17 changes: 15 additions & 2 deletions TelnyxRTC/Telnyx/WebRTC/Peer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,24 @@
Logger.log.i(message: "Peer:: Configuring AVAudioSession")
self.rtcAudioSession.useManualAudio = true
self.rtcAudioSession.isAudioEnabled = false

// Configure audio session for VoIP calls
try self.rtcAudioSession.setCategory(AVAudioSession.Category(rawValue: AVAudioSession.Category.playAndRecord.rawValue))
try self.rtcAudioSession.setMode(AVAudioSession.Mode.voiceChat)
Logger.log.i(message: "Peer:: Configuring AVAudioSession configured")

// Enable mixing with other audio sessions
try self.rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord,

Check failure on line 145 in TelnyxRTC/Telnyx/WebRTC/Peer.swift

View workflow job for this annotation

GitHub Actions / ios_fastlane_tests

missing argument for parameter 'mode' in call

Check failure on line 145 in TelnyxRTC/Telnyx/WebRTC/Peer.swift

View workflow job for this annotation

GitHub Actions / ios_fastlane_tests

missing argument for parameter 'mode' in call
options: [.allowBluetooth, .allowBluetoothA2DP, .mixWithOthers])

// Set preferred audio I/O buffer duration
try self.rtcAudioSession.setPreferredIOBufferDuration(0.005)

// Set preferred sample rate
try self.rtcAudioSession.setPreferredSampleRate(44100.0)

Logger.log.i(message: "Peer:: AVAudioSession configured successfully")
} catch let error {
Logger.log.e(message: "Peer:: Error changing AVAudioSession category: \(error.localizedDescription)")
Logger.log.e(message: "Peer:: Error configuring AVAudioSession: \(error.localizedDescription)")
}
self.rtcAudioSession.unlockForConfiguration()
}
Expand Down
Loading