Reputation: 535
after follow @Marco comment, i updated code like below, but still not working, the loudspeaker sometimes can not enabled
Before report new call/ user accepted call I called the 2 methods below:
configureAudioSessionToDefaultSpeaker()
func configureAudioSessionToDefaultSpeaker() {
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(AVAudioSession.Category.playAndRecord, mode: .default)
try session.setActive(true)
try session.setMode(AVAudioSession.Mode.voiceChat)
try session.setPreferredSampleRate(44100.0)
try session.setPreferredIOBufferDuration(0.005)
} catch {
print("Failed to configure `AVAudioSession`: \(error)")
}
}
I updated more code:
func startCallWithPhoneNumber(call : CallInfoModel) {
configureAudioSessionToDefaultSpeaker()
currentCall = call
if let unwrappedCurrentCall = currentCall {
let handle = CXHandle.init(type: .generic, value: unwrappedCurrentCall.CallerDisplay ?? UNKNOWN)
let startCallAction = CXStartCallAction.init(call: unwrappedCurrentCall.uuid, handle: handle)
let transaction = CXTransaction.init()
transaction.addAction(startCallAction)
requestTransaction(transaction: transaction)
self.provider?.reportOutgoingCall(with: startCallAction.callUUID, startedConnectingAt: nil)
}
}
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
configureAudioSessionToDefaultSpeaker()
delegate?.callDidAnswer()
action.fulfill()
currentCall?.isAccepted = true
let sb = UIStoryboard(name: "main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "SingleCallVC") as! SingleCallVC
vc.modalPresentationStyle = .fullScreen
vc.callObj = currentCall
vc.isIncoming = true
let appDelegate = AppDelegate.shared
appDelegate.window?.rootViewController?.present(vc, animated: true, completion: nil)
}
My call almost work normally but sometime loudspeaker can not be enabled. I read many documents but nothing worked for me. Could someone give me some advice? Thanks.
Upvotes: 1
Views: 1972
Reputation: 1383
I've had success with enabling the speaker using the method below.
let audioQueue = DispatchQueue(label: "audio")
func setSpeaker(_ isEnabled: Bool) {
audioQueue.async {
defer {
AVAudioSession.sharedInstance().unlockForConfiguration()
}
AVAudioSession.sharedInstance().lockForConfiguration()
do {
try AVAudioSession.sharedInstance().overrideOutputAudioPort(isEnabled ? .speaker : .none)
} catch {
debugPrint(error.localizedDescription)
}
}
}
// Enables the audio speaker.
setSpeaker(true)
// Disables the audio speaker.
setSpeaker(false)
Upvotes: 1
Reputation: 1686
You're configuring the AudioSession two times. The RTCAudioSession
it's a proxy of AVAudioSession
. You should do only one configuration to avoid unexpected results. RTCAudioSession
should expose all the methods of the AVAudioSession
, so you should be able to make all the configurations you want inside configureRtcAudioSession()
and eliminate configureAudioSessionToDefaultSpeaker()
or viceversa. I'm not sure if it will solve your issue but at least it should help to avoid unexpected behaviors.
Upvotes: 1