CallKit:使用WebRTC时无声音

Rak*_*uyo 5 audio objective-c ios webrtc callkit

我们的项目使用WebRTC进行VOIP呼叫,并且在访问CallKit框架之前运行良好。但是当我尝试访问CallKit框架时,有一种情况,双方都听不到对方的讲话。当我删除CallKit时,一切恢复正常。

CallKit的应答按钮与项目中的原始应答按钮具有相同的功能。

而令我惊讶的是,没有必要听不到声音。有时一切正常,但有时会出现问题。好吧,出现问题的可能性更大。

我发现以下流程图,我怀疑问题出在函数调用的顺序上。但是我不知道WebRTC如何与图中的功能相对应。
在此处输入图片说明

另外,我很好奇套接字不稳定是否会导致CallKit框架异常工作

请原谅我英语不好,但是这个问题困扰了我好几天,我不知道到底是哪里出了问题,是不是和CallKit框架在哪里冲突?

希望你能帮助我,非常感谢!

小智 9

以正确的方式连接 webrtc 和 callkit 需要做几个步骤:首先,您必须使用 RTCAudioTrack 并添加 RTCAudioSession 来处理音频。旧的旧版 RTCAudioSession 直接添加到 RTCPeerConnection 中有效,但它不是首选的方法。第二件事是使用manualAudio。当应用程序启动时,您应该更改 RTCAudioSession 上的 useManualAudio 标志:

RTCAudioSession.sharedSession().useManualAudio = true
Run Code Online (Sandbox Code Playgroud)

这使您可以推迟音频,直到 CallKit 通知音频会话已激活,因此在 ProviderDelegate 中,您应该实现以下方法:

(void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession
RTCAudioSession.sharedSession().didActivecated(audioSession)
RTCAudioSession.sharedSession().isAudioEnabled = true
Run Code Online (Sandbox Code Playgroud)

对于第二个音频委托方法,不要忘记添加:

(void)provider:(CXProvider *)provider didDeactivateAudioSession:(AVAudioSession *)audioSession
RTCAudioSession.sharedSession().didDeactivecated(audioSession)
RTCAudioSession.sharedSession().isAudioEnabled = false
Run Code Online (Sandbox Code Playgroud)


Pra*_*ypa 5

苹果建议我们等到连接建立后再执行performAnswerAction。下面是源码

Apple 对 Call Kit 文档的建议

如果呼叫的接收者在应用程序与您的服务器建立连接之前应答,请不要立即执行发送到委托的provider:performAnswerCallAction:方法的CXAnswerCallAction对象。相反,请等到建立连接后再实现该对象。当它等待您的应用程序满足请求时,来电界面会让用户知道呼叫正在连接,但尚未准备好。

因此,我们需要等待一两秒,然后才能执行PerformAnswerCallAction中的操作


Rak*_*uyo 3

最后我解决了这个问题,但是我还是不明白为什么能解决。下面是我的解决方案:

首先我将“fulfill”的调用延迟了1秒(注意这个时间不能小于1秒

- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {

if (self.delegate && [self.delegate respondsToSelector:@selector(callKitManager:refreshCurrentCallStatus:)]) {
    [self.delegate callKitManager:self refreshCurrentCallStatus:EUCCallKitStatusAnswerAccept];
}

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [action fulfill];
});}
Run Code Online (Sandbox Code Playgroud)

其次,我还将我的网络请求调用延迟了一秒(这里比前一秒长

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  [self.peerConnection offerForConstraints:[self offerConstraintsRestartIce:NO] completionHandler:^(RTCSessionDescription * _Nullable sdp, NSError * _Nullable error) {

  [self peerConnection:self.peerConnection didCreateSessionDescription:sdp error:error];
        }];
Run Code Online (Sandbox Code Playgroud)

});

这样,我的问题就解决了。

如果你知道为什么这样可以解决这个问题,请评论我,谢谢!