在iOS中通过Callkit接受PJSIP视频通话时,视频未显示

时间:2019-07-11 12:23:39

标签: ios sip pjsip callkit

我正在尝试使用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);

呼叫被成功接受,但不会启动在应用程序中显示的视频。我认为它必须做一些线程化。我该怎么做才能解决此问题?

0 个答案:

没有答案