// // YBLiveVC.m // YBVideo // // Created by YB007 on 2019/11/29. // Copyright © 2019 cat. All rights reserved. // #import "YBLiveVC.h" #import #import #import #import #import #import #import "YBLivePreview.h" #import "YBLiveCtrlView.h" #import "YBShareView.h" #import "Utils.h" #import "YBSocketLive.h" #import "YBLiveEndView.h" #import "UserBulletWindow.h" #import "YBCenterVC.h" #import "adminLists.h" #import "huanxinsixinview.h" #import "JCHATConversationViewController.h" #import "MsgSysVC.h" #import "V8HorizontalPickerView.h" #import "MessageListModel.h" #import "TXBaseBeautyView.h" /******************** 美狐开始 ******************/ #import "MHMeiyanMenusView.h" #import #import #import "MHBeautyParams.h" /******************** 美狐结束 ******************/ #import "YBImRoomSmallView.h" #import "YBLiveRTCManager.h" #import "UpHotView.h" #import "UpHotOrderView.h" @interface YBLiveVC (){ BOOL isclosenetwork; //判断断网回后台 NSTimer *backGroundTimer; //检测后台时间(超过60秒执行断流操作) int backTime; //返回后台时间60s int _canBackTime; //正常60s---锁屏30s NSString *selectShareName; //选择分享的名称 NSString *liveClassStr; //直播分类 NSString *_hostUrl; //推流地址 NSString *_hostStream; //流 int _userlistRefreshTime; //用户列表刷新时间 NSTimer *_listTimer; //用户列表计时器 NSTimer *_liveTimer; //直播时长 NSTimer *_heartTimer; //点亮 UserBulletWindow *buttleView; //用户信息卡 huanxinsixinview *huanxinviews; //直播间私信 JCHATConversationViewController *chatsmall; MsgSysVC *sysView; int unRead; BOOL _isPreView; BOOL isLoadWebSprout; NSString *_liveTitle; BOOL _needScale; YBImRoomSmallView *_imListView; BOOL _isFrontCamera; NSString *uphotOrderId; } @property(nonatomic,strong)UIImageView *pkBgIV; @property (nonatomic,strong)CTCallCenter *callCenter; //@property(nonatomic,strong)TXLivePushConfig *txLivePushonfig; //@property(nonatomic,strong)TXLivePush *txLivePublisher; @property(nonatomic,strong)UIView *txPushPreview; //推流器预览视图 @property(nonatomic,strong)YBLivePreview *livePreview; //开播前预览界面 @property(nonatomic,strong)YBLiveCtrlView *liveCtrlView; //控制层 @property(nonatomic,strong)YBLiveEndView *liveEndView; //直播结束页面 @property(nonatomic,strong)NSDictionary *roomDic; @property (nonatomic, strong) UpHotView *hotView; /******************** 美狐开始 ******************/ @property(nonatomic,strong)UIButton *mhShadowBtn; @property(nonatomic,strong)MHMeiyanMenusView *menusView; @property(nonatomic,strong)MHBeautyManager *beautyManager; /******************** 美狐结束 ******************/ @property(nonatomic,strong)UpHotOrderView *uphotOrderView; @end @implementation YBLiveVC - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [IQKeyboardManager sharedManager].enable = NO; isLoadWebSprout = NO; [self requestJmsg]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [IQKeyboardManager sharedManager].enable = YES; } - (void)viewDidLoad { [super viewDidLoad]; _canBackTime = 60; uphotOrderId = @""; /* if (@available(iOS 13.0,*)) { _canBackTime = 28; } */ _liveTitle = @""; liveClassStr = @"-99999999"; _isFrontCamera = YES; self.naviView.hidden = YES; self.navigationController.interactivePopGestureRecognizer.enabled = NO; self.navigationController.interactivePopGestureRecognizer.delegate =nil; _isPreView = YES; [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; //弹出相机权限 [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { }]; //弹出麦克风权限 [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) { }]; selectShareName = @""; [self addNotification]; [self netMonitoring]; //创建推流器 [self initTxPush]; [self.view addSubview:self.livePreview]; [self.view addSubview:self.liveCtrlView]; NSInteger deviceType = [PublicObj getDeviceType]; //iPhone6s if (deviceType >= 8){ _needScale = NO; }else{ _needScale = YES; } if([_has_hotliveorder isEqual:@"1"]){ YBWeakSelf; _uphotOrderView =[[UpHotOrderView alloc]initWithFrame:CGRectMake(0, 0, _window_width, _window_height)andInfoDic:_hotliveorderDic]; _uphotOrderView.btnEvent = ^(NSString *type) { if([type isEqual:YZMsg(@"使用")]){ uphotOrderId =minstr([weakSelf.hotliveorderDic valueForKey:@"id"]) ; } [weakSelf.uphotOrderView removeFromSuperview]; weakSelf.uphotOrderView = nil; }; [self.view addSubview:_uphotOrderView]; } } -(void)initTxPush{ [self.view addSubview:self.pkBgIV]; _txPushPreview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _window_width, _window_height)]; [self.view addSubview:self.txPushPreview]; [[YBLiveRTCManager shareInstance]initWithLiveMode:V2TXLiveMode_RTC andPushData:_pushSettingDic]; [[YBLiveRTCManager shareInstance]setPushView:_txPushPreview]; [YBLiveRTCManager shareInstance].delegate = self; if ([PublicObj isBaseBeauty]) { //腾讯美颜 [[YBLiveRTCManager shareInstance] setBeautyLevel:[TXBaseBeautyView getBaseBeautyValue] WhitenessLevel:[TXBaseBeautyView getBaseWhiteValue]]; }else{ //其他美颜 // [self txBaseStyle:0 level:0 white:0 ruddiness:0]; // [_txLivePublisher setMirror:YES]; // [[MHSDK shareInstance]initWithAppID:@"33893d3ce4ad50e38efa067755386b24" key:@"061e4b4758d2f8a3afd0a095f543f091"]; [[MHSDK shareInstance] initWithAppID:[common getTISDKAppid] key:[common getTISDKKey]]; } } #pragma mark -美狐回调 -(void)MHBeautyBlock:(V2TXLiveVideoFrame *)srcFrame dstFrame:(V2TXLiveVideoFrame *)dstFrame { dstFrame.textureId= [self.beautyManager getTextureProcessWithTexture:srcFrame.textureId width:(GLint)srcFrame.width height:(GLint)srcFrame.height mirror:YES]; dispatch_async(dispatch_get_main_queue(), ^{ if (self.menusView) { if (!isLoadWebSprout) { isLoadWebSprout = YES; [self.menusView setupDefaultBeautyAndFaceValue]; } } }); } -(void)destoryMHBeauty{ [self destroyMhSource]; } #pragma mark - 美颜开始 -(void)showBeautyUI { if (_livePreview && _isPreView) { _livePreview.hidden = YES; } if ([PublicObj isBaseBeauty]) { YBWeakSelf; [TXBaseBeautyView showBaseBeauty:^(NSString *eventStr, float value, NSString *filterName) { [weakSelf txBaseBeauty:eventStr value:value filter:filterName]; }]; }else{ //[self.tiUIView createTiUIView:NO]; self.mhShadowBtn.hidden = NO; [self.menusView showMenuView:YES]; } } //基础美颜 -(void)txBaseBeauty:(NSString *)eventStr value:(float)value filter:(NSString *)filterName { if ([eventStr isEqual:@"基础美颜-关闭"]) { [self onTiTapEvent]; } if ([eventStr isEqual:@"基础美颜-美颜"]) { [self txBaseStyle:0 level:value white:[TXBaseBeautyView getBaseWhiteValue] ruddiness:0]; } if ([eventStr isEqual:@"基础美颜-美白"]) { [self txBaseStyle:0 level:[TXBaseBeautyView getBaseBeautyValue] white:value ruddiness:0]; } if ([eventStr isEqual:@"基础美颜-滤镜"]) { if (![PublicObj checkNull:filterName]) { [[YBLiveRTCManager shareInstance]setYBFilter:[UIImage imageWithContentsOfFile:filterName]]; }else { [[YBLiveRTCManager shareInstance]setYBFilter:nil]; } } } -(void)txBaseStyle:(int)beautyStyle level:(CGFloat)beautyLevel white:(CGFloat)whiteness ruddiness:(CGFloat)ruddiness { [[YBLiveRTCManager shareInstance] setYBRuddyLevel:ruddiness]; [[YBLiveRTCManager shareInstance]setBeautyLevel:beautyLevel WhitenessLevel:whiteness]; // [[_txLivePublisher getBeautyManager] setBeautyStyle:beautyStyle]; // [[_txLivePublisher getBeautyManager] setBeautyLevel:beautyLevel]; // [[_txLivePublisher getBeautyManager] setWhitenessLevel:whiteness]; // [[_txLivePublisher getBeautyManager] setRuddyLevel:ruddiness]; } - (void)dealloc{ //[self destroyTiSdk]; // [self destroyMhSource]; } -(void)destroyMhSource { if (self.beautyManager) { [self.beautyManager destroy]; self.beautyManager = nil; } } - (void)onTiTapEvent { if (_livePreview && _isPreView) { _livePreview.hidden = NO; } } //美狐 - (MHBeautyManager *)beautyManager { if (!_beautyManager) { _beautyManager = [[MHBeautyManager alloc] init]; } return _beautyManager; } - (UIButton *)mhShadowBtn { if (!_mhShadowBtn) { _mhShadowBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _mhShadowBtn.frame = CGRectMake(0, 0, _window_width, _window_height); [_mhShadowBtn addTarget:self action:@selector(dismissMHUI) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:_mhShadowBtn]; } return _mhShadowBtn; } -(void)dismissMHUI { if (self.menusView.isShow) { self.mhShadowBtn.hidden = YES; //更新美颜值 [sproutCommon updataMHValueToService]; [self.menusView showMenuView:NO]; [self onTiTapEvent]; }else { [self.menusView showMenuView:YES]; } } - (MHMeiyanMenusView *)menusView { if (!_menusView) { // _menusView = [[MHMeiyanMenusView alloc]initWithFrame:CGRectMake(0, window_height - MHMeiyanMenuHeight - BottomIndicatorHeight, window_width,MHMeiyanMenuHeight) superView:self.view delegate:self beautyManager:self.beautyManager isTXSDK:YES]; _menusView = [[MHMeiyanMenusView alloc] initWithFrame:CGRectMake(0, window_height - MHMeiyanMenuHeight - BottomIndicatorHeight, window_width, MHMeiyanMenuHeight) superView:self.view beautyManager:self.beautyManager]; } return _menusView; } - (void)beautyEffectWithLevel:(NSInteger)beauty whitenessLevel:(NSInteger)white ruddinessLevel:(NSInteger)ruddiness { [self txBaseStyle:0 level:beauty white:white ruddiness:ruddiness]; } #pragma mark - 美颜结束 #pragma mark - 直播 -(void)rotateCamera{ dispatch_async(dispatch_get_main_queue(), ^{ // [_txLivePublisher switchCamera]; // [_txLivePublisher setMirror:_txLivePublisher.frontCamera]; _isFrontCamera = !_isFrontCamera; [[YBLiveRTCManager shareInstance]changeCamera:_isFrontCamera]; }); } - (void)txStopRtmp { [[YBLiveRTCManager shareInstance]stopPush]; [[UIApplication sharedApplication] setIdleTimerDisabled:NO]; } -(void)hostStopRoom { if (isclosenetwork) { //断网 [self showNetCloseAlert]; [self destroySource]; [self clickNaviLeftBtn]; }else{ [self getCloseShow]; } } //关播 -(void)getCloseShow { [self destroySource]; [MBProgressHUD showMessage:@""]; YBWeakSelf; [YBNetworking postWithUrl:@"Live.stopRoom" Dic:@{@"stream":_hostStream} Suc:^(int code, id info, NSString *msg) { [MBProgressHUD hideHUD]; if (code == 0) { [weakSelf dismissVC]; }else { [MBProgressHUD showPop:msg]; } } Fail:^(id fail) { [MBProgressHUD hideHUD]; }]; } -(void)superStopRoom { /* [PublicObj resetUserToVisitor]; [self destroySource]; [self clickNaviLeftBtn]; */ [self getCloseShow]; } -(void)destroySource { if (buttleView) { [self removeButtleView]; } [self destroyImListView]; [_liveCtrlView destroyCtrSubView]; [self txStopRtmp]; [self destroyTimer]; [[YBSocketLive liveSocketManeger]liveDisconnectSocket]; [[NSNotificationCenter defaultCenter]removeObserver:self]; [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isLiveing"]; // [self destroyMhSource]; } -(void)dismissVC { [self destroySource]; [MBProgressHUD showMessage:@""]; YBWeakSelf; [YBNetworking postWithUrl:@"Live.stopInfo" Dic:@{@"stream":_hostStream} Suc:^(int code, id info, NSString *msg) { [MBProgressHUD hideHUD]; if (code == 0) { _liveCtrlView.hidden = YES; NSDictionary *subdic = [info firstObject]; [weakSelf createEndView:subdic]; }else { [MBProgressHUD showPop:msg]; } } Fail:^(id fail) { [MBProgressHUD hideHUD]; }]; } -(void)createEndView:(NSDictionary *)endDic { [self.view addSubview:self.liveEndView]; NSMutableDictionary *allDic = @{@"hostAvatar":[Config getUserAvatar],@"hostName":[Config getOwnNicename]}.mutableCopy; [allDic addEntriesFromDictionary:endDic]; [_liveEndView updateData:allDic]; } -(void)destroyTimer { if (backGroundTimer) { [backGroundTimer invalidate]; backGroundTimer = nil; } if (_listTimer) { [_listTimer invalidate]; _listTimer = nil; } if (_liveTimer) { [_liveTimer invalidate]; _liveTimer = nil; } if (_heartTimer) { [_heartTimer invalidate]; _heartTimer = nil; } } #pragma mark - TXVideoProcessDelegate //- (GLuint)onPreProcessTexture:(GLuint)texture width:(CGFloat)width height:(CGFloat)height{ // // if ([PublicObj isBaseBeauty]) { // //普通美颜 // return texture; // } // GLuint newTexture = texture; // /* // if (_needScale){ // newTexture = [_beautyManager processWithTexture:texture width:width height:height scale:0.75]; // }else{ // [self.beautyManager processWithTexture:texture width:width height:height]; // } // */ // newTexture = [self.beautyManager getTextureProcessWithTexture:texture width:width height:height]; // dispatch_async(dispatch_get_main_queue(), ^{ // if (self.menusView) { // if (!isLoadWebSprout) { // isLoadWebSprout = YES; // [self.menusView setupDefaultBeautyAndFaceValue]; // } // } // }); // return newTexture; //} //- (void)onTextureDestoryed{ //// [self destroyTiSdk]; //} //#pragma mark - TXLivePushListener //-(void) onNetStatus:(NSDictionary*) param{ // //} //-(void) onPushEvent:(int)EvtID withParam:(NSDictionary*)param { // dispatch_async(dispatch_get_main_queue(), ^{ // if (EvtID >= 0) { // if (EvtID == PUSH_WARNING_HW_ACCELERATION_FAIL) { // _txLivePublisher.config.enableHWAcceleration = false; // NSLog(@"PUSH_EVT_PUSH_BEGIN硬编码启动失败,采用软编码"); // }else if (EvtID == PUSH_EVT_CONNECT_SUCC) { // // 已经连接推流服务器 // NSLog(@" PUSH_EVT_PUSH_BEGIN已经连接推流服务器"); // }else if (EvtID == PUSH_EVT_PUSH_BEGIN) { // // 已经与服务器握手完毕,开始推流 // [self changePlayState:1]; // NSLog(@"liveshow已经与服务器握手完毕,开始推流"); // }else if (EvtID == PUSH_WARNING_RECONNECT){ // // 网络断连, 已启动自动重连 (自动重连连续失败超过三次会放弃) // NSLog(@"网络断连, 已启动自动重连 (自动重连连续失败超过三次会放弃)"); // }else if (EvtID == PUSH_WARNING_NET_BUSY) { // //[_notification displayNotificationWithMessage:@"您当前的网络环境不佳,请尽快更换网络保证正常直播" forDuration:5]; // } // }else { // if (EvtID == PUSH_ERR_NET_DISCONNECT) { // NSLog(@"PUSH_EVT_PUSH_BEGIN网络断连,且经多次重连抢救无效,可以放弃治疗,更多重试请自行重启推流"); // [MBProgressHUD showPop:YZMsg(@"网络断连")]; // [self hostStopRoom]; // } // } // }); //} #pragma mark --RTC推流回调 /** * 推流器连接状态回调通知 * * @param status 推流器连接状态 {@link V2TXLivePushStatus}。 * @param msg 连接状态信息。 * @param extraInfo 扩展信息。 */ -(void)ybRTCPushStatusUpdate:(V2TXLivePushStatus)status message:(NSString *)msg extraInfo:(NSDictionary *)extraInfo{ dispatch_async(dispatch_get_main_queue(), ^{ if (status == V2TXLivePushStatusDisconnected) { NSLog(@"PUSH_EVT_PUSH_BEGIN网络断连,且经多次重连抢救无效,可以放弃治疗,更多重试请自行重启推流"); [MBProgressHUD showPop:YZMsg(@"网络断连")]; [self hostStopRoom]; }else if(status == V2TXLivePushStatusConnecting){ /// 正在连接服务器 // if (isPUSH_WARNING_RECONNECT) { // isPUSH_WARNING_RECONNECT = NO; // [self checkLiveingStatus]; // } }else if(status == V2TXLivePushStatusConnectSuccess){ /// 连接服务器成功 [self changePlayState:1]; }else if(status == V2TXLivePushStatusConnectSuccess){ /// 重连服务器中 NSLog(@"网络断连, 已启动自动重连 (自动重连连续失败超过三次会放弃)"); } }); } -(void)ybPushLiveStatus:(V2TXLiveCode)pushStatus { if (pushStatus == V2TXLIVE_OK) { NSLog(@"LIVEBROADCAST --:推流成功、停止推流"); }else if (pushStatus == V2TXLIVE_ERROR_INVALID_PARAMETER){ // [_notification displayNotificationWithMessage:@"操作失败,url 不合法" forDuration:5]; NSLog(@"推流器启动失败"); }else if (pushStatus == V2TXLIVE_ERROR_INVALID_LICENSE){ // [_notification displayNotificationWithMessage:@"操作失败,license 不合法,鉴权失败" forDuration:5]; NSLog(@"推流器启动失败"); }else if (pushStatus == V2TXLIVE_ERROR_REFUSED){ // [_notification displayNotificationWithMessage:@"操作失败,RTC 不支持同一设备上同时推拉同一个 StreamId" forDuration:5]; NSLog(@"推流器启动失败"); }else if (pushStatus == V2TXLIVE_WARNING_NETWORK_BUSY){ // [_notification displayNotificationWithMessage: // @"您当前的网络环境不佳,请尽快更换网络保证正常直播" forDuration:5]; } } #pragma mark - 控制层回调 -(void)controlViewCallBack:(NSString *)eventType andEvnent:(NSDictionary *)eventDic { YBWeakSelf; if ([eventType isEqual:@"控制-动画结束"]) { //开始推流 [self goStartPushing]; } if ([eventType isEqual:@"控制-关闭"]) { NSDictionary *contentDic = @{@"title":YZMsg(@"提示"),@"msg":YZMsg(@"是否要结束直播?"),@"left":YZMsg(@"取消"),@"right":YZMsg(@"确定")}; [YBAlertView showAlertView:contentDic complete:^(int eventType) { if (eventType == 1) { [weakSelf hostStopRoom]; } }]; } if ([eventType isEqual:@"控制-美颜"]) { [self showBeautyUI]; } if ([eventType isEqual:@"控制-翻转"]) { [self rotateCamera]; } if ([eventType isEqual:@"控制-闪光灯"]) { if (_isFrontCamera) { [MBProgressHUD showError:YZMsg(@"只有后置摄像头才能开启闪光灯")]; return; } _liveCtrlView.isTorch = !_liveCtrlView.isTorch; [[YBLiveRTCManager shareInstance]cameraTorch:_liveCtrlView.isTorch]; // if (![_txLivePublisher toggleTorch:_liveCtrlView.isTorch]) { // _liveCtrlView.isTorch = !_liveCtrlView.isTorch; // } // if (_txLivePublisher.frontCamera) { // [MBProgressHUD showPop:YZMsg(@"只有后置摄像头才能开启闪光灯")]; // } } if ([eventType isEqual:@"控制-直播聊天"]) { //发送socket 'ct' [eventDic valueForKey:@"ct"] [[YBSocketLive liveSocketManeger] liveSendMsg:minstr([eventDic valueForKey:@"ct"])]; } if ([eventType isEqual:@"控制-信息卡"]) { [weakSelf showButtleView:minstr([eventDic valueForKey:@"id"])]; } if ([eventType isEqual:@"控制-私信"]) { [weakSelf liveRoomPraviteMsg]; } if ([eventType isEqual:@"控制-在售"]) { [[YBSocketLive liveSocketManeger] liveSendOnSaleShowHidden:eventDic]; } if ([eventType isEqual:@"控制-主播下麦他人"]) { int isHostToHost = [minstr([eventDic valueForKey:@"hostToHost"]) intValue]; if (isHostToHost) { [[YBSocketLive liveSocketManeger] liveSendAnchorCtrOfAcntion:@"5" andExtDic:@{@"pkuid":minstr([eventDic valueForKey:@"uid"]),@"pkpull":@""}]; }else { [[YBSocketLive liveSocketManeger] liveSendHostDisconnect:eventDic]; } } if ([eventType isEqual:@"控制-主播和主播连麦请求"]) { [[YBSocketLive liveSocketManeger] liveSendAnchorStartLink:[eventDic valueForKey:@"otherInfo"] andMyInfo:[eventDic valueForKey:@"myInfo"]]; } if ([eventType isEqual:@"控制-发起PK"]) { [[YBSocketLive liveSocketManeger] liveSendStartPk]; } } //开始推流 -(void)goStartPushing { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isLiveing"]; _hostUrl = minstr([_roomDic valueForKey:@"push"]); _hostStream = minstr([_roomDic valueForKey:@"stream"]); _userlistRefreshTime = [minstr([_roomDic valueForKey:@"userlist_time"]) intValue]; if (_userlistRefreshTime < 10) { _userlistRefreshTime = 10; } if (_liveCtrlView) { _liveCtrlView.liveUid = [Config getOwnID]; _liveCtrlView.liveStream = _hostStream; _liveCtrlView.liveTitle = _liveTitle; _liveCtrlView.liveHostUrl = _hostUrl; } // //推流器 // _txLivePublisher.delegate = self; // [self.txLivePublisher setVideoQuality:VIDEO_QUALITY_HIGH_DEFINITION adjustBitrate:YES adjustResolution:YES]; _hostUrl = [NSString stringWithFormat:@"%@&mix=session_id:%@",_hostUrl,[Config getOwnID]]; _liveCtrlView.liveHostUrl = _hostUrl; [[YBLiveRTCManager shareInstance]startPush:_hostUrl]; [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; // int isOK = [_txLivePublisher startPush:_hostUrl]; // if (isOK != 0) { // [MBProgressHUD showPop:[NSString stringWithFormat:@"%@:%d",YZMsg(@"推流器启动失败"),isOK]]; // NSLog(@"推流器启动失败"); // [self callBackClosePreView]; // return; // } // if (!_listTimer) { _listTimer = [NSTimer scheduledTimerWithTimeInterval:_userlistRefreshTime target:self selector:@selector(reloadUserList) userInfo:nil repeats:YES]; } if (!_heartTimer) { _heartTimer = [NSTimer scheduledTimerWithTimeInterval:0.8 target:self selector:@selector(socketLight) userInfo:nil repeats:YES]; } if (!_liveTimer) { _liveTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(liveTimeUpdate) userInfo:nil repeats:YES]; } //socket [self startSocketBlockMonitor]; [[YBSocketLive liveSocketManeger]liveConnectSocket:_roomDic]; } -(void)reloadUserList { [_liveCtrlView timerReloadList]; } -(void)socketLight { [_liveCtrlView socketLightAnimation]; } //直播时长 -(void)liveTimeUpdate { [_liveCtrlView updateLiveTime]; } #pragma mark - 直播间私信列表开始 -(void)liveRoomPraviteMsg { [self destroyImListView]; YBWeakSelf; _imListView = [YBImRoomSmallView showImListWithLiveUid:[Config getOwnID]]; _imListView.imSmallType = ImSmall_List; _imListView.imCtrEvent = ^(ImCtrType type, NSDictionary *ctrDic) { if (type == ImCtr_Dismiss) { [weakSelf destroyImListView]; } }; } -(void)destroyImListView { if (_imListView) { [_imListView removeFromSuperview]; _imListView = nil; } } #pragma mark - 直播间私信列表结束 #pragma mark - 用户卡片信息开始 - (void)showButtleView:(NSString *)touid{ if (buttleView) { [self removeButtleView]; } buttleView = [[UserBulletWindow alloc]initWithUserID:touid andIsAnchor:YES andAnchorID:[Config getOwnID]]; buttleView.delegate = self; [self.view addSubview:buttleView]; } - (void)removeButtleView { [buttleView destroySubs]; [buttleView removeFromSuperview]; buttleView = nil; } -(void)socketShutUp:(NSString *)name andID:(NSString *)ID andType:(NSString *)type { [[YBSocketLive liveSocketManeger] liveSendShutUpUser:@{@"type":type,@"touid":ID,@"touname":name}]; } -(void)socketkickuser:(NSString *)name andID:(NSString *)ID { [[YBSocketLive liveSocketManeger] liveSendKickUser:@{@"touname":name,@"touid":ID}]; } -(void)pushZhuYe:(NSString *)IDS { YBCenterVC *center = [[YBCenterVC alloc]init]; center.otherUid = IDS; center.isPush = YES; [[YBBaseAppDelegate sharedAppDelegate] pushViewController:center animated:YES]; } -(void)siXin:(NSString *)icon andName:(NSString *)name andID:(NSString *)ID andIsatt:(NSString *)isatt { [self destroyImListView]; YBWeakSelf; [[YBMessageManager shareManager] getChatCellDataWithTouid:ID finish:^(int code, TConversationCellData * _Nonnull cellData) { dispatch_async(dispatch_get_main_queue(), ^{ if (code == 0) { _imListView = [YBImRoomSmallView showImListWithLiveUid:[Config getOwnID]]; _imListView.imSmallType = ImSmall_C2C; [_imListView goChatWithC2CWithConv:cellData]; _imListView.imCtrEvent = ^(ImCtrType type, NSDictionary *ctrDic) { if (type == ImCtr_Dismiss) { [weakSelf destroyImListView]; } }; } }); }]; } - (void)hideChatMall{ if (huanxinviews) { [huanxinviews forMessage]; CATransition *transition = [CATransition animation]; transition.duration = 0.3; //设置动画淡入淡出的效果 transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; transition.type = kCATransitionPush; transition.subtype = kCATransitionFromLeft; [chatsmall.view.layer addAnimation:transition forKey:nil]; [chatsmall.view removeFromSuperview]; chatsmall.view = nil; chatsmall = nil; }else{ [UIView animateWithDuration:0.3 animations:^{ chatsmall.view.frame = CGRectMake(_window_width, _window_height*0.6, _window_width, _window_height*0.4); } completion:^(BOOL finished) { [chatsmall.view removeFromSuperview]; chatsmall.view = nil; chatsmall = nil; }]; } } -(void)setAdminSuccess:(NSString *)isadmin andName:(NSString *)name andID:(NSString *)ID { [[YBSocketLive liveSocketManeger] liveSendSetAdmin:@{@"isadmin":isadmin,@"touid":ID,@"touname":name}]; } -(void)adminList { adminLists *adminVC = [[adminLists alloc]init]; adminVC.delegate = self; adminVC.modalPresentationStyle = 0; [self presentViewController:adminVC animated:YES completion:nil]; } #pragma mark - 用户卡片信息结束 #pragma mark - socket 回调监听 -(void)startSocketBlockMonitor { YBWeakSelf; //检查直播状态 [YBSocketLive liveSocketManeger].checkLiveingStatus = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf checkLiveingStatus]; }; //超管关播 [YBSocketLive liveSocketManeger].superStopRoom = ^(NSString *socEvent, NSDictionary *socketDic) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf superStopRoom]; }); }; //用户点亮 [YBSocketLive liveSocketManeger].userLight = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketLightAnimation]; }; //发言 [YBSocketLive liveSocketManeger].userSendMsg = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketChatDic:socketDic]; }; //用户离开 [YBSocketLive liveSocketManeger].userLeave = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketUserLeave:socketDic]; }; //用户进入 [YBSocketLive liveSocketManeger].userEnter = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketUserEnter:socketDic]; }; //系统消息 [YBSocketLive liveSocketManeger].systemMsg = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketChatDic:socketDic]; }; //送礼物 [YBSocketLive liveSocketManeger].sendGift = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketSendGift:socketDic]; }; //其他设备登陆 [YBSocketLive liveSocketManeger].otherDeviceLogin = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf showAlertMsg]; }; //购买守护 [YBSocketLive liveSocketManeger].buyGuardMsg = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketUpdateGuardMsg:socketDic]; }; //连麦用户流信息 [YBSocketLive liveSocketManeger].linkPlayMsg = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketShowLinkUserPop:socketDic]; }; //连麦用户挂断 [YBSocketLive liveSocketManeger].linkUserDisconnect = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketLinkUserDisconnect:socketDic]; }; //收到连麦请求 [YBSocketLive liveSocketManeger].linkHostToHostRequest = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView destroyAnchorOnlineList]; }; //主播-主播连成功 [YBSocketLive liveSocketManeger].linkHostToHostMsg = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketLinkHostToHostSuc:socketDic]; [weakSelf changeLinkPlayer:YES toHostid:minstr([socketDic valueForKey:@"pkuid"])]; }; //主播-主播挂断 [YBSocketLive liveSocketManeger].linkHostToHostDisconnect = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketlinkHostToHostDisconnect:socketDic]; [weakSelf changeLinkPlayer:NO toHostid:@""]; }; //收到PK请求【只需隐藏自己的发起PK按钮】 [YBSocketLive liveSocketManeger].linkPKGetRequest = ^(NSString *socEvent, NSDictionary *socketDic) { _liveCtrlView.startPkBtn.hidden = YES; }; //PK-拒绝 [YBSocketLive liveSocketManeger].linkPKUnAgree = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf startPKBtnShow:YES]; }; //PK-开始 [YBSocketLive liveSocketManeger].linkPKSuc = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf startPKBtnShow:NO]; [weakSelf.liveCtrlView socketLinkPKStart:socketDic]; }; //PK-忙碌 [YBSocketLive liveSocketManeger].linkPKBusy = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf startPKBtnShow:YES]; }; //PK-超时 [YBSocketLive liveSocketManeger].linkPKTimeout = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf startPKBtnShow:YES]; }; //PK-结果 [YBSocketLive liveSocketManeger].linkPKResult = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketLinkPKReult:socketDic]; }; //PK-进度 [YBSocketLive liveSocketManeger].linkPKProgress = ^(NSString *socEvent, NSDictionary *socketDic) { [weakSelf.liveCtrlView socketLinkPKProgress:socketDic]; }; } -(void)startPKBtnShow:(BOOL)isShow{ _liveCtrlView.startPkBtn.hidden = !isShow; [_liveCtrlView cancelPKAlert]; } -(void)changeLinkPlayer:(BOOL)isLink toHostid:(NSString *)toHostid{ if (isLink) { [_liveCtrlView showToHostInfoWithId:toHostid]; _txPushPreview.frame = CGRectMake(0, 130+statusbarHeight, _window_width/2, _window_width*2/3); }else { [_liveCtrlView destroyPkTohostInfo]; _txPushPreview.frame = CGRectMake(0, 0, _window_width, _window_height); } } -(void)showAlertMsg { /// 220421弹窗去掉直接关播 [self hostStopRoom]; /* YBWeakSelf; NSDictionary *contentDic = @{@"title":@"",@"msg":YZMsg(@"当前账号已在其他设备登录"),@"left":@"",@"right":YZMsg(@"确定")}; [YBAlertView showAlertView:contentDic complete:^(int eventType) { if (eventType == 1) { [weakSelf hostStopRoom]; } }]; */ } #pragma mark - 预览层回调 -(void)previewCallBack:(NSString *)eventType andEvnent:(NSString *)eventContent { NSLog(@"预览type:%@-con:%@",eventType,eventContent); if ([eventType isEqual:@"预览-切换"]) { [self rotateCamera]; } if ([eventType isEqual:@"预览-关闭"]) { [self callBackClosePreView]; } if ([eventType isEqual:@"预览-开直播"]) { [self callBackStartLive]; } if ([eventType isEqual:@"预览-美颜"]) { [self showBeautyUI]; } if ([eventType isEqual:@"预览-分享"]) { selectShareName = eventContent; } if ([eventType isEqual:@"预览-分类"]) { liveClassStr = eventContent; } if ([eventType isEqual:@"预览-上热门"]) { [self goUpHotView]; } } #pragma mark - 上热门 -(void)goUpHotView{ YBWeakSelf; _hotView = [[UpHotView alloc]initWithFrame:CGRectMake(0, 0, _window_width, _window_height)]; _hotView.closeEvent = ^(NSString *status, NSString *orderid) { if([status isEqual:@"确定"]){ uphotOrderId = orderid; } [weakSelf.hotView removeFromSuperview]; weakSelf.hotView = nil; }; [self.view addSubview:_hotView]; } - (void)callBackClosePreView{ [self txStopRtmp]; // [self destroyMhSource]; [UIApplication sharedApplication].idleTimerDisabled = NO; [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isLiveing"]; [self clickNaviLeftBtn]; } -(void)callBackStartLive { if ([PublicObj checkNull:minstr(selectShareName)]) { [self createRoom]; }else { YBWeakSelf; NSDictionary *shareDic = @{@"hostName":[Config getOwnNicename],@"thumb_s":[Config getUserAvatarThumb],@"hostId":[Config getOwnID],@"liveTitle":_liveTitle}; [[YBShareView noShareUIManager]executeShareWithType:RKShareType_LivePre shareType:selectShareName parameter:shareDic complete:^(int codeEvent, NSString *nums) { [weakSelf createRoom]; }]; } } #pragma mark - 开始直播请求 -(void)createRoom { if ([liveClassStr isEqual:@"-99999999"]) { [MBProgressHUD showPop:YZMsg(@"请选择直播频道")]; return; } _liveTitle = minstr(_livePreview.inputTitleStr); NSString *deviceinfo = [NSString stringWithFormat:@"%@_%@_%@",[PublicObj iphoneType],[[UIDevice currentDevice] systemVersion],[PublicObj getNetworkType]]; NSDictionary *postDic = @{@"title":minstr(_livePreview.inputTitleStr), @"province":@"", @"city":(_livePreview.locationSwitch&&[cityDefault getLocationCity])?[cityDefault getLocationCity]:@"", @"lng":(_livePreview.locationSwitch&&[cityDefault getLocationLng])?[cityDefault getLocationLng]:@"", @"lat":(_livePreview.locationSwitch&&[cityDefault getLocationLat])?[cityDefault getLocationLat]:@"", @"deviceinfo":deviceinfo, @"uid":[Config getOwnID], @"token":[Config getOwnToken], @"isshop":@(_livePreview.cartOpen), @"liveclassid":liveClassStr, @"lang":[YBLanguageTools serviceLang], }; [MBProgressHUD showMessage:@""]; //AFHTTPSessionManager *session = [AFHTTPSessionManager manager]; NSString *postUrl = [purl stringByAppendingFormat:@"?service=Live.createRoom"]; [[YBNetworking ybnetManager] POST:postUrl parameters:postDic headers:nil constructingBodyWithBlock:^(id _Nonnull formData) { if (_livePreview.thumbImage) { [formData appendPartWithFileData:[Utils compressImage:_livePreview.thumbImage] name:@"file" fileName:@"duibinaf.png" mimeType:@"image/jpeg"]; } } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { [MBProgressHUD hideHUD]; NSString *retStr = minstr([responseObject valueForKey:@"ret"]); if ([retStr isEqual:@"200"]) { NSDictionary *data = [responseObject valueForKey:@"data"]; NSString *code = [NSString stringWithFormat:@"%@",[data valueForKey:@"code"]]; if ([code isEqual:@"0"]) { _roomDic = [[data valueForKey:@"info"]firstObject]; _livePreview.hidden = YES; _isPreView = NO; _liveCtrlView.hidden = NO; //开播动画 [_liveCtrlView startLiveAnimation]; [_liveCtrlView createroomUpdateInfo:_roomDic]; _liveCtrlView.cartBtn.hidden = !_livePreview.cartOpen; [_liveCtrlView resetPKBtnFrame]; }else { [MBProgressHUD showPop:[data valueForKey:@"msg"]]; } }else { [MBProgressHUD showPop:[responseObject valueForKey:@"msg"]]; } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { [MBProgressHUD hideHUD]; [MBProgressHUD showError:YZMsg(@"网络错误")]; }]; } #pragma mark - 检查开播状态 - (void)checkLiveingStatus{ [YBNetworking postWithUrl:@"Live.checkLiveing" Dic:@{@"stream":minstr([_roomDic valueForKey:@"stream"])} Suc:^(int code, id info, NSString *msg) { if (code == 0) { NSDictionary *dic = [info firstObject]; NSLog(@"info=%@",info); if ([minstr([dic valueForKey:@"status"]) isEqual:@"0"]) { [self showNetCloseAlert]; [self getCloseShow]; } } } Fail:nil]; } -(void)showNetCloseAlert { //[MBProgressHUD showPop:YZMsg(@"网络连接出错,直播结束")]; NSDictionary *contentDic = @{@"title":YZMsg(@"提示"),@"msg":YZMsg(@"网络连接出错,直播结束"),@"left":@"",@"right":YZMsg(@"确定")}; [YBAlertView showAlertView:contentDic complete:^(int eventType) { }]; } #pragma mark - 更改开播状态 -(void)changePlayState:(int)status{ NSDictionary *changelive = @{ @"stream":_hostStream, // @"status":[NSString stringWithFormat:@"%d",status] @"hotlive_orderid":uphotOrderId }; [YBNetworking postWithUrl:@"Live.changeLive" Dic:changelive Suc:^(int code, id info, NSString *msg) { } Fail:nil]; } #pragma mark - 通知 -(void)addNotification{ //注册进入后台的处理 NSNotificationCenter* notification = [NSNotificationCenter defaultCenter]; [notification addObserver:self selector:@selector(appactive) name:UIApplicationDidBecomeActiveNotification object:nil]; [notification addObserver:self selector:@selector(appnoactive) name:UIApplicationWillResignActiveNotification object:nil]; [notification addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [notification addObserver:self selector:@selector(keyboardWillHidden) name:UIKeyboardWillHideNotification object:nil]; [notification addObserver:self selector:@selector(shajincheng) name:@"shajincheng" object:nil]; //获取所有未读消息 [[V2TIMManager sharedInstance] addConversationListener:self]; } // 收到所有会话的未读总数变更通知 - (void)onTotalUnreadMessageCountChanged:(UInt64)totalUnreadCount { [self requestJmsg]; } -(void)keyboardWillShow:(NSNotification *)not { //获取键盘的高度 NSDictionary *userInfo = [not userInfo]; NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]; CGRect keyboardRect = [aValue CGRectValue]; CGFloat height = keyboardRect.size.height; [UIView animateWithDuration:0.3 animations:^{ if (_liveCtrlView) { _liveCtrlView.keyBoardIsShow = YES; _liveCtrlView.top = - height; [_liveCtrlView keyBoardNoticeIsShow:YES andHeight:height]; } }completion:^(BOOL finished) { [self strangeExcursion]; }]; } -(void)strangeExcursion{ //很奇怪刘海平手机会偏移 37 [UIView animateWithDuration:0.3 animations:^{ self.view.top = 0; }]; } -(void)keyboardWillHidden { [UIView animateWithDuration:0.3 animations:^{ if (_liveCtrlView) { _liveCtrlView.keyBoardIsShow = NO; _liveCtrlView.top = 0; _liveCtrlView.chatTool.hidden = YES; _liveCtrlView.botBtnFunView.hidden = NO; [_liveCtrlView keyBoardNoticeIsShow:NO andHeight:0]; } }]; } -(void)shajincheng{ [self dismissVC]; } -(void)appactive{ if (_isPreView) { return; } NSLog(@"哈哈哈哈哈哈哈哈哈哈哈哈 app回到前台"); [[YBLiveRTCManager shareInstance]resumePush]; [self forwardGround]; } -(void)appnoactive{ if (_isPreView) { return; } [[YBLiveRTCManager shareInstance]pausePush]; [self backGround]; NSLog(@"0000000000000000000 app进入后台"); } -(void)backgroundselector{ backTime +=1; NSLog(@"返回后台时间%d",backTime); if (backTime > _canBackTime) { [self hostStopRoom]; } } -(void)backGround{ if (!backGroundTimer) { [self sendEmccBack]; backGroundTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(backgroundselector) userInfo:nil repeats:YES]; } } -(void)forwardGround{ if (backTime != 0) { [[YBSocketLive liveSocketManeger] liveSendPhoneCall:@"主播回来了" andEn:@"The anchor comes back"]; } if (backTime > _canBackTime) { [self hostStopRoom]; } if (isclosenetwork == NO) { [backGroundTimer invalidate]; backGroundTimer = nil; backTime = 0; } } //来电话 -(void)sendEmccBack { [[YBSocketLive liveSocketManeger] liveSendPhoneCall:@"主播离开一下,精彩不中断,不要走开哦" andEn:@"The anchor leaves for a moment. The stream must go on, don't go away"]; } #pragma mark - 网络 -(void)netMonitoring { YBWeakSelf; [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusUnknown: NSLog(@"未识别的网络"); isclosenetwork = YES; [weakSelf backGround]; break; case AFNetworkReachabilityStatusNotReachable: NSLog(@"不可达的网络(未连接)"); isclosenetwork = YES; [weakSelf backGround]; break; case AFNetworkReachabilityStatusReachableViaWWAN: isclosenetwork = NO; [weakSelf forwardGround]; if (weakSelf.roomDic) { [weakSelf checkLiveingStatus]; } break; case AFNetworkReachabilityStatusReachableViaWiFi: isclosenetwork = NO; if (weakSelf.roomDic) { [weakSelf checkLiveingStatus]; } [weakSelf forwardGround]; break; default: break; } }]; [[AFNetworkReachabilityManager sharedManager] startMonitoring]; self.callCenter = [CTCallCenter new]; self.callCenter.callEventHandler = ^(CTCall *call) { dispatch_async(dispatch_get_main_queue(), ^{ if ([call.callState isEqualToString:CTCallStateDialing]) { NSLog(@"电话主动拨打电话"); [weakSelf reciverPhoneCall]; } else if ([call.callState isEqualToString:CTCallStateConnected]) { NSLog(@"电话接通"); [weakSelf reciverPhoneCall]; } else if ([call.callState isEqualToString:CTCallStateDisconnected]) { NSLog(@"电话挂断"); [weakSelf phoneCallEnd]; } else if ([call.callState isEqualToString:CTCallStateIncoming]) { NSLog(@"电话被叫"); [weakSelf reciverPhoneCall]; } else { NSLog(@"电话其他状态"); } }); }; } - (void)reciverPhoneCall{ [self appnoactive]; } - (void)phoneCallEnd{ [self appactive]; } #pragma mark - 私信监听 //- (void)onReceiveMessageRetractEvent:(JMSGMessageRetractEvent *)retractEvent;{ // [self requestJmsg]; //} //-(void)onReceiveMessage:(JMSGMessage *)message error:(NSError *)error{ // [self requestJmsg]; //} -(void)requestJmsg { [[YBImManager shareInstance]getAllUnredNumExceptUser:@[@"dsp_admin_1",@"dsp_fans",@"dsp_like",@"dsp_at",@"dsp_comment",@"dsp_user_live",@"goodsorder_admin"] complete:^(int allUnread) { unRead = allUnread; dispatch_async(dispatch_get_main_queue(), ^{ if (_liveCtrlView) { [_liveCtrlView updateUnread:unRead]; } }); }]; } #pragma mark - set/get - (UIImageView *)pkBgIV { if (!_pkBgIV) { _pkBgIV = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, _window_width, _window_height)]; _pkBgIV.contentMode = UIViewContentModeScaleAspectFill; _pkBgIV.clipsToBounds = YES; //_pkBgIV.image = [UIImage imageNamed:@"pk背景"]; _pkBgIV.userInteractionEnabled = YES; _pkBgIV.backgroundColor = RGB_COLOR(@"#1e1e1e", 1); } return _pkBgIV; } - (YBLivePreview *)livePreview { if (!_livePreview) { YBWeakSelf; _livePreview = [[YBLivePreview alloc]initWithFrame:CGRectMake(0, 0, _window_width, _window_height)]; _livePreview.livePreEvent = ^(NSString *eventType, NSString *eventContent) { [weakSelf previewCallBack:eventType andEvnent:eventContent]; }; } return _livePreview; } - (YBLiveCtrlView *)liveCtrlView { if (!_liveCtrlView) { YBWeakSelf; _liveCtrlView = [[YBLiveCtrlView alloc]initWithFrame:CGRectMake(0, 0, _window_width, _window_height)]; _liveCtrlView.hidden = YES; _liveCtrlView.liveCtrEvent = ^(NSString *eventStr, NSDictionary *eventDic) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf controlViewCallBack:eventStr andEvnent:eventDic]; }); }; } return _liveCtrlView; } - (YBLiveEndView *)liveEndView { if (!_liveEndView) { YBWeakSelf; _liveEndView = [[YBLiveEndView alloc]initWithFrame:CGRectMake(0, 0, _window_width, _window_height)]; _liveEndView.liveEndEvent = ^{ [weakSelf clickNaviLeftBtn]; }; } return _liveEndView; } @end