David Marcus
David Marcus

Reputation: 474

CallKit Interferes With WebRTC Video

When I use CallKit to answer a WebRTC call, the video chat works most of the time. Once in a while the camera on my local iPhone isn't accessed correctly because of CallKit. When I remove CallKit, the video chat always works. Also if I set a delay for 1.5 second after I answer a CallKit call and then start the video chat, it seems to work well all of the time. What's the reason for this?

Upvotes: 2

Views: 2583

Answers (3)

YSR fan
YSR fan

Reputation: 735

I am using WebRTC + CallKit in my App. I started a call and when I press Lock / Power button then the CallKit call is getting disconnected and the My Voip call audio route changes to Receiver and remains.

Why locking the iPhone terminating the call.

Here is my Code.

    var callUUID: UUID?

extension AppDelegate {
    func initiateCallKitCall() {
        let config = CXProviderConfiguration(localizedName: "Huddl.ai")
        config.includesCallsInRecents = false;
        config.supportsVideo = true;
        config.maximumCallsPerCallGroup = 1
        provider = CXProvider(configuration: config)
        guard let provider = provider else { return }
        provider.setDelegate(self, queue: nil)
        callController = CXCallController()
        guard let callController = callController else { return }
        callUUID = UUID()
        let transaction = CXTransaction(action: CXStartCallAction(call: callUUID!, handle: CXHandle(type: .generic, value: "Huddl.ai")))
        callController.request(transaction, completion: { error in
            print("Error is : \(String(describing: error))")
        })

    }

    func endCallKitCall(userEnded: Bool) {
        self.userEnded = userEnded
        guard provider != nil else { return }
        guard let callController = callController else { return }
        if let uuid = callUUID {
            let endCallAction = CXEndCallAction(call: uuid)
            callController.request(
                CXTransaction(action: endCallAction),
                completion: { error in
                    if let error = error {
                        print("Error: \(error)")
                    } else {
                        print("Success")
                    }
                })
        }
    }

    func isCallGoing() -> Bool {
        let callController = CXCallController()
        if callController.callObserver.calls.count != 0 {
            return true
        }
        return false
    }
}

extension AppDelegate: CXProviderDelegate {

    func providerDidReset(_ provider: CXProvider) {
        print("-Provider-providerDidReset")
    }

    func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
        print("-Provider-perform action: CXAnswerCallAction")
        action.fulfill()
    }

    func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
        action.fulfill()
        print("-Provider: End Call")
    }

    func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
        action.fulfill()

        DispatchQueue.main.asyncAfter(wallDeadline: DispatchWallTime.now() + 3) {
            provider.reportOutgoingCall(with: action.callUUID, startedConnectingAt: Date())
            DispatchQueue.main.asyncAfter(wallDeadline: DispatchWallTime.now() + 1.5) {
                provider.reportOutgoingCall(with: action.callUUID, connectedAt: Date())
            }
        }
    }

    func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {
        action.fulfill()
    }

    func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
        RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession)
        RTCAudioSession.sharedInstance().isAudioEnabled = true
    }

    func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
        RTCAudioSession.sharedInstance().audioSessionDidDeactivate(audioSession)
        RTCAudioSession.sharedInstance().isAudioEnabled = false
    }
}

Upvotes: 0

johncederholm
johncederholm

Reputation: 149

Try implementing your (re)connection logic in providerDidReset(_ provider: CXProvider). You may also want to provide checks in this method to ensure you aren't resetting a successful connection.

Upvotes: 0

Ajay
Ajay

Reputation: 2643

Callkit is intended for Audio Call only, so callkit will activate AudioSession only.
Video will be activated only after you navigate to your application.

Try answering the call on phone lock screen, then you will get understood.

Test Facebook or any other popular app.

Upvotes: 2

Related Questions