Я пытаюсь принять входящий SIP-видеовызов с помощью PJSIP с использованием CallKit.Если я не использую CallKit, я могу принять вызов, и видео отображается правильно в представлении контроллера основного вида.Но проблема в том, что когда я внедряю CallKit, при входящем звонке я показываю CallKit UI для звонка, и когда я принимаю звонок, он фактически подключается, но видео не начинает работать.Единственное, что я вижу, это зеленый фон в поле зрения.Я подозреваю, потому что я принимаю вызов в главном потоке из AppDelegate, он не может показать видео.
У меня есть объективная функция обратного вызова C для входящего вызова, и оттуда я вызываю другую функцию, которая, в свою очередь, вызываетфункция в AppDelegate для обработки работы пользовательского интерфейса CallKit.
Это моя функция обратного вызова для входящего вызова
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);
, который успешно принят, но не запускает показ видео в приложении.Я думаю, что это должно сделать что-то нить.Что я могу сделать, чтобы решить эту проблему?