我正在尝试使用CallKit通过PJSIP接受传入的SIP视频呼叫。如果我不实现CallKit,则可以接受呼叫,并且视频可以在主视图控制器的视图中正确显示。但是问题是当我实现CallKit时,在传入呼叫中显示呼叫的CallKit UI,并且当我接受呼叫时,呼叫实际上已连接但视频无法开始工作。我唯一看到的是视图中的绿色背景。我怀疑是因为我正在接受来自AppDelegate的主线程中的调用,所以无法显示视频。
我有用于传入呼叫的目标C回调函数,然后从那里调用另一个函数,该函数又调用AppDelegate中的函数来处理CallKit UI工作。
这是我的来电回叫功能
static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
pjsip_rx_data *rdata) {
pjsua_call_info ci;
PJ_UNUSED_ARG(acc_id);
PJ_UNUSED_ARG(rdata);
pjsua_call_get_info(call_id, &ci);
PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!",
(int)ci.remote_info.slen,
ci.remote_info.ptr));
pjsua_call_setting opt;
pjsua_call_setting_default(&opt);
opt.vid_cnt = 1;
opt.aud_cnt = 1;
#if PJSUA_HAS_VIDEO
printf("video is there \n");
#endif
/* Automatically answer incoming calls with 200/OK */
//pjsua_call_answer2(call_id, &opt, 200, NULL, NULL);
dispatch_async(dispatch_get_main_queue(), ^{
AppDelegate *application = (AppDelegate *)[[UIApplication sharedApplication] delegate];
application.call_id = call_id;
CallManager *callMng = [[CallManager alloc] init];
[callMng acceptCall];
});
}
CallManager代码如下所示。除了将函数传递给AppDelegate
之外,它目前什么也不做#import "CallManager.h"
@implementation CallManager
- (void)acceptCall {
AppDelegate *application = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[application onIncomingCall];
}
@end
我的AppDelegate看起来像这样:
#import "my_app.h"
#import "AppDelegate.h"
@interface AppDelegate () <CXProviderDelegate>
@end
@implementation AppDelegate
- (void) onIncomingCall {
NSLog(@"anuran hello world");
CXProviderConfiguration *configuration = [[CXProviderConfiguration alloc] initWithLocalizedName:@"Anuran SIP Phone"];
configuration.supportsVideo = YES;
configuration.maximumCallsPerCallGroup = 1;
configuration.supportedHandleTypes = [NSSet setWithObject:@(CXHandleTypePhoneNumber)];
_provider = [[CXProvider alloc] initWithConfiguration:configuration];
[_provider setDelegate:self queue:nil];
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.hasVideo = YES;
update.supportsDTMF = YES;
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:@"Anuran The God"];
self.current_call_uuid = [[NSUUID alloc] init];
[_provider reportNewIncomingCallWithUUID:self.current_call_uuid update:update completion:^(NSError * _Nullable error) {
}];
}
- (void) onCallEnd {
CXEndCallAction *endaction = [[CXEndCallAction alloc] initWithCallUUID:self.current_call_uuid];
CXCallController *controller = [[CXCallController alloc] init];
CXTransaction *transcation = [[CXTransaction alloc] init];
[transcation addAction:endaction];
[controller requestTransaction:transcation completion:^(NSError * _Nullable error) {
if(error != NULL) {
NSLog(@"anuran end call error %@",error.localizedDescription);
}else {
NSLog(@"anuran end call success");
}
}];
}
- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
NSLog(@"anuran performAnswerCallAction");
pjsua_call_setting opt;
pjsua_call_setting_default(&opt);
opt.vid_cnt = 1;
opt.aud_cnt = 1;
NSLog(@"anuran performAnswerCallAction callId %d",[self call_id]);
pj_status_t status = pjsua_call_answer2([self call_id], &opt, 200, NULL, NULL);
if(status == PJ_SUCCESS) {
NSLog(@"anuran call picked up from delegate");
[action fulfill];
}else {
NSLog(@"anuran call could not be picked up from delegate");
[action fail];
}
}
- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action {
[action fulfillWithDateEnded:[[NSDate alloc] init]];
pjsua_call_answer([self call_id], 486, NULL, NULL);
}
- (void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession {
NSLog(@"anuran didActivateAudioSession");
//pjsua_set_snd_dev(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV);
}
... rest of the part irrelevant to PJSIP
如您在函数- (void) onIncomingCall
中所见,我称
[_provider reportNewIncomingCallWithUUID:self.current_call_uuid update:update completion:^(NSError * _Nullable error) {
}];
这将触发委托函数,然后我最终实际上通过
接受了调用pj_status_t status = pjsua_call_answer2([self call_id], &opt, 200, NULL, NULL);
呼叫被成功接受,但不会启动在应用程序中显示的视频。我认为它必须做一些线程化。我该怎么做才能解决此问题?