首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >接受锁定屏幕呼叫时,Callkit和Webrtc没有音频

接受锁定屏幕呼叫时,Callkit和Webrtc没有音频
EN

Stack Overflow用户
提问于 2019-07-19 13:14:57
回答 3查看 1.7K关注 0票数 0

我试图使callkit与webrtc的来电,但当我收到电话,并从锁定的屏幕接受它,没有声音,直到我运行应用程序在前景模式。我已经配置了音频信号发送通知给RTCAudioSession,但是它不起作用。你有什么解决办法吗?

代码语言:javascript
运行
复制
      func configureAudioSession() {

        let sharedSession = AVAudioSession.sharedInstance()
        do {
            try sharedSession.setCategory(AVAudioSessionCategoryPlayAndRecord, mode: AVAudioSessionModeVideoChat, options: .mixWithOthers)
            try sharedSession.setMode(AVAudioSessionModeVideoChat)
//            try sharedSession.setAggregatedIOPreference(AVAudioSessionIOType.aggregated)
        } catch {
            debugPrint("Failed to configure `AVAudioSession`")
        }
    }

    func handleIncomingCall(spaceName:String) {
        if callUUID != nil {
            oldCallUUID = callUUID
        }
        callUUID = UUID()
        print("CallManager handle uuid = \(callUUID?.description)")
        let update = CXCallUpdate()
        update.hasVideo = true
        update.remoteHandle = CXHandle(type: .generic, value: spaceName)
        self.configureAudioSession()
        provider?.reportNewIncomingCall(with: callUUID!, update: update, completion: { error in
            print("CallManager report new incoming call completion")
        })
    }

 func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
        print("CallManager didActivate")
        RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession)
        RTCAudioSession.sharedInstance().isAudioEnabled = true
        self.callDelegate?.callIsAnswered()
    }

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

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-07-23 10:47:36

好吧,我找到问题的原因了。在IOS 12中,当您从锁定的屏幕启动webrtc并试图获得对相机的访问(输出卷中断,因此解决方案是检查屏幕是否处于活动状态,如果没有)时,请不要请求并将本地RTCVideoTrack添加到您的RTCStream中。

票数 3
EN

Stack Overflow用户

发布于 2019-07-22 14:19:18

您的测试iOS是什么版本的iPhone?

票数 0
EN

Stack Overflow用户

发布于 2021-06-09 11:12:04

请注意,我分享我的代码,它接近我的需要,我分享,以供参考。您需要根据需要更改它。

当您收到voip通知时,创建webrtc处理类的新事件,并将这两行添加到代码块中,因为从voip通知中启用音频会话失败

代码语言:javascript
运行
复制
RTCAudioSession.sharedInstance().useManualAudio = true
RTCAudioSession.sharedInstance().isAudioEnabled = false 

didReceive法;

代码语言:javascript
运行
复制
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
               let state = UIApplication.shared.applicationState
               
        
     
                   if(payload.dictionaryPayload["hangup"] == nil && state != .active
                   ){
                       
               
                     Globals.voipPayload = payload.dictionaryPayload as! [String:Any] // I pass parameters to Webrtc handler via Global singleton to create answer according to sdp sent by payload.
                        
                       RTCAudioSession.sharedInstance().useManualAudio = true
                       RTCAudioSession.sharedInstance().isAudioEnabled = false
                       
                     
                      
                     Globals.sipGateway = SipGateway() // my Webrtc and Janus gateway handler class
                    
                       
                     Globals.sipGateway?.configureCredentials(true) // I check janus gateway credentials stored in Shared preferences and initiate websocket connection and create peerconnection 
to my janus gateway which is signaling server for my environment
                    
                       
                  initProvider() //Crating callkit provider
                       
                       self.update.remoteHandle = CXHandle(type: .generic, value:String(describing: payload.dictionaryPayload["caller_id"]!))
                          Globals.callId = UUID()
             
                       let state = UIApplication.shared.applicationState
                       
                      
                          Globals.provider.reportNewIncomingCall(with:Globals.callId , update: self.update, completion: { error in
                           
                           
                          })
                       
                
               }
              
           }
    
        
        func  initProvider(){
            let config = CXProviderConfiguration(localizedName: "ulakBEL")
            config.iconTemplateImageData = UIImage(named: "ulakbel")!.pngData()
            config.ringtoneSound = "ringtone.caf"
                   // config.includesCallsInRecents = false;
                    config.supportsVideo = false
            
            Globals.provider = CXProvider(configuration:config )
            Globals.provider.setDelegate(self, queue: nil)
             update = CXCallUpdate()
             update.hasVideo = false
             update.supportsDTMF = true
      
        }

