1

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.

famfamfam
  • 396
  • 3
  • 8
  • 31
  • When do you call those 2 methods? Is it on `func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession)`? – shinwan Feb 09 '21 at 06:18
  • this above function is for implement but i do nothing for this, my knowledge about callkit + webrtc is not enough, im so sorry about that, i updated more code about call configureaudiosession – famfamfam Feb 09 '21 at 06:39

2 Answers2

0

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.

Marco
  • 1,572
  • 1
  • 10
  • 21
  • Hi, first time im only set configureAudioSession only one time in diDAcceptCall method, but i make 40% of my call have no sound , but when try to above code it"s only remain 5%. – famfamfam Feb 10 '21 at 12:54
0

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)
Hamer
  • 1,354
  • 1
  • 21
  • 34
  • What is `lockForConfiguration` and `unlockForConfiguration ` – Saqib Omer Sep 02 '21 at 09:56
  • These are used to grant your application exclusive access to the device's hardware when making changes. https://developer.apple.com/documentation/avfoundation/avcapturedevice/1387810-lockforconfiguration – Hamer Sep 03 '21 at 03:15