// // VideoChatViewController.m // LekangGuard // // Created by ecell on 2023/1/12. // #import "VideoChatViewController.h" #import "VideoMemberCollectionViewCell.h" #import "CallViewController.h" #import "JCManager.h" #import "BRManager.h" #import "TihuManager.h" @interface VideoChatViewController () @property (nonatomic, assign) WSLWaterFlowLayoutStyle flowLayoutStyle; @property (nonatomic ,strong) UICollectionView *menuCollectionView; @property (nonatomic ,strong) UIView *headerView; @property (nonatomic ,strong) DeviceVideoConfigModel *configModel; @property (assign, nonatomic) int callTimes; @property (assign, nonatomic) BOOL isCancelTimer; @end @interface TestUILabel : UILabel @end @implementation TestUILabel - (void)drawTextInRect:(CGRect)rect { //文字距离上下左右边框都有10单位的间隔 CGRect newRect = CGRectMake(rect.origin.x + 10, rect.origin.y + 10, rect.size.width - 20, rect.size.height -20); [super drawTextInRect:newRect]; } @end @implementation VideoChatViewController - (void)viewDidLoad { [super viewDidLoad]; self.zx_navTitle = GJText(@"视频通话"); // Do any additional setup after loading the view. [self.view addSubview:self.headerView]; [self.headerView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self.view); make.top.equalTo(self.view).offset(iPhoneX_NavHeight); make.height.mas_equalTo(300); }]; [self GetQueryVideo]; UIButton *callBtn = [UICommon ui_buttonSimple:CGRectZero font:FontADA_(14) normalColor:KKWhiteColorColor normalText:GJText(@"视频通话") click:^(id x) { [self monitorDevice]; }]; callBtn.backgroundColor = KKMainColor; callBtn.layer.cornerRadius = 5; callBtn.layer.masksToBounds = YES; [self.view addSubview:callBtn]; [callBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self.view).inset(20); make.bottom.equalTo(self.view.mas_bottom).inset(iPhoneX_TabbarSafeBottomMargin > 0 ? iPhoneX_TabbarSafeBottomMargin : 30); make.height.mas_equalTo(Adapted(48)); }]; WSLWaterFlowLayout *FlowLayout = [[WSLWaterFlowLayout alloc] init]; FlowLayout.delegate = self; FlowLayout.flowLayoutStyle = self.flowLayoutStyle; _menuCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH-20, SCREEN_HEIGHT) collectionViewLayout:FlowLayout]; _menuCollectionView.backgroundColor = KKClearColor; _menuCollectionView.dataSource = self; _menuCollectionView.delegate = self; _menuCollectionView.showsVerticalScrollIndicator = NO; _menuCollectionView.alwaysBounceVertical = NO; _menuCollectionView.scrollEnabled = NO; if (@available(iOS 11.0, *)) _menuCollectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; [_menuCollectionView registerClass:VideoMemberCollectionViewCell.class forCellWithReuseIdentifier:NSStringFromClass(VideoMemberCollectionViewCell.class)]; [self.view addSubview:_menuCollectionView]; [_menuCollectionView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self.view); make.top.equalTo(self.headerView.mas_bottom); make.bottom.equalTo(callBtn.mas_top); }]; } #pragma mark - WSLWaterFlowLayoutDelegate //返回每个item大小 - (CGSize)waterFlowLayout:(WSLWaterFlowLayout *)waterFlowLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake((SCREEN_WIDTH-65)/5, (SCREEN_WIDTH)/5); } /** 头视图Size */ -(CGSize )waterFlowLayout:(WSLWaterFlowLayout *)waterFlowLayout sizeForHeaderViewInSection:(NSInteger)section { return CGSizeMake(SCREEN_WIDTH, 0); } /** 列数*/ -(CGFloat)columnCountInWaterFlowLayout:(WSLWaterFlowLayout *)waterFlowLayout { return 5; } /** 列间距*/ -(CGFloat)columnMarginInWaterFlowLayout:(WSLWaterFlowLayout *)waterFlowLayout { return 10; } /** 行间距*/ -(CGFloat)rowMarginInWaterFlowLayout:(WSLWaterFlowLayout *)waterFlowLayout { return 10; } /** 边缘之间的间距*/ -(UIEdgeInsets)edgeInsetInWaterFlowLayout:(WSLWaterFlowLayout *)waterFlowLayout { return UIEdgeInsetsMake(5, 10, 5, 10); } #pragma mark - UICollectionView数据源 //组个数 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } //组内成员个数 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.modelListArr.count; } //设置元素内容 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { VideoMemberCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass(VideoMemberCollectionViewCell.class) forIndexPath:indexPath]; cell.model = self.modelListArr[indexPath.row]; return cell; } -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { } - (UIView *)headerView { if (!_headerView) { _headerView = [UIView new]; _headerView.backgroundColor = KKClearColor; UIImageView *iconView = [UIImageView new]; iconView.layer.cornerRadius = 8; iconView.layer.masksToBounds = YES; if (APIManager.sharedManager.deviceModel.image.length <= 0) [iconView setImage:ImageName_(APIManager.sharedManager.deviceModel.sex == 2 ? @"icon_head_girl" : @"icon_head_boy")]; else [iconView sd_setImageWithURL:[NSURL URLWithString:APIManager.sharedManager.deviceModel.image] placeholderImage:ImageName_(@"")]; [_headerView addSubview:iconView]; [iconView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(_headerView); make.top.equalTo(_headerView).offset(Adapted(50)); make.width.height.mas_equalTo(Adapted(70)); }]; UILabel *nameLabel = [UICommon ui_label:CGRectZero lines:0 align:NSTextAlignmentLeft font:FontADA_(17) textColor:KKTextBlackColor text:@"" Radius:0]; nameLabel.text = APIManager.sharedManager.deviceModel.name; [_headerView addSubview:nameLabel]; [nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(_headerView); make.top.equalTo(iconView.mas_bottom).offset(5); }]; NSString *Labelstr = GJText(@"设备视频通话联系人管理(注:每次只能和一个联系人视频)"); CGRect rect = [UICommon GetTextWidth:Labelstr ViewHeight:SCREEN_WIDTH fontSize:Font_(13) type:@"h"]; UIView *bgView = [UIView new]; bgView.backgroundColor = RGB(248, 248, 248); [_headerView addSubview:bgView]; [bgView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(_headerView); make.bottom.equalTo(_headerView.mas_bottom); make.height.mas_equalTo(Adapted(rect.size.height+10)); }]; UILabel *titleLabel = [UICommon ui_label:CGRectZero lines:0 align:NSTextAlignmentLeft font:FontADA_(13) textColor:KKGrey121 text:Labelstr Radius:0]; [_headerView addSubview:titleLabel]; [titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(bgView).inset(15); make.centerY.equalTo(bgView); }]; } return _headerView; } #pragma mark 根据imei查询可视频通话成员 /// 根据imei查询可视频通话成员 - (void)GetQueryVideo { [UICommon MessageUpload:@"加载中"]; NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:APIManager.sharedManager.deviceModel.imei forKey:@"imei"]; [[[APIManager sharedManager] APGET:QueryVideo_URL parameters:parameters resultClass:nil] subscribeNext:^(NSArray *arr) { [UICommon HidenLoading]; if (ARRAYHASVALUE(arr)) { [arr enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { MemberModel *model = [MemberModel yy_modelWithJSON:obj]; [self.modelListArr addObject:model]; }]; [self.menuCollectionView reloadData]; } } error:^(NSError * _Nullable error) { NSDictionary *dic = error.userInfo; [UICommon MessageErrorText:dic[NSLocalizedDescriptionKey]]; }]; } #pragma mark 视频通话方法 /// 视频通话方法 - (void)monitorDevice { kWeakSelf(self) JLAuthorizationManager *jlManager = [JLAuthorizationManager defaultManager]; [jlManager JL_requestAuthorizationWithAuthorizationType:JLAuthorizationTypeMicrophone authorizedHandler:^{ [weakself videoActionFunction]; } unAuthorizedHandler:^{ EasyAlertView *alertV = [EasyAlertView alertViewWithTitle:GJText(@"请在iPhone的\"设置-隐私-麦克风\"选项中,允许智慧校园访问你的麦克风") subtitle:nil AlertViewType:AlertViewTypeSystemAlert config:nil]; [alertV addAlertItem:^EasyAlertItem *{ return [EasyAlertItem itemWithTitle:GJText(@"确定") type:AlertItemTypeSystemDefault callback:nil]; }]; [alertV showAlertView]; }]; [jlManager JL_requestAuthorizationWithAuthorizationType:JLAuthorizationTypeCamera authorizedHandler:nil unAuthorizedHandler:^{ EasyAlertView *alertV = [EasyAlertView alertViewWithTitle:GJText(@"请在iPhone的\"设置-隐私-相机\"选项中,允许智慧校园访问你的相机") subtitle:nil AlertViewType:AlertViewTypeSystemAlert config:nil]; [alertV addAlertItem:^EasyAlertItem *{ return [EasyAlertItem itemWithTitle:GJText(@"确定") type:AlertItemTypeSystemDefault callback:nil]; }]; [alertV showAlertView]; }]; } #pragma mark 主动请求视频通话返回配置参数 /// 主动请求视频通话返回配置参数 - (void)videoActionFunction { kWeakSelf(self) [UICommon MessageUpload:@"加载中"]; NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:@(0) forKey:@"callType"];/// 视频通话类型(0:视频,1:语音) [parameters setValue:APIManager.sharedManager.deviceModel.imei forKey:@"imei"]; [parameters setValue:@"APP" forKey:@"type"];/// 手表发起传:device,APP发起传:APP [[[APIManager sharedManager] APGET:UserQueryVideo_URL parameters:parameters resultClass:DeviceVideoConfigModel.class] subscribeNext:^(DeviceVideoConfigModel *model) { [UICommon HidenLoading]; weakself.configModel = model; [weakself callVideo:model]; } error:^(NSError * _Nullable error) { NSDictionary *dic = error.userInfo; [UICommon MessageErrorText:dic[NSLocalizedDescriptionKey]]; }]; } #pragma mark 拨打拨打视频电话 - (void)callVideo:(DeviceVideoConfigModel *)model { kWeakSelf(self) NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:@(0) forKey:@"callType"]; [parameters setValue:APIManager.sharedManager.deviceModel.imei forKey:@"imei"]; [[[APIManager sharedManager] APGET:VideoCall_URL parameters:parameters resultClass:nil] subscribeNext:^(id _Nullable x) { [UICommon HidenLoading]; if(model.videoType == 2) { //声网 [weakself SWJoinChannel]; } else if (model.videoType == 3) { /// 佰瑞 [weakself BR_LoginAndCallVideo]; } else if (model.videoType == 4) { /// 鹈鹕 [weakself TH_LoginAndCallVideo]; } else if (model.videoType == 1) { //菊风 (默认) [weakself JH_LoginAndCallVideo]; } } error:^(NSError * _Nullable error) { NSDictionary *dic = error.userInfo; [UICommon MessageErrorText:dic[NSLocalizedDescriptionKey]]; }]; } #pragma mark 声网 /// 调起声网 - (void)SWJoinChannel { UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; CallViewController *callVC = [sb instantiateViewControllerWithIdentifier:@"CallViewController"]; callVC.appid = self.configModel.appKey; // callVC.token = self.agoraModel.token; callVC.video_id = self.configModel.videoId; // callVC.channelID = self.agoraModel.channelID; callVC.uid = self.configModel.userId; // callVC.device_uid = self.configModel.device_uid; callVC.videoSize = CGSizeMake(self.configModel.width, self.configModel.height) ; //AgoraVideoDimension640x360 callVC.limit_time = self.configModel.allCallTime; callVC.wait_time = self.configModel.callInterval; callVC.modalPresentationStyle = UIModalPresentationFullScreen; [self presentViewController:callVC animated:NO completion:nil]; } #pragma mark 菊风 /// 调起菊风 - (void)JH_LoginAndCallVideo { //需要去注册 if(![JCManager shared].client) { [[JCManager shared] initializeWithAPPKey:self.configModel.appKey]; [[JCManager shared].client setServerAddress:@"http:cn.router.justalkcloud.com:8080"]; [[JCManager shared].client login:APIManager.sharedManager.loginModel.openid password:@"test" loginParam:nil]; } else { [[JCManager shared] _stopCallTimeoutTimer]; [[JCManager shared] _stopVideoLimitTimeoutTimer]; } [JCManager shared].gMianVC = self; //测试模拟 // self.jhModel.limit_time = DefineVideoLimitTime; // self.jhModel.wait_time = DefineCallWaitTime; [JCManager shared].model = self.configModel; [[JCManager shared] callVideoWithUserName]; //调起页面 UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; JuPhoonCallViewController *callVC = [sb instantiateViewControllerWithIdentifier:@"JuPhoonCallViewController"]; [JCManager shared].callViewController = callVC; callVC.video_id = self.configModel.videoId; callVC.distinguishability_width = self.configModel.width; callVC.distinguishability_heiger = self.configModel.height; callVC.device = APIManager.sharedManager.deviceModel; callVC.isReceiveCall = NO; //主叫 callVC.statusLabel.text = GJText(@"正在发起通话请求..."); [callVC openLocationCarmeraViewWithFullSScreen:YES]; // //清除原本定时器配置 callVC.modalPresentationStyle = UIModalPresentationFullScreen; [self.navigationController presentViewController:callVC animated:YES completion:nil]; } #pragma mark 佰瑞 /// 调起佰瑞 - (void)BR_LoginAndCallVideo { if (![[BRManager shared] isUserLogin]) { [[BRManager shared] initialize]; [BRManager shared].gMianVC = self; [[BRManager shared] login:self.configModel.deviceUserName nick:APIManager.sharedManager.deviceModel.name]; } [BRManager shared].brModel = self.configModel; [BRManager shared].isReceiveCall = NO; [BRManager shared].video_id = self.configModel.videoId; [BRManager shared].callType = 0; kWeakSelf(self) [[BRManager shared] showCallDialog:APIManager.sharedManager.deviceModel userId:[self.configModel.deviceUserName intValue] callback:^{ [weakself cancelTimer]; }]; _callTimes = 0; BOOL online = [[BRManager shared] queryRemoteUserOnline:[self.configModel.deviceUserName intValue]]; if (online) { [AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REQUEST :[self.configModel.deviceUserName intValue] :0 :0 :0 :@"video"]; } 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 :[self.configModel.deviceUserName intValue] :0 :0 :0 :@"video"]; return; } BOOL online = [[BRManager shared] queryRemoteUserOnline:[self.configModel.deviceUserName intValue]]; if (online) { [AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REQUEST :[self.configModel.deviceUserName intValue] :0 :0 :0 :@"video"]; } else { [self performSelector:@selector(reCall) withObject:nil afterDelay:3]; } NSLog(@"查询用户在线次数:%d", _callTimes); } #pragma mark 鹈鹕 /// 调起鹈鹕 - (void)TH_LoginAndCallVideo { if (![[TihuManager shared] isUserLogin]) { [[TihuManager shared] login:APIManager.sharedManager.loginModel.openid pwd:@"123456"]; } [TihuManager shared].thModel = self.configModel; [TihuManager shared].isReceiveCall = NO; [TihuManager shared].video_id = self.configModel.videoId; [TihuManager shared].callType = 0; kWeakSelf(self) [[TihuManager shared] showCallDialog:APIManager.sharedManager.deviceModel userId:self.configModel.deviceUserName callback:^{ [weakself cancelTimer2]; }]; _callTimes = 0; _isCancelTimer = NO; [[TihuManager shared] queryRemoteUserOnline:self.configModel.imei callback:^(BOOL online) { if (online) { [MoonChatPlatform startCalling:self.configModel.imei phoneType:MoonChatVideo callBlock:^(CallStatus status) { NSLog(@"========CallStatus=%zd", status); }]; } else { if (!self->_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.configModel.imei phoneType:MoonChatVideo callBlock:^(CallStatus status) { NSLog(@"=========CallStatus=%zd", status); }]; return; } kWeakSelf(self) [[TihuManager shared] queryRemoteUserOnline:self.configModel.imei callback:^(BOOL online) { if (online) { [MoonChatPlatform startCalling:self.configModel.imei phoneType:MoonChatVideo callBlock:^(CallStatus status) { NSLog(@"========CallStatus=%zd", status); }]; } else { if (!self->_isCancelTimer) { [weakself performSelector:@selector(reCall2) withObject:nil afterDelay:3]; } } NSLog(@"查询用户在线:%d", online); }]; NSLog(@"查询用户在线次数:%d", _callTimes); } /* #pragma mark - Navigation // In a storyboard-based application, you will often w ant to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end