修改didActivate和didDeActive委托函数,如下所示

代码语言:javascript
运行
复制
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
       print("CallManager didActivate")
       RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession)
       RTCAudioSession.sharedInstance().isAudioEnabled = true
      // self.callDelegate?.callIsAnswered()
    
 
   }

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

在Webrtc处理程序类中,配置媒体发送者和音频

代码语言:javascript
运行
复制
private func createPeerConnection(webRTCCallbacks:PluginHandleWebRTCCallbacksDelegate) {
   
        let rtcConfig =  RTCConfiguration.init()
        rtcConfig.iceServers = server.iceServers
        rtcConfig.bundlePolicy = RTCBundlePolicy.maxBundle
        rtcConfig.rtcpMuxPolicy = RTCRtcpMuxPolicy.require
        rtcConfig.continualGatheringPolicy = .gatherContinually
        rtcConfig.sdpSemantics = .planB
        
        let constraints = RTCMediaConstraints(mandatoryConstraints: nil,
                                                 optionalConstraints: ["DtlsSrtpKeyAgreement":kRTCMediaConstraintsValueTrue])
           
        pc = sessionFactory.peerConnection(with: rtcConfig, constraints: constraints, delegate: nil)
        self.createMediaSenders()
        self.configureAudioSession()
        
   
        
      if webRTCCallbacks.getJsep() != nil{
        handleRemoteJsep(webrtcCallbacks: webRTCCallbacks)
        }
      
    }

mediaSenders;

代码语言:javascript
运行
复制
private func createMediaSenders() {
        let streamId = "stream"
        
        // Audio
        let audioTrack = self.createAudioTrack()
        self.pc.add(audioTrack, streamIds: [streamId])
        
        // Video
      /*  let videoTrack = self.createVideoTrack()
        self.localVideoTrack = videoTrack
        self.peerConnection.add(videoTrack, streamIds: [streamId])
        self.remoteVideoTrack = self.peerConnection.transceivers.first { $0.mediaType == .video }?.receiver.track as? RTCVideoTrack
        
        // Data
        if let dataChannel = createDataChannel() {
            dataChannel.delegate = self
            self.localDataChannel = dataChannel
        }*/
    }

  private func createAudioTrack() -> RTCAudioTrack {
        let audioConstrains = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: nil)
        let audioSource = sessionFactory.audioSource(with: audioConstrains)
        let audioTrack = sessionFactory.audioTrack(with: audioSource, trackId: "audio0")
        return audioTrack
    }

audioSession;

代码语言:javascript
运行
复制
private func configureAudioSession() {
        self.rtcAudioSession.lockForConfiguration()
        do {
            try self.rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord.rawValue)
            try self.rtcAudioSession.setMode(AVAudioSession.Mode.voiceChat.rawValue)
        } catch let error {
            debugPrint("Error changeing AVAudioSession category: \(error)")
        }
        self.rtcAudioSession.unlockForConfiguration()
    }

请考虑这一点,因为我使用回调和委托,代码包括委托和回调块。您可以相应地忽略它们!!

作为参考,您还可以在此链接上查看该示例

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57113297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档