I have been facing this issue for a while and I have found a solution for this. The problem was caused when we set AVAudioSessionCategory before the WebRTC completed its configurations. We can fix this by updating the audio configurations on AudioSessionRouteChange happens. There are two approaches to finding the AudioSessionRouteChange and update the configurations.
1. Using RTCAudioSessionDelegate
let rtcAudioSession = RTCAudioSession.sharedInstance()
// set RTCAudioSessionDelegate to your class
rtcAudioSession.add(self)
// MARK: - RTCAudioSessionDelegate
extension YourClass: RTCAudioSessionDelegate {
func audioSessionDidChangeRoute(_ session: RTCAudioSession,
reason: AVAudioSession.RouteChangeReason,
previousRoute: AVAudioSessionRouteDescription) {
// set audio configurations
rtcAudioSession.lockForConfiguration()
do {
try rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord.rawValue, with: [.defaultToSpeaker, .allowBluetoothA2DP, .allowBluetooth])
try rtcAudioSession.setMode(AVAudioSession.Mode.videoChat.rawValue)
try rtcAudioSession.setActive(true)
} catch let error {
debugPrint("Error changeing AVAudioSession category: \(error)")
}
rtcAudioSession.unlockForConfiguration()
}
}
1. AVAudioSession.routeChangeNotification
let rtcAudioSession = RTCAudioSession.sharedInstance()
NotificationCenter.default.addObserver(forName: AVAudioSession.routeChangeNotification,
object: nil,
queue: nil,
using: onRouteChange)
private func onRouteChange(_ notification: Notification) {
// set audio configurations
rtcAudioSession.lockForConfiguration()
do {
try rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord.rawValue, with: [.defaultToSpeaker, .allowBluetoothA2DP, .allowBluetooth])
try rtcAudioSession.setMode(AVAudioSession.Mode.videoChat.rawValue)
try rtcAudioSession.setActive(true)
} catch let error {
debugPrint("Error changeing AVAudioSession category: \(error)")
}
rtcAudioSession.unlockForConfiguration()
}