// // VideoTabPopView.m // tongxin // // Created by ecell on 2023/5/5. // Copyright © 2023 xTT. All rights reserved. // #import "VideoTabPopView.h" #import "User.h" #import #import "AgoraConfigModel.h" #import "JuphoonModel.h" #import "BairuiModel.h" #import "TihuModel.h" #import "VideoUserModel.h" #import "CallViewController.h" #import "JCManager.h" #import "BRManager.h" #import "TihuManager.h" #import @interface VideoTabPopView () @property (nonatomic ,strong) NSMutableArray *btnsArr; @property (nonatomic ,strong) NSMutableArray *labelsArr; @property (nonatomic ,weak) UIView *bgView; /** 设备 支持的视频类型 0 不支持 1 声网 2 环信 4 菊风 5 佰锐 */ @property (assign, nonatomic) int video_type; /** 声网配置model */ @property (strong, nonatomic) AgoraConfigModel *agoraModel; /** 菊风配置model */ @property (strong, nonatomic) JuphoonModel *jhModel; /** 佰锐配置model */ @property (strong, nonatomic) BairuiModel *brModel; /** 鹈鹕配置model */ @property (strong, nonatomic) TihuModel *tihuModel; /** 选中的家庭成员数组 */ @property (strong, nonatomic) NSMutableArray *checked_video_list; /** 未选中的家庭成员数组 */ @property (strong, nonatomic) NSMutableArray *unchecked_video_list; @property (assign, nonatomic) int callTimes; @property (assign, nonatomic) BOOL isCancelTimer; @property (strong, nonatomic) NSString *dwUserStr; @end @implementation VideoTabPopView + (instancetype)sharedManager{ static dispatch_once_t onceToken; static VideoTabPopView *instance; dispatch_once(&onceToken, ^{ instance = [[VideoTabPopView alloc] init]; }); return instance; } -(instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.frame = [UIScreen mainScreen].bounds; self.backgroundColor = RGBA(0, 0, 0, 0.4); UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGuestures:)]; [self addGestureRecognizer:tapGesture]; [self subView]; } return self; } - (void)subView { WEAKSELF UIView *bgView = [UICommon ui_view:CGRectMake(0, ScreenHeight, ScreenWidth, 368) backgroundColor:KKWhiteColorColor cornerRadius:0 borderWidth:0 borderColor:KKWhiteColorColor]; self.bgView = bgView; [UICommon ui_uiViewFillet:bgView.bounds Viewdirection:PYUIdirectionTop toView:bgView sizeMake:17]; [self addSubview:bgView]; UIImageView *topImg = [UICommon ui_imageView:CGRectZero fileName:@"video_popView_topbg"]; [bgView addSubview:topImg]; [topImg mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(bgView); make.top.equalTo(bgView); make.height.mas_equalTo(Adapted(topImg.image.size.height)); }]; UIButton *phoneBtn = [UICommon ui_buttonSimple:CGRectZero font:FontADA_(14) normalColor:RGB(20, 20, 20) normalText:@"拨打电话" click:^(id x) { if (self.deviceModel.phone == 0) { LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:@"未设置设备号码,是否设置?" message:nil style:LGAlertViewStyleAlert buttonTitles:@[@"设置"] cancelButtonTitle:@"取消" destructiveButtonTitle:nil actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) { [weakSelf dismiss]; UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; UINavigationController *deviceVC = [sb instantiateViewControllerWithIdentifier:@"EditDeviceViewController"]; deviceVC.hidesBottomBarWhenPushed = YES; [[UICommon currentVC] setValue:@(NO) forKey:@"isAdd"]; [[UICommon currentVC].navigationController pushViewController:deviceVC animated:YES]; } cancelHandler:nil destructiveHandler:nil]; [alertView showAnimated:YES completionHandler:nil]; }else{ NSString * string = [[NSMutableString alloc] initWithFormat:@"tel:%@",self.deviceModel.phone]; if(self.deviceModel.phone.length == 11){ string = [NSString stringWithFormat:@"tel:+86-%@", self.deviceModel.phone]; } if(CurrentSystemVersion.doubleValue > 10){ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:string] options:@{} completionHandler:nil]; }else{ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:string]]; } } }]; phoneBtn.size = CGSizeMake(88, 120); [phoneBtn setImage:ImageName_(@"popView_callPhone_icon") forState:0]; [bgView addSubview:phoneBtn]; [phoneBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(bgView.mas_centerX).inset(49); make.bottom.equalTo(bgView.mas_bottom).inset(80); make.size.mas_equalTo(CGSizeMake(88, 120)); }]; UIButton *videoBtn = [UICommon ui_buttonSimple:CGRectZero font:FontADA_(14) normalColor:RGB(20, 20, 20) normalText:@"视频通话" click:^(id x) { [weakSelf monitorDevice]; }]; videoBtn.size = CGSizeMake(88, 120); [videoBtn setImage:ImageName_(@"popView_callVideo_icon") forState:0]; [bgView addSubview:videoBtn]; [videoBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(bgView.mas_centerX).offset(49); make.top.equalTo(phoneBtn.mas_top); make.size.mas_equalTo(CGSizeMake(88, 120)); }]; [UICommon setTitleAndImage:videoBtn :1.1]; [UICommon setTitleAndImage:phoneBtn :1.1]; } -(void)viewWillAppears { NSString * valueStr = [UserDefaults valueForKey:VideoTimeAndIDAndWHRecordKey]; NSArray *strArr = [valueStr componentsSeparatedByString:@"&"]; if(valueStr && strArr.count == 5){ //上传视频时间 NSMutableDictionary *dic = [NSMutableDictionary dictionary]; int durationTime = [strArr[0] intValue]; int wait_duration = [strArr[4] intValue]; if(durationTime >= wait_duration){ durationTime = durationTime - wait_duration; }else{ durationTime = 0; } [dic setValue:@(durationTime) forKey:@"duration"];//减去等待时间 [dic setValue:strArr[1] forKey:@"video_id"]; [dic setValue:@([strArr[2] intValue]) forKey:@"distinguishability_width"]; [dic setValue:@([strArr[3] intValue]) forKey:@"distinguishability_heiger"]; [dic setValue:@(wait_duration) forKey:@"wait_duration"]; [cUser postVideoCallTimeParame:[dic copy] deviceModel:self.deviceModel success:^(id responseObject) { xLog(@"上传视频时间成功"); //MARK: 上传完视频时间后删除存储的 Key [UserDefaults removeObjectForKey:VideoTimeAndIDAndWHRecordKey]; //[self loadData]; } failure:^{ xLog(@"上传视频时间失败"); }]; }else{ //[self loadData]; } } -(void)loadData { self.video_type = cUser.cDevice.support_video.intValue; WEAKSELF if(_video_type == 0) return; //MARK: 获取设备uuid成员列表 [cUser.cDevice getVideoUserListSuccess:^(id _Nonnull responseObject) { [weakSelf.checked_video_list removeAllObjects]; if([responseObject[@"checked_video_list"] isKindOfClass:[NSArray class]]){ for (NSDictionary *item in responseObject[@"checked_video_list"]) { VideoUserModel *model = [VideoUserModel new]; [model mj_setKeyValues:item]; [weakSelf.checked_video_list addObject:model]; } } [weakSelf.unchecked_video_list removeAllObjects]; if([responseObject[@"unchecked_video_list"] isKindOfClass:[NSArray class]]){ for (NSDictionary *item in responseObject[@"unchecked_video_list"]) { VideoUserModel *model = [VideoUserModel new]; [model mj_setKeyValues:item]; [weakSelf.unchecked_video_list addObject:model]; } } } failure:^{ }]; } - (void)subBtns { for (UIButton *btn in self.btnsArr) { [btn removeFromSuperview]; } for (UILabel *label in self.labelsArr) { [label removeFromSuperview]; } self.btnsArr = [NSMutableArray new]; self.labelsArr = [NSMutableArray new]; CGFloat beginX = ScreenWidth/2- (cUser.myDevices.count*48+20*(cUser.myDevices.count-1))/2; for (NSInteger i = 0; i < cUser.myDevices.count; i++) { Device *dev = cUser.myDevices[i]; UIButton *deviceBtn = [UICommon ui_buttonSimple:CGRectZero font:FontADA_(0) normalColor:KKGrey102 normalText:@"" click:^(UIButton *btn) { for (UIButton *butt in self.btnsArr) { butt.layer.borderWidth = butt.tag == btn.tag ? 4 : 0; if (btn.tag == butt.tag) { self.deviceModel = cUser.myDevices[btn.tag]; butt.frame = CGRectMake(butt.x-8, 28, 64, 64); } else butt.frame = CGRectMake(beginX+butt.tag*(48+20), 36, 48, 48); butt.layer.borderColor = KKWhiteColorColor.CGColor; butt.layer.cornerRadius = butt.size.height/2; butt.layer.masksToBounds = YES; } for (UILabel *label in self.labelsArr) { label.font = label.tag == btn.tag ? FontBold_(14) : Font_(14); } }]; [deviceBtn sd_setImageWithURL:[NSURL URLWithString:dev.avator] forState:0 placeholderImage:[myHelper getImageWithName:@"默认用户头像"]]; deviceBtn.frame = CGRectMake(beginX+i*(48+20), 36, 48, 48); deviceBtn.tag = i; [self.bgView addSubview:deviceBtn]; UILabel *nameLabel = [UICommon ui_label:CGRectZero lines:1 align:NSTextAlignmentCenter font:Font_(14) textColor:KKTextBlackColor51 text:dev.name Radius:0]; nameLabel.tag = i; [self.bgView addSubview:nameLabel]; [nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(deviceBtn); make.top.equalTo(self.bgView).offset(92); }]; [self.btnsArr addObject:deviceBtn]; [self.labelsArr addObject:nameLabel]; if([dev.imei isEqualToString:cUser.cDevice.imei]) { self.deviceModel = cUser.cDevice; nameLabel.font = FontBold_(14); deviceBtn.layer.borderWidth = 4; deviceBtn.layer.borderColor = KKWhiteColorColor.CGColor; deviceBtn.frame = CGRectMake(deviceBtn.x-8, deviceBtn.y-8, 64, 64); } deviceBtn.layer.cornerRadius = deviceBtn.size.height/2; deviceBtn.layer.masksToBounds = YES; } } - (void)showView { //[UICommon currentVC].tabBarController.tabBar.hidden = YES; //[self loadData]; [self subBtns]; [[UIApplication sharedApplication].delegate.window addSubview:self]; [UIView animateWithDuration:0.25f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{ CGRect frame = self.bgView.frame; frame.origin.y = frame.origin.y - frame.size.height; self.bgView.frame = frame; }completion:^(BOOL finished) { // self.backgroundColor = RGBA(0, 0, 0, 0.2); }]; } - (void)dismiss { [UIView animateWithDuration:0.25f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{ CGRect frame = self.bgView.frame; frame.origin.y = frame.origin.y + frame.size.height; self.bgView.frame = frame; }completion:^(BOOL finished) { //[UICommon currentVC].tabBarController.tabBar.hidden = NO; self.hidden = YES; [self removeFromSuperview]; }]; } - (void)handleGuestures:(UITapGestureRecognizer *)sender { CGPoint point = [sender locationInView:self.bgView]; if(![self.bgView.layer containsPoint:point]) { [self dismiss]; return; } } - (void)monitorDevice { WEAKSELF JLAuthorizationManager *jlManager = [JLAuthorizationManager defaultManager]; [jlManager JL_requestAuthorizationWithAuthorizationType:JLAuthorizationTypeAudio authorizedHandler:^{ [weakSelf selectCallTypeFunction:0]; // [weakSelf setDwUserStr:@"video"]; } unAuthorizedHandler:^{ LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:[NSString stringWithFormat:@"请在iPhone的\"设置-隐私-麦克风\"选项中,允许%@访问你的麦克风",APPName] message:nil style:LGAlertViewStyleAlert buttonTitles:@[@"确定"] cancelButtonTitle:@"" destructiveButtonTitle:nil actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) { // [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; } cancelHandler:^(LGAlertView *alertView) { } destructiveHandler:nil]; [alertView showAnimated:YES completionHandler:nil]; }]; [jlManager JL_requestAuthorizationWithAuthorizationType:JLAuthorizationTypeVideo authorizedHandler:nil unAuthorizedHandler:^{ LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:[NSString stringWithFormat:@"请在iPhone的\"设置-隐私-相机\"选项中,允许%@访问你的相机",APPName] message:nil style:LGAlertViewStyleAlert buttonTitles:@[@"确定"] cancelButtonTitle:@"" destructiveButtonTitle:nil actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) { } cancelHandler:^(LGAlertView *alertView) { } destructiveHandler:nil]; [alertView showAnimated:YES completionHandler:nil]; }]; } /// 选择拨打的是什么类型 0: 视频 1:语音 /// @param type 0: 视频 1:语音 - (void)selectCallTypeFunction:(int)type { [self dismiss]; WEAKSELF [cUser getVideoAccoutCallType:type deviceModel:self.deviceModel Success:^(id responseObject) { if([responseObject[@"deviceVideoType"] isEqualToString:@"SW"]){ //声网 weakSelf.agoraModel = [AgoraConfigModel mj_objectWithKeyValues:responseObject]; weakSelf.agoraModel.call_type = type; //调起 SW [weakSelf SWJoinChannel]; } else if ([responseObject[@"deviceVideoType"] isEqualToString:@"BR"]) { weakSelf.brModel = [BairuiModel mj_objectWithKeyValues:responseObject]; weakSelf.brModel.call_type = type; [weakSelf BR_LoginAndCallVideo]; } else if ([responseObject[@"deviceVideoType"] isEqualToString:@"TH"]) { weakSelf.tihuModel = [TihuModel mj_objectWithKeyValues:responseObject]; weakSelf.tihuModel.call_type = type; [weakSelf TH_LoginAndCallVideo]; } else { //菊风 (默认) weakSelf.jhModel = [JuphoonModel mj_objectWithKeyValues:responseObject]; //[weakSelf.jhModel setValuesForKeysWithDictionary:responseObject]; weakSelf.jhModel.call_type = type; //调起 Juphoon [weakSelf JH_LoginAndCallVideo]; } [UICommon currentVC].tabBarController.tabBar.hidden = YES; } failure:^{ [UICommon currentVC].tabBarController.tabBar.hidden = YES; }]; } /// 声网 - (void)SWJoinChannel { UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; CallViewController *callVC = [sb instantiateViewControllerWithIdentifier:@"CallViewController"]; callVC.appid = self.agoraModel.appid; // callVC.token = self.agoraModel.token; callVC.video_id = self.agoraModel.video_id; callVC.device = self.deviceModel; callVC.channelID = self.agoraModel.channelID; callVC.uid = self.agoraModel.app_uid; callVC.device_uid = self.agoraModel.device_uid; callVC.videoSize = CGSizeMake(self.agoraModel.distinguishability_width, self.agoraModel.distinguishability_heiger) ; //AgoraVideoDimension640x360 callVC.limit_time = self.agoraModel.limit_time; callVC.wait_time = self.agoraModel.wait_time; callVC.modalPresentationStyle = UIModalPresentationFullScreen; [[UICommon currentVC] presentViewController:callVC animated:NO completion:nil]; } #pragma mark --- Juphoon 拨打视频通话 --- -(void)JH_LoginAndCallVideo { //需要去注册 if(![JCManager shared].client) { [[JCManager shared] initializeWithAPPKey:self.jhModel.appkey]; [[JCManager shared].client setServerAddress:@"http:cn.router.justalkcloud.com:8080"]; [[JCManager shared].client login:self.jhModel.username password:@"test" loginParam:nil]; } else { [[JCManager shared] _stopCallTimeoutTimer]; [[JCManager shared] _stopVideoLimitTimeoutTimer]; } [JCManager shared].gMianVC = [UICommon currentVC]; [JCManager shared].model = self.jhModel; [[JCManager shared] callVideoWithUserName]; //调起页面 UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; JuPhoonCallViewController *callVC = [sb instantiateViewControllerWithIdentifier:@"JuPhoonCallViewController"]; [JCManager shared].callViewController = callVC; callVC.video_id = self.jhModel.video_id; callVC.distinguishability_width = self.jhModel.distinguishability_width; callVC.distinguishability_heiger = self.jhModel.distinguishability_heiger; xLog(@"JF通话的限制时长:%d", self.jhModel.limit_time); callVC.device = self.deviceModel; callVC.isReceiveCall = NO; //主叫 callVC.statusLabel.text = @"正在发起通话请求..."; if (self.jhModel.call_type == 0) { [callVC openLocationCarmeraViewWithFullSScreen:YES]; } //清除原本定时器配置 // [[JCManager shared] _stopCallTimeoutTimer]; // [[JCManager shared] _stopVideoLimitTimeoutTimer]; callVC.modalPresentationStyle = UIModalPresentationFullScreen; [[UICommon currentVC].navigationController presentViewController:callVC animated:YES completion:nil]; } #pragma mark --- Bairui 拨打视频通话 --- - (void)BR_LoginAndCallVideo { if (![[BRManager shared] isUserLogin]) { [[BRManager shared] login:cUser.bairui_id nick: cUser.name]; } [BRManager shared].brModel = self.brModel; [BRManager shared].isReceiveCall = NO; [BRManager shared].video_id = self.brModel.video_id; [BRManager shared].device = self.deviceModel; [BRManager shared].callType = self.brModel.call_type; WEAKSELF [[BRManager shared] showCallDialog:cUser userId:[_brModel.device_username intValue] callback:^{ [weakSelf cancelTimer]; }]; _callTimes = 0; BOOL online = [[BRManager shared] queryRemoteUserOnline:[_brModel.device_username intValue]]; if (online) { [AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REQUEST :[_brModel.device_username intValue] :0 :0 :0 :_dwUserStr]; NSLog(@"callType=========1=====> %@", _dwUserStr); } else { [self performSelector:@selector(reCall) withObject:nil afterDelay:3]; } } - (void)cancelTimer { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(reCall) object:nil]; } - (void)reCall { _callTimes++; if (_callTimes > 3) { [AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REQUEST :[_brModel.device_username intValue] :0 :0 :0 :_dwUserStr]; NSLog(@"callType=========3=====> %@", _dwUserStr); return; } BOOL online = [[BRManager shared] queryRemoteUserOnline:[_brModel.device_username intValue]]; if (online) { [AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REQUEST :[_brModel.device_username intValue] :0 :0 :0 :_dwUserStr]; NSLog(@"callType=========2=====> %@", _dwUserStr); } else { [self performSelector:@selector(reCall) withObject:nil afterDelay:3]; } NSLog(@"查询用户在线次数:%d", _callTimes); } #pragma mark --- Tihu 拨打视频通话 --- - (void)TH_LoginAndCallVideo { // [MoonChatPlatform startCalling:@"321" phoneType:MoonChatVideo callBlock:^(CallStatus status) { // NSLog(@"==========CallStatus=%zd", status); // }]; // // return; if (![[TihuManager shared] isUserLogin]) { [[TihuManager shared] login:cUser.openid pwd:@"123456"]; } [TihuManager shared].thModel = self.tihuModel; [TihuManager shared].isReceiveCall = NO; [TihuManager shared].video_id = self.tihuModel.video_id; [TihuManager shared].device = self.deviceModel; [TihuManager shared].callType = self.tihuModel.call_type; WEAKSELF [[TihuManager shared] showCallDialog:self.deviceModel userId:_tihuModel.device_username callback:^{ [weakSelf cancelTimer2]; }]; _callTimes = 0; _isCancelTimer = NO; [[TihuManager shared] queryRemoteUserOnline:self.deviceModel.imei callback:^(BOOL online) { if (online) { [MoonChatPlatform startCalling:self.deviceModel.imei phoneType:MoonChatVideo callBlock:^(CallStatus status) { NSLog(@"========CallStatus=%zd", status); }]; } else { if (!_isCancelTimer) { [weakSelf performSelector:@selector(reCall2) withObject:nil afterDelay:3]; } } NSLog(@"查询用户在线:%d", online); }]; } - (void)cancelTimer2 { _isCancelTimer = YES; [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(reCall2) object:nil]; } - (void)reCall2 { _callTimes++; if (_callTimes > 3) { [MoonChatPlatform startCalling:self.deviceModel.imei phoneType:MoonChatVideo callBlock:^(CallStatus status) { NSLog(@"=========CallStatus=%zd", status); }]; return; } WEAKSELF [[TihuManager shared] queryRemoteUserOnline:self.deviceModel.imei callback:^(BOOL online) { if (online) { [MoonChatPlatform startCalling:self.deviceModel.imei phoneType:MoonChatVideo callBlock:^(CallStatus status) { NSLog(@"========CallStatus=%zd", status); }]; } else { if (!_isCancelTimer) { [weakSelf performSelector:@selector(reCall2) withObject:nil afterDelay:3]; } } NSLog(@"查询用户在线:%d", online); }]; NSLog(@"查询用户在线次数:%d", _callTimes); } -(AgoraConfigModel *)agoraModel{ if(!_agoraModel){ _agoraModel = [AgoraConfigModel new]; } return _agoraModel; } -(JuphoonModel *)jhModel{ if(!_jhModel){ _jhModel = [JuphoonModel new]; } return _jhModel; } -(BairuiModel *)brModel{ if(!_brModel){ _brModel = [BairuiModel new]; } return _brModel; } -(TihuModel *)tihuModel{ if(!_tihuModel){ _tihuModel = [TihuModel new]; } return _tihuModel; } -(NSMutableArray *)checked_video_list{ if(!_checked_video_list){ _checked_video_list = [NSMutableArray array]; } return _checked_video_list; } -(NSMutableArray *)unchecked_video_list{ if(!_unchecked_video_list){ _unchecked_video_list = [NSMutableArray array]; } return _unchecked_video_list; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ @end