CallKit + WebRTC:在 iOS 中按下锁定/电源按钮时 CallKit 通话断开

Posted

技术标签:

【中文标题】CallKit + WebRTC:在 iOS 中按下锁定/电源按钮时 CallKit 通话断开【英文标题】:CallKit + WebRTC: CallKit call is getting disconnected when pressing lock / Power button in iOS 【发布时间】:2020-02-27 12:37:15 【问题描述】:

这是一个会议应用程序,我正在发起拨出电话以将我的 VoIP 电话作为高优先级,并且在我进行 VoIP 通话时不会中断来电。

我在我的应用程序中使用 WebRTC + CallKit。 我开始通话,当我按下锁定/电源按钮时,CallKit 通话将被断开,我的 Voip 通话音频路由更改为 Receiver 并保持不变。

为什么要锁定 iPhone 以终止通话。

这是我的代码。

 var callUUID: UUID?

extension AppDelegate 
    func initiateCallKitCall() 
        let config = CXProviderConfiguration(localizedName: "AppName")
        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: "AppName")))
        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
    

【问题讨论】:

【参考方案1】:

当且仅当通话通过屏幕顶部的内置扬声器(接收器)进行时,电源按钮才会结束通话。在任何其他情况下(即通过耳机、蓝牙或内置扬声器播放音频),电源按钮都不会结束通话。

本地电话也是如此。

【讨论】:

默认连接通话时如何确保通话音频通过扬声器。或通过编程方式。 配置音频会话的时候可以尝试添加这个:AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)【参考方案2】:

我想在这里回答所有与 CallKit 相关的问题。 我的问题的答案是:

您需要在 voip 通话成功建立后将 AudioSession 模式设置为 .default。

try AVAudioSession.sharedInstance().setMode(.default)
AudioRouteManager.shared.fourceRouteAudioToSpeakers()

【讨论】:

以上是关于CallKit + WebRTC:在 iOS 中按下锁定/电源按钮时 CallKit 通话断开的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 iOS 模拟器中使用 CallKit 接听电话?

如何在使用 Callkit 时播放声音,例如铃声?

在不启动本机 UI 的情况下添加 CallKit 条目

iOS CallKit 广告集成

iOS10:CallKit的简单应用

如何在 swift 4 iOS 中将 Callkit 与 Agora VOiP 集成?