12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048 |
- //
- // LiveRoomViewController.m
- // KulexiuForTeacher
- //
- // Created by 王智 on 2022/6/21.
- //
- #import "LiveRoomViewController.h"
- #import "LivePreviewBodyView.h"
- #import <RongRTCLib/RongRTCLib.h>
- #import <RongIMKit/RongIMKit.h>
- #import <RongFaceBeautifier/RongFaceBeautifier.h>
- #import "KSBeautySettingView.h"
- #import "KSEnterLiveroomManager.h"
- #import "LiveroomTimeManager.h"
- #import "UserInfoManager.h"
- #import <RongIMKit/RongIMKit.h>
- #import "KSChatInputBarControl.h"
- #import "LiveRoomHeadView.h"
- #import "LiveRoomBottomView.h"
- #import "SeatContentView.h"
- #import "SeatTipsView.h"
- #import "KSLiveStreamVideo.h"
- #import "KSRCMessageModel.h"
- #import "KSChatroomMessageCenter.h"
- #import "KSChatroomTextCell.h"
- #import "LiveRoomAlertView.h"
- #import "LiveMoreDisplayView.h"
- #import "LiveAnimationView.h"
- #import "KSShareChooseViewController.h"
- #import "KSChatLiveMessage.h"
- #import "LiveSeatActionView.h"
- typedef NS_ENUM(NSInteger, LIVEPAGE) {
- LIVEPAGE_PREVIEW,
- LIVEPAGE_LIVE,
- };
- @interface LiveRoomViewController ()<RCRTCEngineEventDelegate,RCRTCRoomEventDelegate,RCRTCStatusReportDelegate,UIGestureRecognizerDelegate,KSChatInputBarControlDelegate,UITableViewDataSource,UITableViewDelegate,LiveroomTimeManagerDelegate>
- @property (nonatomic, strong) LiveroomTimeManager *timeManager;
- @property (nonatomic, assign) LIVEPAGE pageType;
- @property (nonatomic, assign) BOOL isPauseLive; // 是否暂停直播
- @property (nonatomic, assign) BOOL isOtherLogin; // 是否被顶掉
- @property (nonatomic, strong) LivePreviewBodyView *previewPageView;
- @property (nonatomic, strong) RCRTCVideoView *preVideoView;
- @property (nonatomic, strong) KSBeautySettingView *settingView;
- @property (nonatomic, assign) BOOL isBeautyOn;
- @property (nonatomic, assign) int filterLevel;
- #pragma mark ------- 直播房间信息
- /*!
- 身份状态 主讲人/观众
- */
- @property (nonatomic, assign) RCRTCLiveRoleType liveRoleType;
- /// 主讲人id
- @property (nonatomic, strong) NSString *createrId;
- /// 主讲人名称
- @property (nonatomic, strong) NSString *createrName;
- /// 主讲人头像
- @property (nonatomic, strong) NSString *createrAvatal;
- // 是否禁止连麦
- @property (nonatomic, assign) BOOL enableSeat;
- // 是否禁止聊天
- @property (nonatomic, assign) BOOL enableChat;
- // 是否允许点赞
- @property (nonatomic, assign) BOOL enableLike;
- @property (nonatomic, assign) NSInteger likeCount;
- /// 房间人数
- @property (nonatomic, assign) NSInteger totalCount;
- #pragma mark ---- Live page
- @property (nonatomic, strong) UIView *livePageView;
- @property (nonatomic, strong) RCRTCRoom *room;
- @property (nonatomic, assign) BOOL isImConnected;
- @property (nonatomic, assign) BOOL hasSendWelcomeMessage;
- @property (nonatomic, strong) KSLiveStreamVideo *localVideo;
- @property (nonatomic, strong) UIView *liveVideoView;
- @property (nonatomic, strong) LiveRoomHeadView *headView;
- @property (nonatomic, copy) LiveRoomBottomView *bottomView;
- /// 连麦的视图
- @property (nonatomic, strong) SeatContentView *seatContainer;
- // 聊天UI
- /*!
- 消息列表CollectionView和输入框都在这个view里
- */
- @property(nonatomic, strong) UIView *messageContentView;
- /*!
- 会话页面的TableView
- */
- @property (nonatomic, strong) UITableView *conversationMessageTableView;
- /*!
- 聊天内容的消息Cell数据模型的数据源
-
- @discussion 数据源中存放的元素为消息Cell的数据模型,即RCDLiveMessageModel对象。
- */
- @property(nonatomic, strong) NSMutableArray<KSRCMessageModel *> *conversationDataRepository;
- /**
- 输入工具栏
- */
- @property(nonatomic,strong) KSChatInputBarControl *inputBar;
- /**
- * 是否需要滚动到底部
- */
- @property(nonatomic, assign) BOOL isNeedScrollToButtom;
- @property (nonatomic, strong) UIView *seatCtrlView;
- @property (nonatomic, strong) LiveSeatActionView *seatActionView;
- @property (nonatomic, strong) NSMutableArray *seatApplyArray; // 申请连麦数组
- // 远端连麦用户
- @property (nonatomic, strong) NSMutableArray *remoteMemberArray;
- /// 连麦申请统计数据
- @property (nonatomic, strong) SeatTipsView *seatApplyTips;
- /// 提示窗
- @property (nonatomic, strong) LiveRoomAlertView *alertView;
- // 定时器
- @property (nonatomic, strong) dispatch_source_t timer;
- @property (nonatomic, strong) LiveMoreDisplayView *moreView;
- @property (nonatomic) LiveAnimationView *animationView;
- /// 直播课结束时间
- @property (nonatomic, strong) NSString *liveEndTime;
- /// 直播间关闭延迟时间
- @property (nonatomic, assign) NSInteger expiredCloseMinute;
- @property (nonatomic, copy) LiveRoomBackAction callback;
- @property (nonatomic, strong) UITapGestureRecognizer *gesture;
- @property (nonatomic, assign) BOOL needPublishStream;
- @end
- @implementation LiveRoomViewController
- - (void)backRefreshCallback:(LiveRoomBackAction)callback {
- if (callback) {
- self.callback = callback;
- }
- }
- - (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
- self.ks_prefersNavigationBarHidden = YES;
- self.isOtherLogin = NO;
- [self registerOtherLoginNotice];
- [self configUI];
- [self configEngine];
- self.pageType = LIVEPAGE_PREVIEW;
- }
- - (void)registerOtherLoginNotice {
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveroomLogOut) name:@"liveroomLogout" object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveroomQuit) name:@"liveroomQuit" object:nil];
- }
- - (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear:animated];
- [UIApplication sharedApplication].idleTimerDisabled = YES;
- [IQKeyboardManager sharedManager].enableAutoToolbar = NO;
- [IQKeyboardManager sharedManager].enable = NO;
- [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
- }
- - (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
- [UIApplication sharedApplication].idleTimerDisabled = NO;
- [IQKeyboardManager sharedManager].enableAutoToolbar = YES;
- [IQKeyboardManager sharedManager].enable = YES;
- if (@available(iOS 13.0, *)) {
- [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDarkContent;
- } else {
- // Fallback on earlier versions
- [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
- }
- }
- - (void)configUI {
- self.previewPageView = [LivePreviewBodyView shareInstance];
- [self.view addSubview:self.previewPageView];
- [self.previewPageView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.bottom.top.mas_equalTo(self.view);
- }];
- MJWeakSelf;
- [self.previewPageView previewOperationCallback:^(PREVIEWLIVEACTION action) {
- [weakSelf previewOperationAction:action];
- }];
- [[RCRTCBeautyEngine sharedInstance] reset];
- }
- - (void)configEngine {
- if (!self.preVideoView) {
- self.preVideoView = [[RCRTCVideoView alloc] init];
- self.preVideoView.fillMode = RCRTCVideoFillModeAspectFill;
- self.preVideoView.frameAnimated = NO;
- [self.previewPageView.videoView addSubview:self.preVideoView];
- [self.preVideoView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.top.bottom.right.mas_equalTo(self.previewPageView.videoView);
- }];
- }
- [[RCRTCEngine sharedInstance].defaultVideoStream setVideoView:self.preVideoView];
- RCRTCVideoStreamConfig *videoConfig = [RCRTCEngine sharedInstance].defaultVideoStream.videoConfig;
- videoConfig.videoSizePreset = RCRTCVideoSizePreset1920x1080;
- [[RCRTCEngine sharedInstance].defaultVideoStream setVideoConfig:videoConfig];
- [[RCRTCEngine sharedInstance].defaultVideoStream startCapture];
- self.filterLevel = 50;
- }
- - (void)previewOperationAction:(PREVIEWLIVEACTION)action {
- switch (action) {
- case PREVIEWLIVEACTION_BACK: // 返回
- {
- if (self.isPauseLive) { // 退出RTC房间
- [self quitRoomBackPreView:NO];
- }
- else {
- self.room = nil;
- self.preVideoView = nil;
- [[RCRTCEngine sharedInstance].defaultVideoStream stopCapture];
- if (self.callback) {
- self.callback();
- }
- [self.navigationController dismissViewControllerAnimated:YES completion:nil];
- }
- }
- break;
- case PREVIEWLIVEACTION_SWITCH: // 切换
- {
- [[RCRTCEngine sharedInstance].defaultVideoStream switchCamera];
- }
- break;
- case PREVIEWLIVEACTION_BEAUTY: // 美颜
- {
- [self displayBeautyView];
- }
- break;
- case PREVIEWLIVEACTION_SHARE: // 分享
- {
- [self shareLiveRoomMessage];
- }
- break;
- case PREVIEWLIVEACTION_OPEN: // 进入直播间
- {
- [self showLiveView];
- }
- break;
- default:
- break;
- }
- }
- - (void)shareLiveRoomMessage {
- // 选择群组分享
- KSChatLiveMessage *liveShareMsg = [[KSChatLiveMessage alloc] init];
- liveShareMsg.roomUID = self.roomId;
- NSString *teacherName = UserDefaultObjectForKey(NicknameKey);
- if ([NSString isEmptyString:teacherName]) {
- teacherName = [NSString stringWithFormat:@"游客%@",UserDefaultObjectForKey(UIDKey)];
- }
- liveShareMsg.teacherName = teacherName;
- liveShareMsg.teacherAvatar = UserDefaultObjectForKey(AvatarUrlKey);
- liveShareMsg.liveDescMessage = self.liveContent;
-
- KSShareChooseViewController *chooseCtrl = [[KSShareChooseViewController alloc] init];
- chooseCtrl.msgContent = liveShareMsg;
- [self.navigationController pushViewController:chooseCtrl animated:YES];
- }
- - (void)displayBeautyView {
- [self displayBottomView:YES];
- if (_settingView == nil) {
-
- RCRTCBeautyOption *option = [[RCRTCBeautyEngine sharedInstance] getCurrentBeautyOption];
- RCRTCBeautyFilter filter = [[RCRTCBeautyEngine sharedInstance] getCurrentBeautyFilter];
- FILTER_TYPE type = [self getFilterType:filter];
- MJWeakSelf;
- [self.settingView evaluateMessageWithWhite:option.whitenessLevel smoothLevel:option.smoothLevel ruddyLevel:option.ruddyLevel brightLevel:option.brightLevel filter:type filterLevel:self.filterLevel callback:^(BOOL isOpenBeauty, NSInteger white, NSInteger smoothLevel, NSInteger ruddyLevel, NSInteger brightLevel, FILTER_TYPE type, int filterLevel) {
- [weakSelf configSettingBeauty:YES white:white smoothLevel:smoothLevel ruddyLevel:ruddyLevel brightLevel:brightLevel filter:[self getRongBeautyWithType:type] filterLevel:filterLevel];
- }];
- }
-
- [self.view addSubview:self.settingView];
- [self.settingView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.top.bottom.mas_equalTo(self.view);
- }];
- }
- - (FILTER_TYPE)getFilterType:(RCRTCBeautyFilter)filter {
- switch (filter) {
- case RCRTCBeautyFilterNone:
- return FILTER_TYPE_NONE;
- case RCRTCBeautyFilterFresh:
- return FILTER_TYPE_QINGXIN;
- case RCRTCBeautyFilterEsthetic:
- return FILTER_TYPE_WEIMEI;
- case RCRTCBeautyFilterRomantic:
- return FILTER_TYPE_LANGMAN;
- default:
- return FILTER_TYPE_NONE;
- break;
- }
- }
- - (RCRTCBeautyFilter)getRongBeautyWithType:(FILTER_TYPE)type {
- switch (type) {
- case FILTER_TYPE_NONE:
- return RCRTCBeautyFilterNone;
- case FILTER_TYPE_QINGXIN:
- return RCRTCBeautyFilterFresh;
- case FILTER_TYPE_WEIMEI:
- return RCRTCBeautyFilterEsthetic;
- case FILTER_TYPE_LANGMAN:
- return RCRTCBeautyFilterRomantic;
- default:
- return RCRTCBeautyFilterNone;
- break;
- }
- }
- - (void)configSettingBeauty:(BOOL)isOn white:(NSInteger)whitenessLevel smoothLevel:(NSInteger)smoothLevel ruddyLevel:(NSInteger)ruddyLevel brightLevel:(NSInteger)brightLevel filter:(RCRTCBeautyFilter)filter filterLevel:(int)filterLevel {
- self.isBeautyOn = isOn;
- if (isOn) {
- // 获取当前美颜参数
- RCRTCBeautyOption *option = [[RCRTCBeautyEngine sharedInstance] getCurrentBeautyOption];
- // 修改参数
- option.whitenessLevel = whitenessLevel;
- option.smoothLevel = smoothLevel;
- option.ruddyLevel = ruddyLevel;
- option.brightLevel = brightLevel;
- // 设置美颜
- [[RCRTCBeautyEngine sharedInstance] setBeautyOption:isOn option:option];
- // 设置滤镜
- [[RCRTCBeautyEngine sharedInstance] setBeautyFilter:filter];
- // 设置滤镜强度
- [[RCRTCBeautyEngine sharedInstance] setFilterIntensity:filterLevel];
- }
- else {
- [[RCRTCBeautyEngine sharedInstance] reset];
- }
- }
- - (void)showLiveView {
- if (self.isPauseLive) { // 直接切换页面
- self.pageType = LIVEPAGE_LIVE;
- [self.view addSubview:self.livePageView];
- [self.livePageView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.top.bottom.mas_equalTo(self.view);
- }];
- // 开启推流
- [self startPublishStream];
- }
- else {
- [self showhud];
- MJWeakSelf;
- [KSEnterLiveroomManager queryLiveroomConfig:self.roomId callback:^(NSDictionary * _Nullable parm) {
- [weakSelf removehub];
- if (parm != nil) {
- [weakSelf setupLiveroomConfig:parm];
- [weakSelf createLivePageViewDisplay];
- }
- }];
- }
- }
- - (void)startPublishStream {
- self.pageType = LIVEPAGE_LIVE;
- self.isPauseLive = NO;
- [self publishLocalStream];
- }
- - (void)setupLiveroomConfig:(NSDictionary *)source {
- NSLog(@"room config----- %@",source);
- self.liveRoleType = RCRTCLiveRoleTypeBroadcaster;
- self.createrId = [source stringValueForKey:@"speakerId"];
- self.createrName = [source stringValueForKey:@"speakerName"];
- self.createrAvatal = [source stringValueForKey:@"speakerPic"];
- self.likeCount = [source integerValueForKey:@"likeNum"]; // 点赞数
- NSInteger lookCount = [source integerValueForKey:@"lookNum"];
- self.totalCount = lookCount; // 观看人数
- NSString *roomConfig = [source stringValueForKey:@"roomConfig"];
- NSData *jsonData = [roomConfig dataUsingEncoding:NSUTF8StringEncoding];
- NSError *err;
- NSDictionary *configDic = [NSJSONSerialization JSONObjectWithData:jsonData
- options:NSJSONReadingMutableContainers
- error:&err];
- if (configDic) {
- self.enableChat = ![configDic boolValueForKey:@"whether_chat"];
- self.enableSeat = ![configDic boolValueForKey:@"whether_mic"];
- self.enableLike = ![configDic boolValueForKey:@"whether_like"];
- }
- BOOL isTemp = [[source stringValueForKey:@"roomType"] isEqualToString:@"TEMP"];
- self.isTempRoom = isTemp;
- if (isTemp == NO) {
- self.liveEndTime = [source stringValueForKey:@"liveEndTime"];
- self.expiredCloseMinute = [source integerValueForKey:@"expiredCloseMinute"];
- }
- else {
- self.liveEndTime = [source stringValueForKey:@"liveEndTime"];
- self.expiredCloseMinute = 0;
- }
-
-
- }
- - (void)createLivePageViewDisplay {
- self.pageType = LIVEPAGE_LIVE;
- self.isImConnected = [USER_MANAGER checkIMConnected];
- [self registerNotification];
- [self setupUI];
- [self configIMConnect];
- [self startTimer];
- }
- #pragma mark --- settingView
- - (KSBeautySettingView *)settingView {
- if (!_settingView) {
- _settingView = [KSBeautySettingView shareInstance];
- MJWeakSelf;
- [_settingView hiddenViewCallback:^{
- [weakSelf displayBottomView:NO];
- }];
-
- }
- return _settingView;
- }
- - (void)displayBottomView:(BOOL)isHidden {
- if (isHidden) {
- self.previewPageView.functionView.hidden = YES;
- }
- else {
- self.previewPageView.functionView.hidden = NO;
- }
- }
- #pragma mark ------- Live page
- - (void)startTimer {
- if (self.timer) {
- dispatch_resume(self.timer);
- }
- }
- - (void)registerNotification {
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(IMConnetedCallback) name:@"RongIMConnected" object:nil];
- [KSChatroomMessageCenter registerMessageTypes];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMessageNotification:) name:OnReceiveChatroomMessageNotification object:nil];
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnterBackground) name:@"appEnterBackground" object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appBecomeActive) name:@"appBecomeActive" object:nil];
- [self configTimerManager];
- }
- - (void)configTimerManager {
-
- self.timeManager.endClassTime = self.liveEndTime;
- self.timeManager.autoCloseNetworkRoomTime = [self getCloseTime];
- self.timeManager.isTempRoom = self.isTempRoom;
- }
- #pragma mark ------ enter back ground
- - (void)appEnterBackground {
- self.isEnterBackground = YES;
- if (self.isPauseLive == NO) { // 暂停推流
- [self pauseLiveActionBack:NO];
- }
- }
- - (void)appBecomeActive {
- if (self.isEnterBackground && self.pageType == LIVEPAGE_LIVE && self.isOtherLogin == NO) {
- if ([USER_MANAGER checkIMConnected]) {
- // 开启推流
- [self startPublishStream];
- }
- else {
- self.needPublishStream = YES;
- }
-
- }
- self.isEnterBackground = NO;
- }
- - (void)setupUI {
- CGSize size = self.view.bounds.size;
- [self.view addSubview:self.livePageView];
- [self.livePageView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.top.bottom.mas_equalTo(self.view);
- }];
-
- [self.livePageView addSubview:self.liveVideoView];
- [self.liveVideoView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.top.bottom.right.mas_equalTo(self.livePageView);
- }];
-
- [self.livePageView addSubview:self.headView];
-
- [self.headView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.mas_equalTo(self.livePageView);
- make.height.mas_equalTo(90);
- if (@available(iOS 11.0, *)) {
- make.top.mas_equalTo(self.livePageView.mas_safeAreaLayoutGuideTop).offset(10);
- } else {
- // Fallback on earlier versions
- make.top.mas_equalTo(self.livePageView.mas_top).offset(10);
- }
- }];
- [self.livePageView addSubview:self.messageContentView];
- [self.livePageView addSubview:self.bottomView];
-
- self.headView.boardcastName.text = [NSString returnNoNullStringWithString:self.createrName];
- if (![NSString isEmptyString:self.createrAvatal]) {
- [self.headView.boardcastAvatal sd_setImageWithURL:[NSURL URLWithString:[self.createrAvatal getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"teacher_logo"]];
- }
- [self countLikeMessageCount];
-
- [self.headView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.mas_equalTo(self.livePageView);
- make.height.mas_equalTo(90);
- if (@available(iOS 11.0, *)) {
- make.top.mas_equalTo(self.livePageView.mas_safeAreaLayoutGuideTop).offset(10);
- } else {
- // Fallback on earlier versions
- make.top.mas_equalTo(self.livePageView.mas_top).offset(10);
- }
- }];
- [self.livePageView addSubview:self.messageContentView];
- [self.livePageView addSubview:self.bottomView];
-
- [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.mas_equalTo(self.livePageView);
- if (@available(iOS 11.0, *)) {
- make.bottom.mas_equalTo(self.livePageView.mas_safeAreaLayoutGuideBottom).offset(-5);
- } else {
- // Fallback on earlier versions
- make.bottom.mas_equalTo(self.livePageView.mas_bottom).offset(-5);
- }
- make.height.mas_equalTo(44);
- }];
-
- [self.messageContentView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.mas_equalTo(self.livePageView.mas_left);
- make.right.mas_equalTo(self.livePageView.mas_right);
- make.bottom.mas_equalTo(self.bottomView.mas_top).offset(-5);
- make.height.mas_equalTo(180);
- }];
- [self.livePageView addSubview:self.inputBar];
- [_inputBar setBackgroundColor: [UIColor whiteColor]];
-
- [_inputBar setFrame:CGRectMake(0, kScreenHeight, size.width , 50)];
- [_inputBar setHidden:YES];
-
- [self.messageContentView addSubview:self.conversationMessageTableView];
- [self.conversationMessageTableView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.top.mas_equalTo(self.messageContentView);
- make.width.mas_equalTo(KPortraitWidth);
- make.bottom.mas_equalTo(self.messageContentView.mas_bottom);
- }];
-
- [self.livePageView addSubview:self.seatApplyTips];
- [self.seatApplyTips hideView];
- [self.seatApplyTips mas_makeConstraints:^(MASConstraintMaker *make) {
- make.bottom.mas_equalTo(self.bottomView.mas_top).offset(2);
- make.height.mas_equalTo(20);
- make.left.mas_equalTo(self.bottomView.mas_right).offset(-72);
- }];
-
- UITapGestureRecognizer *resetBottomTapGesture =[[UITapGestureRecognizer alloc]
- initWithTarget:self
- action:@selector(resetBottomGesture:)];
- resetBottomTapGesture.delegate = self;
- [self.livePageView addGestureRecognizer:resetBottomTapGesture];
- }
- - (void)joinChatRoom {
-
- [[RCIMClient sharedRCIMClient] joinChatRoom:self.roomId messageCount:-1 success:^{
- dispatch_async(dispatch_get_main_queue(), ^{
- [self addConstMessage];
- });
- KSLiveChatroomWelcome *joinChatroomMessage = [[KSLiveChatroomWelcome alloc] init];
- [joinChatroomMessage setMsgId:[RCIM sharedRCIM].currentUserInfo.userId];
- MJWeakSelf;
- [self sendMessage:joinChatroomMessage displayMessage:NO callback:^(BOOL success) {
- weakSelf.hasSendWelcomeMessage = YES;
- }];
- // 加入成功发送消息
-
- } error:^(RCErrorCode status) {
- if (status == RC_CHATROOM_NOT_EXIST || status == KICKED_FROM_CHATROOM || status == RC_PARAMETER_INVALID_CHATROOM) {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self MBPShow:@"加入聊天室失败"];
- });
- }
- }];
- }
- - (void)configIMConnect {
- if (self.isImConnected == YES) {
- [self connectionService];
- }
- else {
- MJWeakSelf;
- [USER_MANAGER connectionIMCallback:^(BOOL isSuccess) {
- dispatch_main_async_safe(^{
- [weakSelf connectionService];
- });
- }];
- }
- }
- - (void)IMConnetedCallback {
-
- dispatch_main_async_safe(^{
- // IM 连接成功回调
- if (self.hasSendWelcomeMessage) { // 如果已经发送了进入消息
- // 查询是否直播间开启
- [KSNetworkingManager speakerCheckRoomInfoRequest:KS_GET roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
- if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
- // 回调信息
- MJWeakSelf;
- [self notiferJoinSuccessToServiceCallback:^{
- [weakSelf MBPShow:@"IM连接成功"];
- [weakSelf sendWelcomeMessage];
- }];
- }
- else {
- [self MBPShow:MESSAGEKEY];
- [self quitRoomBackPreView:NO];
- }
- } faliure:^(NSError * _Nonnull error) {
-
- }];
- }
- if (self.needPublishStream) {
- [self startPublishStream];
- }
- });
- }
- - (void)sendWelcomeMessage {
- MJWeakSelf;
- [[RCIMClient sharedRCIMClient] joinExistChatRoom:self.roomId messageCount:-1 success:^{
- KSLiveChatroomWelcome *joinChatroomMessage = [[KSLiveChatroomWelcome alloc] init];
- [joinChatroomMessage setMsgId:[RCIM sharedRCIM].currentUserInfo.userId];
- [self sendMessage:joinChatroomMessage displayMessage:NO callback:^(BOOL success) {
- [weakSelf joinRTCRoom];
- }];
- } error:^(RCErrorCode status) {
- NSLog(@"error code %zd" ,status);
- }];
- }
- - (void)joinRTCRoom {
- [self setRoleType];
- }
- - (void)liveroomLogOut {
- if (self.isOtherLogin) {
- return;
- }
- self.isOtherLogin = YES;
- [self MBPShow:@"该账号在其他设备上登录"];
- [self quitRoomBackPreView:NO];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-
- [[NSNotificationCenter defaultCenter] postNotificationName:@"liveroomBackRefresh" object:nil];
- });
- }
- - (void)liveroomQuit {
- if (self.isOtherLogin) {
- return;
- }
- self.isOtherLogin = YES;
- [self quitRoomBackPreView:NO];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [[NSNotificationCenter defaultCenter] postNotificationName:@"liveroomBackRefresh" object:nil];
- });
- }
-
- - (void)connectionService {
- [self setRoleType];
- [self joinChatRoom];
- }
- - (void)countLikeMessageCount {
- NSInteger count = self.likeCount;
- NSString *desc = @"";
- if (count > 10000) {
- count = count / 10000;
- desc = [NSString stringWithFormat:@"本场点赞%zd万+",count];
- }
- else {
- desc = [NSString stringWithFormat:@"本场点赞%zd",count];
- }
- self.headView.likeCount.text = desc;
- }
- - (void)countMemberCount {
- NSInteger count = self.totalCount;
- NSString *desc = @"";
- if (count > 10000) {
- count = count / 10000;
- desc = [NSString stringWithFormat:@"%zd万+人",count];
- }
- else {
- desc = [NSString stringWithFormat:@"%zd人",count];
- }
- self.headView.roomMemberCount.text = desc;
- }
- // 刷新seatView
- - (void)renderSeatView {
- NSMutableArray *seatArray = [NSMutableArray array];
- NSArray *remoteUserArray = [self.room.remoteUsers mutableCopy];
- for (RCRTCRemoteUser *user in remoteUserArray) {
- if (![user.userId containsString:@"rc_mc_"]) {
- [seatArray addObject:user.userId];
- }
- }
- if (seatArray.count) {
- if (![self.livePageView.subviews containsObject:self.seatContainer]) {
- [self.livePageView addSubview:self.seatContainer];
- }
-
- [self.seatContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
- make.left.right.mas_equalTo(self.livePageView);
- make.top.mas_equalTo(self.headView.mas_bottom).offset(10);
- make.height.mas_equalTo(80);
- }];
-
- self.seatContainer.seatMemberArray = [NSMutableArray arrayWithArray:seatArray];
- [self.seatContainer refreshSeatUI];
- }
- else {
- [self removeSeatContainer];
- }
- }
- - (void)removeSeatContainer {
- if ([self.livePageView.subviews containsObject:self.seatContainer]) {
- [self.seatContainer removeFromSuperview];
- }
- }
- - (void)setRoleType {
- // 1.设置切换听筒为扬声器
- [[RCRTCEngine sharedInstance] setDefaultAudioRouteToSpeaker:YES];
- [RCRTCEngine sharedInstance].statusReportDelegate = self;
- // 2.添加本地采集预览界面
- [self setupLocalVideoView];
- // 3.加入RTC房间
- [self joinRTCLiveRoom];
- }
- // 添加本地采集预览页面
- - (void)setupLocalVideoView {
- [self.liveVideoView addSubview:self.localVideo.canvesView];
- [self.localVideo.canvesView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.top.bottom.mas_equalTo(self.liveVideoView);
- }];
- }
- #pragma mark ----- RCRTCStatusReportDelegate
- - (void)didReportStatusForm:(RCRTCStatusForm *)form {
- BOOL isConnectedFailed = NO;
- for (RCRTCStreamStat* stat in form.sendStats) {
- if (stat.packetLoss == 1.0) {
- isConnectedFailed = YES;
- break;
- }
- }
-
- [self showNetStatus:form.rtt networkLost:isConnectedFailed];
- // NSLog(@"%@",form.description);
- // 网络状态差提示
-
- }
- - (void)showNetStatus:(NSInteger)rttValue networkLost:(BOOL)isFailed {
- dispatch_main_async_safe((^{
- if (isFailed) {
- [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_bad"]];
- self.headView.msLabel.text = @"网络已断开";
- }
- else {
- self.headView.msLabel.text = [NSString stringWithFormat:@"%zdms",rttValue];
- if (rttValue < 100) {
- [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_good"]];
- }
- else if (rttValue < 200) {
- [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_nomal"]];
- }
- else {
- [self.headView.rttImage setImage:[UIImage imageNamed:@"live_networking_bad"]];
- }
- }
-
- }));
- }
- #pragma mark ---- RCRTCRoomEventDelegate
- // 远端发布流
- - (void)didPublishStreams:(NSArray<RCRTCInputStream *> *)streams {
- [self subscribeRemoteResource:streams];
- NSLog(@"didPublishStreams --------");
- }
- // 订阅远端流
- - (void)subscribeRemoteResource:(NSArray<RCRTCInputStream *> *)streams {
- [self subscribeRemoteResource:streams isTiny:NO];
- }
- - (void)subscribeRemoteResource:(NSArray<RCRTCInputStream *> *)streams isTiny:(BOOL)isTiny {
- // 订阅房间中远端用户音视频流资源
- NSArray *tinyStream = isTiny ? streams : @[];
- NSArray *ordinaryStream = isTiny ? @[] : streams;
- MJWeakSelf;
- [self.room.localUser subscribeStream:ordinaryStream
- tinyStreams:tinyStream
- completion:^(BOOL isSuccess, RCRTCCode desc) {
- if (desc != RCRTCCodeSuccess) {
- NSString *errorStr = [NSString stringWithFormat:@"订阅远端流失败:%ld", (long) desc];
- [weakSelf MBPShow:errorStr];
- return;
- }
- }];
- [self renderSeatView];
- }
- - (void)didUnpublishStreams:(NSArray<RCRTCInputStream *> *)streams {
- NSLog(@"didUnPublishStreams --------");
- [self renderSeatView];
- }
- - (void)didOfflineUser:(RCRTCRemoteUser *)user {
- [self renderSeatView];
- }
- - (void)didJoinUser:(RCRTCRemoteUser *)user {
- NSLog(@"--didJoinUser-");
- // [self renderSeatView];
- }
- // 如果有远端用户离开房间
- - (void)didLeaveUser:(RCRTCRemoteUser *)user {
- NSLog(@"--didLeaveUser-");
- // 如果有人离开房间
- if ([self judgeContainMember:user.userId]) {
- [self removeMember:user.userId];
- [self refreshSeatApplyView];
- }
- [self renderSeatView];
- }
- // 远端用户切换身份
- - (void)didSwitchRoleWithUser:(RCRTCRemoteUser *)user roleType:(RCRTCLiveRoleType)roleType {
- if (roleType == RCRTCLiveRoleTypeBroadcaster) {
- if ([self judgeContainUser:user.userId] == NO) {
- [self.remoteMemberArray addObject:user];
- // 刷新连麦成员状态数据
- if ([self judgeContainMember:user.userId]) {
- // 更新状态
- [self updateMemberStatusConnecting:user.userId];
- [self refreshSeatApplyView];
- }
- }
- }
- else {
- [self removeMemberUserId:user.userId];
- // 刷新连麦成员数据
- if ([self judgeContainMember:user.userId]) {
- [self removeMember:user.userId];
- [self refreshSeatApplyView];
- }
- }
- [self renderSeatView];
-
- NSLog(@"didSwitchRoleWithUser --------");
- }
- - (BOOL)judgeContainUser:(NSString *)userId {
- BOOL containUser = NO;
- for (RCRTCRemoteUser *remoteUser in self.remoteMemberArray) {
- if ([remoteUser.userId isEqualToString:userId]) {
- containUser = YES;
- }
- }
- return containUser;
- }
- - (BOOL)getUserConnectStatus:(NSString *)userId {
- BOOL isConnected = NO;
- for (LiveSeatMember *member in self.seatApplyArray) {
- if ([member.userId isEqualToString:userId]) {
- return member.isConnected;
- }
- }
- return isConnected;
- }
- - (void)removeMemberUserId:(NSString *)userId {
- for (RCRTCRemoteUser *remoteUser in self.remoteMemberArray) {
- if ([remoteUser.userId isEqualToString:userId]) {
- [self.remoteMemberArray removeObject:remoteUser];
- return;
- }
- }
- }
- #pragma mark - KSChatInputBarControlDelegate
- // 根据inputBar 回调来修改页面布局
- - (void)onInputBarControlContentSizeChanged:(CGRect)frame withAnimationDuration:(CGFloat)duration andAnimationCurve:(UIViewAnimationCurve)curve {
- CGRect originFrame = _inputBar.frame;
- __weak __typeof(&*self)weakSelf = self;
- // 目前只使用y值即可 -- 只修改messageContentView高度,让展示消息view和输入框随之移动
- [UIView animateWithDuration:duration animations:^{
- [UIView setAnimationCurve:curve];
- [weakSelf.inputBar setFrame:CGRectMake(0, frame.origin.y - originFrame.size.height, originFrame.size.width, originFrame.size.height)];
- [UIView commitAnimations];
- }];
- }
- // 发送消息
- - (void)onTouchSendButton:(NSString *)text {
- [self touristSendMessage:text];
- }
- - (void)touristSendMessage:(NSString *)text {
-
- RCTextMessage *rcTextMessage = [RCTextMessage messageWithContent:text];
- MJWeakSelf;
- [self sendMessage:rcTextMessage displayMessage:YES callback:^(BOOL success) {
- [weakSelf setDefaultBottomViewStatus];
- }];
- }
- #pragma mark ---- RTC
- - (void)joinRTCLiveRoom {
- // 1.配置房间
- RCRTCRoomConfig *config = [[RCRTCRoomConfig alloc] init];
- config.roomType = RCRTCRoomTypeLive;
- config.liveType = RCRTCLiveTypeAudioVideo;
- config.roleType = RCRTCLiveRoleTypeBroadcaster;
- __weak typeof(self) weakSelf = self;
- [[RCRTCEngine sharedInstance] joinRoom:self.roomId config:config completion:^(RCRTCRoom * _Nullable room, RCRTCCode code) {
- dispatch_main_async_safe(^{
- __strong typeof(weakSelf) strongSelf = weakSelf;
- if (code == RCRTCCodeSignalServerNotConnect || code == RCRTCCodeParameterError || code == RCRTCCodeNotInRTCRoom || code == RCRTCCodeRTCTokenIsNull || code == RCRTCCodeHttpTimeoutError || code == RCRTCCodeHttpError || code == RCRTCCodeVoIPNotAvailable) {
- NSLog(@"%@",[NSString stringWithFormat:@"加入失败 code %ld",code]);
- [strongSelf MBPShow:@"加入直播间失败"];
- // [strongSelf.navigationController dismissViewControllerAnimated:YES completion:nil];
- }
- else {
- [strongSelf notiferJoinSuccessToServiceCallback:^{
-
- }];
- if (room) {
- strongSelf.room = room;
- strongSelf.room.delegate = self;
- }
- [strongSelf countMemberCount];
- // 发布本地视频流
- if (strongSelf.isPauseLive == NO && strongSelf.isEnterBackground == NO) {
- [strongSelf publishLocalStream];
- }
- }
-
- });
- }];
- }
- - (void)publishLocalStream {
- // 1.设置渲染视图渲染视图
- [[RCRTCEngine sharedInstance].defaultVideoStream setVideoView:self.localVideo.canvesView];
- // 2.设置视频流参数
- RCRTCVideoStreamConfig *videoConfig = [RCRTCEngine sharedInstance].defaultVideoStream.videoConfig;
- videoConfig.videoSizePreset = RCRTCVideoSizePreset1280x720;
- videoConfig.videoFps = RCRTCVideoFPS30;
- [[RCRTCEngine sharedInstance].defaultVideoStream setVideoConfig:videoConfig];
- // 3.开始视频采集
- [[RCRTCEngine sharedInstance].defaultVideoStream startCapture];
- [RCRTCEngine sharedInstance].defaultVideoStream.enableTinyStream = NO;
- [[RCRTCEngine sharedInstance].defaultAudioStream setAudioQuality:RCRTCAudioQualityMusicHigh Scenario:RCRTCAudioScenarioMusicChatRoom];
- // 发布本地视频流到房间
- MJWeakSelf;
- [self.room.localUser publishDefaultLiveStreams:^(BOOL isSuccess, RCRTCCode code, RCRTCLiveInfo * _Nullable liveInfo) {
- if (code == RCRTCCodeSuccess) {
- weakSelf.needPublishStream = NO;
- }
- else {
- [weakSelf MBPShow:@"视频流发布失败"];
- }
- }];
- }
- - (void)exitRoomCallback:(void(^)(BOOL success))callback {
- [[RCRTCEngine sharedInstance].defaultVideoStream stopCapture];
- _localVideo = nil;
- _preVideoView = nil;
- _room = nil;
- MJWeakSelf;
- [[RCRTCEngine sharedInstance] leaveRoom:^(BOOL isSuccess, RCRTCCode code) {
- dispatch_main_async_safe(^{
- [weakSelf sendLeaveMessageCallback:^(BOOL success) {
- callback(success);
- }];
- });
- }];
- }
- // 销毁房间
- - (void)distoryRoomCallback:(void(^)(BOOL success))callback {
- [[RCRTCEngine sharedInstance].defaultVideoStream stopCapture];
- _localVideo = nil;
- _preVideoView = nil;
- _room = nil;
- __weak typeof(self) weakSelf = self;
- [[RCRTCEngine sharedInstance] leaveRoom:^(BOOL isSuccess, RCRTCCode code) {
- dispatch_main_async_safe(^{
- __strong typeof(weakSelf) strongSelf = weakSelf;
- [strongSelf sendLeaveMessageCallback:^(BOOL success) {
- callback(success);
- }];
- });
- }];
- }
- #pragma mark -- 加入直播间和退出直播间回到服务
- - (void)notiferJoinSuccessToServiceCallback:(void(^)(void))callback {
- [KSNetworkingManager liveRoomJoinRoomRequest:KS_GET roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
- callback();
- } faliure:^(NSError * _Nonnull error) {
- callback();
- }];
- }
- #pragma mark -- 退出直播间回掉服务
- - (void)quitNotiferService {
- [KSNetworkingManager LiveroomQuit:KS_POST success:^(NSDictionary * _Nonnull dic) {
- if ([dic integerValueForKey:@"errCode"] == 0) {
- NSLog(@"success");
- }
- else {
- NSLog(@"----- error %@", [dic stringValueForKey:@"errMsg"]);
- }
- } faliure:^(NSError * _Nonnull error) {
-
- }];
- }
- - (void)closeRoomNotiferService {
- [KSNetworkingManager destroyLiveRoomRequest:KS_GET roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
- if ([dic integerValueForKey:@"errCode"] == 0) {
- NSLog(@"success");
- }
- else {
- NSLog(@"----- error %@", [dic stringValueForKey:@"errMsg"]);
- }
- } faliure:^(NSError * _Nonnull error) {
-
- }];
-
- }
- - (void)sendLeaveMessageCallback:(void(^)(BOOL success))callback {
-
- RCUserInfo *currentUserInfo = [RCIM sharedRCIM].currentUserInfo;
- KSLiveChatroomLeave *leaveMessage = [[KSLiveChatroomLeave alloc] init];
- leaveMessage.userId = currentUserInfo.userId;
- leaveMessage.userName = currentUserInfo.name;
- [self sendMessage:leaveMessage displayMessage:NO callback:^(BOOL success) {
- callback(success);
- }];
- }
- - (void)quitChatRoom {
- [[RCIMClient sharedRCIMClient] quitChatRoom:self.roomId success:^{
- NSLog(@"sucess log out--");
- } error:^(RCErrorCode status) {
- NSLog(@"RCErrorCode------%ld ", (long)status);
- }];
- }
- - (void)addConstMessage { // 固定欢迎词语
- RCTextMessage *statement = [RCTextMessage messageWithContent:@"欢迎进入直播课堂,请遵守相关法规,禁止传播低俗、暴力等不良信息。为孩子创造健康绿色的学习环境。"];
- statement.extra = @"statement";
- RCMessage *constMessage = [[RCMessage alloc] initWithType:ConversationType_CHATROOM targetId:self.roomId direction:MessageDirection_SEND content:statement];
- constMessage.content.senderUserInfo = [RCIM sharedRCIM].currentUserInfo;
- [self appendAndDisplayMessage:constMessage];
- }
- #pragma mark - views init
- /**
- * 接收到消息的回调
- */
- - (void)didReceiveMessageNotification:(NSNotification *)notification {
- NSDictionary *dic = notification.object;
- __block RCMessage *rcMessage = dic[@"message"];
- KSRCMessageModel *model = [[KSRCMessageModel alloc] initWithMessage:rcMessage];
- model.userInfo = rcMessage.content.senderUserInfo;
- if (model.conversationType == ConversationType_CHATROOM && [model.targetId isEqualToString:self.roomId]) {
- __weak typeof(&*self) __blockSelf = self;
- dispatch_main_async_safe((^{
- // 对赞消息拦截 ,展示动画,不插入数据源 ,对于seat消息 和踢出消息,弹出alert
- if (rcMessage) {
- // 👍🏻消息
- if ([rcMessage.content isMemberOfClass:[KSLiveChatroomLike class]]) {
- KSLiveChatroomLike *likeMessage = (KSLiveChatroomLike *)rcMessage.content;
- // 统计点赞数量
- __blockSelf.likeCount += likeMessage.counts;
- [__blockSelf countLikeMessageCount];
- }
- else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomWelcome class]]) {
- // 过滤自己发送的欢迎消息
- if ([rcMessage.senderUserId isEqualToString:UserDefault(UIDKey)]) {
- return;
- }
- // 弹幕
- RCUserInfo *userInfo = rcMessage.content.senderUserInfo;
- NSString *userName = [userInfo.name stringByAppendingString:@""];
- NSString *contentMsg = [NSString stringWithFormat:@"%@ 进入直播间",userName];
- [__blockSelf showAnimationView:YES showMessag:contentMsg];
-
- if ([__blockSelf judgeContainMember:rcMessage.senderUserId]) {
- [__blockSelf removeMember:rcMessage.senderUserId];
- [__blockSelf refreshSeatApplyView];
- [__blockSelf renderSeatView];
- }
- }
- else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomMemberUp class]]) {
- KSLiveChatroomMemberUp *member = (KSLiveChatroomMemberUp *)rcMessage.content;
- __blockSelf.totalCount = member.count;
- [__blockSelf countMemberCount];
- }
- // 用户退出消息
- else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomLeave class]]) {
- KSLiveChatroomLeave *memberLeaveMsg = (KSLiveChatroomLeave *)rcMessage.content;
- if ([__blockSelf judgeContainMember:memberLeaveMsg.userId]) {
- [__blockSelf removeMember:memberLeaveMsg.userId];
- [__blockSelf refreshSeatApplyView];
- }
- return;
- }
- // 连麦申请消息
- else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomSeatApply class]]) {
- KSLiveChatroomSeatApply *seatApplyMessage = (KSLiveChatroomSeatApply *)rcMessage.content;
-
- if (seatApplyMessage.type == SEATHANDLE_APPLY) { // 观众申请 加入申请中
- LiveSeatMember *member = [[LiveSeatMember alloc] init];
- member.avatar = seatApplyMessage.audienceAvatar;
- member.name = seatApplyMessage.audienceName;
- member.userId = seatApplyMessage.audienceId;
- member.isConnected = NO;
- if (![__blockSelf judgeContainMember:member.userId]) {
- [__blockSelf.seatApplyArray addObject:member];
- [__blockSelf refreshSeatApplyView];
- }
- }
- else if (seatApplyMessage.type == SEATHANDLE_CANCELAPPLY) { // 观众取消申请 从申请中剔除
- if ([__blockSelf judgeContainMember:seatApplyMessage.audienceId]) {
- // 如果在申请中的状态
- BOOL connectedStatus = [__blockSelf getUserConnectStatus:seatApplyMessage.audienceId];
- if (connectedStatus == NO) {
- NSLog(@"hahahhahah");
- [__blockSelf removeMember:seatApplyMessage.audienceId];
- [__blockSelf refreshSeatApplyView];
- }
-
- }
- }
- return;
- }
- // 连麦回复消息(暂不处理)
- else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomSeatResponse class]]) {
-
- }
- else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomDownSeat class]]) { // 观众下麦,从列表中移除
- KSLiveChatroomDownSeat *downSeatMessage = (KSLiveChatroomDownSeat *)rcMessage.content;
- if ([__blockSelf judgeContainMember:downSeatMessage.audienceId]) {
- [__blockSelf removeMember:downSeatMessage.audienceId];
- [__blockSelf refreshSeatApplyView];
- }
- return;
- }
- else if ([rcMessage.content isMemberOfClass:[KSRCShopRushMessage class]]) {
- KSRCShopRushMessage *rushMsg = (KSRCShopRushMessage *)rcMessage.content;
-
- NSString *contentMsg = [NSString stringWithFormat:@"%@ 正在抢购",[NSString returnNoNullStringWithString:rushMsg.userName]];
- [__blockSelf showAnimationView:NO showMessag:contentMsg];
- }
- else if ([rcMessage.content isMemberOfClass:[RCTextMessage class]]) {
- [__blockSelf insertMessage:rcMessage userInfo:notification.userInfo];
- }
- else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomClose class]]) { // 直播间已关闭
-
- [__blockSelf MBPShow:@"直播已结束"];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // 退出直播间
- [__blockSelf quitRoomBackPreView:NO];
- });
- return;
- }
- }
-
- }));
- }
- }
- - (void)insertMessage:(RCMessage *)rcMessage userInfo:(NSDictionary *)userInfo {
- // left
- NSDictionary *leftDic = userInfo;
- if (leftDic && [leftDic[@"left"] isEqual:@(0)]) {
- self.isNeedScrollToButtom = YES;
- }
- [self appendAndDisplayMessage:rcMessage];
- }
- - (BOOL)judgeContainMember:(NSString *)userId {
- for (LiveSeatMember *obj in self.seatApplyArray) {
- if ([obj.userId isEqualToString:userId]) {
- return YES;
- }
- }
- return NO;
- }
- - (NSInteger)queryConnectingCount {
- NSInteger count = 0;
- for (LiveSeatMember *member in self.seatApplyArray) {
- if (member.isConnected) {
- count++;
- }
- }
- return count;
- }
- - (void)removeMember:(NSString *)memberId {
- for (LiveSeatMember *member in self.seatApplyArray) {
- if ([member.userId isEqualToString:memberId]) {
- [self.seatApplyArray removeObject:member];
- return;
- }
- }
- }
- - (void)updateMemberStatusWaiting:(NSString *)userId {
- for (LiveSeatMember *obj in self.seatApplyArray) {
- if ([obj.userId isEqualToString:userId]) {
- obj.isConnected = NO;
- return;
- }
- }
- }
- - (void)updateMemberStatusConnecting:(NSString *)userId {
- for (LiveSeatMember *obj in self.seatApplyArray) {
- if ([obj.userId isEqualToString:userId]) {
- obj.isConnected = YES;
- return;
- }
- }
- }
- - (void)refreshSeatApplyView {
- if (self.seatApplyArray.count) {
- [self showSeatTips:self.seatApplyArray.count];
- }
- else {
- [self hideSeatTips];
- }
- [self.seatActionView refreshSeatApplyTable:self.seatApplyArray];
- }
- - (void)showSeatTips:(NSInteger)count {
- NSString *countDesc = count >= 100 ? @"99+" : [NSString stringWithFormat:@"%zd",count];
- [self.seatApplyTips configCountMessage:countDesc];
- [self.seatApplyTips showTipsView];
- }
- - (void)hideSeatTips {
- [self.seatApplyTips hideView];
- }
- // 发送人数同步消息
- - (void)sendMemberCountMessage {
- KSLiveChatroomMemberCount *syncMessage = [[KSLiveChatroomMemberCount alloc] init];
- syncMessage.count = self.totalCount;
-
- [self sendMessage:syncMessage displayMessage:NO callback:^(BOOL success) {
-
- }];
- }
- #pragma mark ----- time manager delegate
- - (void)formatTime:(NSString *)timeString {
- self.headView.timeLabel.text = timeString;
- }
- - (void)timeLabelAddAnimation:(CABasicAnimation *)animation {
- self.headView.timeLabel.textColor = HexRGB(0x2DC7AA);
- // [self.headView.timeLabel.layer addAnimation:animation forKey:nil];
- }
- //- (void)quitClassroomNotifer {
- // [self MBPShow:@"直播已结束!"];
- // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // [self quitRoomBackPreView:NO];
- // });
- //}
- #pragma mark - gesture and button action
- - (void)resetBottomGesture:(UIGestureRecognizer *)gestureRecognizer {
- if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
- [self setDefaultBottomViewStatus];
- }
- }
- - (void)setDefaultBottomViewStatus {
- [self.inputBar setInputBarStatus:KSBottomBarStatusDefault];
- [self.inputBar setHidden:YES];
- }
- #pragma mark ---- sendMessage/showMessage
- - (void)sendMessage:(RCMessageContent *)messageContent displayMessage:(BOOL)displayMessage callback:(void(^)(BOOL success))callback {
- if (_roomId == nil) {
- return;
- }
- messageContent.senderUserInfo = [RCIM sharedRCIM].currentUserInfo;
- if (messageContent == nil) {
- return;
- }
- __weak typeof(&*self) __weakself = self;
- [KSChatroomMessageCenter sendChatMessage:self.roomId content:messageContent success:^(long messageId) {
- dispatch_async(dispatch_get_main_queue(), ^{
- RCMessage *message = [[RCMessage alloc] initWithType:ConversationType_CHATROOM targetId:__weakself.roomId direction:MessageDirection_SEND content:messageContent];
- message.content.senderUserInfo = [RCIM sharedRCIM].currentUserInfo;
-
- message.senderUserId = UserDefault(UIDKey);
- if (displayMessage) {
- [__weakself appendAndDisplayMessage:message];
- }
- [__weakself.inputBar clearInputView];
- callback(YES);
- });
-
- } error:^(RCErrorCode errorCode, long messageId) {
- if (errorCode == RC_CHATROOM_NOT_EXIST) {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self MBPShow:@"聊天已被解散,请退出后重进。"];
- });
- }
- dispatch_async(dispatch_get_main_queue(), ^{
- [__weakself.inputBar clearInputView];
- NSLog(@"发送失败,errorcode is: %ld",(long)errorCode);
- callback(NO);
- });
- }];
- }
- /**
- * 将消息加入本地数组
- */
- - (void)appendAndDisplayMessage:(RCMessage *)rcMessage {
- if (!rcMessage) {
- return;
- }
-
- KSRCMessageModel *model = [[KSRCMessageModel alloc] initWithMessage:rcMessage];
- model.userInfo = rcMessage.content.senderUserInfo;
- if (!model.userInfo) {
- model.userInfo = [RCIMClient sharedRCIMClient].currentUserInfo;
- }
-
- if ([self appendMessageModel:model]) {
- NSIndexPath *indexPath =
- [NSIndexPath indexPathForItem:self.conversationDataRepository.count - 1
- inSection:0];
- if ([self.conversationMessageTableView numberOfRowsInSection:0] !=
- self.conversationDataRepository.count - 1) {
- return;
- }
- // view刷新
- [self.conversationMessageTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
- if ([self isAtTheBottomOfTableView] || self.isNeedScrollToButtom) {
- [self scrollToBottomAnimated:YES];
- self.isNeedScrollToButtom=NO;
- }
- }
- return;
- }
- /**
- * 如果当前会话没有这个消息id,把消息加入本地数组
- */
- - (BOOL)appendMessageModel:(KSRCMessageModel *)model {
-
- if (!model.content) {
- return NO;
- }
- //这里可以根据消息类型来决定是否显示,如果不希望显示直接return NO
-
- //数量不可能无限制的大,这里限制收到消息过多时,就对显示消息数量进行限制。
- //用户可以手动下拉更多消息,查看更多历史消息。
- if (self.conversationDataRepository.count>100) {
- // NSRange range = NSMakeRange(0, 1);
- KSRCMessageModel *message = self.conversationDataRepository[0];
- [[RCIMClient sharedRCIMClient]deleteMessages:@[@(message.messageId)]];
- [self.conversationDataRepository removeObjectAtIndex:0];
- [self.conversationMessageTableView reloadData];
- }
-
- [self.conversationDataRepository addObject:model];
- return YES;
- }
- /**
- * 判断消息是否在collectionView的底部
- *
- * @return 是否在底部
- */
- - (BOOL)isAtTheBottomOfTableView {
- if (self.conversationMessageTableView.contentSize.height <= self.conversationMessageTableView.frame.size.height) {
- return YES;
- }
- if(self.conversationMessageTableView.contentOffset.y +200 >= (self.conversationMessageTableView.contentSize.height - self.conversationMessageTableView.frame.size.height)) {
- return YES;
- }else{
- return NO;
- }
- }
- /**
- * 消息滚动到底部
- *
- * @param animated 是否开启动画效果
- */
- - (void)scrollToBottomAnimated:(BOOL)animated {
- if ([self.conversationMessageTableView numberOfSections] == 0) {
- return;
- }
- NSUInteger finalRow = MAX(0, [self.conversationMessageTableView numberOfRowsInSection:0] - 1);
- if (0 == finalRow) {
- return;
- }
- NSIndexPath *finalIndexPath =
- [NSIndexPath indexPathForItem:finalRow inSection:0];
- [self.conversationMessageTableView scrollToRowAtIndexPath:finalIndexPath atScrollPosition:UITableViewScrollPositionTop animated:animated];
- }
- /*
- #pragma mark - Navigation
- // In a storyboard-based application, you will often want 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.
- }
- */
- #pragma mark ----- table data source
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return self.conversationDataRepository.count;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- KSRCMessageModel *model = [self.conversationDataRepository objectAtIndex:indexPath.row];
- RCMessageContent *messageContent = model.content;
- KSChatroomTextCell *cell = [tableView dequeueReusableCellWithIdentifier:@"KSChatroomTextCell"];
- if(!cell){
- cell = [[KSChatroomTextCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"KSChatroomTextCell"];
- }
- if ([messageContent isMemberOfClass:[RCTextMessage class]] || [messageContent isMemberOfClass:[KSLiveChatroomWelcome class]] || [messageContent isMemberOfClass:[KSLiveChatroomLike class]] || [messageContent isMemberOfClass:[KSLiveChatroomSeatApply class]] || [messageContent isMemberOfClass:[KSLiveChatroomSeatResponse class]]){
- [cell setDataModel:model createrId:self.createrId];
- }
- return cell;
- }
- #pragma mark --- lazying
- - (UIView *)livePageView {
- if (!_livePageView) {
- _livePageView = [[UIView alloc] init];
- _livePageView.backgroundColor = HexRGB(0x25292e);
- }
- return _livePageView;
- }
- - (UIView *)liveVideoView {
- if (!_liveVideoView) {
- _liveVideoView = [[UIView alloc] init];
- _liveVideoView.backgroundColor = [UIColor clearColor];
- }
- return _liveVideoView;
- }
- - (LiveRoomHeadView *)headView {
- if (!_headView) {
- _headView = [LiveRoomHeadView shareInstance];
- }
- return _headView;
- }
- - (LiveRoomBottomView *)bottomView {
- if (!_bottomView) {
- _bottomView = [LiveRoomBottomView shareInstance];
- MJWeakSelf;
- [_bottomView bottomClickAction:^(LIVEROOMACTION action) {
- [weakSelf bottomViewAction:action];
- }];
- }
- return _bottomView;
- }
- - (void)bottomViewAction:(LIVEROOMACTION)action {
- switch (action) {
- case LIVEROOMACTION_CHAT: // 聊天
- {
- [_inputBar setHidden:NO];
- [_inputBar setInputBarStatus:KSBottomBarStatusKeyboard];
- }
- break;
- case LIVEROOMACTION_SEAT: // 呼出连麦页面
- {
- [self displaySeatView];
- }
- break;
- case LIVEROOMACTION_QUIT: // 退出
- {
- [self showMoreView];
- }
- default:
- break;
- }
- }
- - (void)showMoreView {
- [self.view addSubview:self.moreView];
- }
- - (SeatTipsView *)seatApplyTips {
- if (!_seatApplyTips) {
- _seatApplyTips = [[SeatTipsView alloc] init];
- }
- return _seatApplyTips;
- }
- - (void)displaySeatView {
- [self.view addSubview:self.seatCtrlView];
- [self refreshSeatApplyView];
- }
- - (void)closeRoomAction {
- MJWeakSelf;
- self.alertView = [LiveRoomAlertView liveroomAlertWithTitle:@"结束直播后,不可再次开启" leftButtonTitle:@"取消" rightTitle:@"结束直播" inView:self.view cancel:^{
-
- } confirm:^{
- [weakSelf distoryRoomAction];
- }];
- }
- - (void)pauseAction {
- MJWeakSelf;
- self.alertView = [LiveRoomAlertView liveroomAlertWithTitle:@"暂停后观众将无法看到视频画面" leftButtonTitle:@"取消" rightTitle:@"暂停直播" inView:self.view cancel:^{
-
- } confirm:^{
- [weakSelf quitRoomBackPreView:YES];
- }];
- }
- - (void)distoryRoomAction {
- MJWeakSelf;
- [self distoryRoomCallback:^(BOOL success) {
- [weakSelf closeRoomNotiferService];
- [weakSelf quitChatRoom];
- weakSelf.room = nil;
- if (self.callback) {
- self.callback();
- }
- [weakSelf.navigationController dismissViewControllerAnimated:YES completion:nil];
-
- }];
- }
- - (void)pauseLiveActionBack:(BOOL)backPreView {
- self.needPublishStream = NO;
- KSRCPauseLiveMessage *pauseMsg = [[KSRCPauseLiveMessage alloc] init];
- MJWeakSelf;
- [self sendMessage:pauseMsg displayMessage:NO callback:^(BOOL success) {
- if (backPreView) {
- [weakSelf.moreView hideView];
- weakSelf.isPauseLive = YES;
- weakSelf.pageType = LIVEPAGE_PREVIEW;
- [weakSelf.livePageView removeFromSuperview];
- [weakSelf configEngine];
- }
- }];
-
- [self.room.localUser unpublishDefaultLiveStreams:^(BOOL isSuccess, RCRTCCode code) {
- if (isSuccess) {
-
- }
- }];
- }
- - (void)quitRoomBackPreView:(BOOL)backPreView {
-
- if (backPreView) { // 暂停
- [self pauseLiveActionBack:YES];
- }
- else {
- if (self.pageType == LIVEPAGE_PREVIEW && self.isPauseLive == NO) {
- self.room = nil;
- self.preVideoView = nil;
- [[RCRTCEngine sharedInstance].defaultVideoStream stopCapture];
- if (self.callback) {
- self.callback();
- }
- [self.navigationController dismissViewControllerAnimated:YES completion:nil];
-
- }
- else {
- MJWeakSelf;
- [self exitRoomCallback:^(BOOL success) {
- // quit 接口
- [weakSelf quitNotiferService];
- [weakSelf quitChatRoom];
- [weakSelf.moreView hideView];
- if (self.callback) {
- self.callback();
- }
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [weakSelf.navigationController dismissViewControllerAnimated:YES completion:nil];
-
- });
- }];
- }
- }
- }
- - (KSLiveStreamVideo *)localVideo {
- if (!_localVideo) {
- _localVideo = [KSLiveStreamVideo LocalStreamVideo];
- }
- return _localVideo;
- }
- - (NSMutableArray *)remoteMemberArray {
- if (!_remoteMemberArray) {
- _remoteMemberArray = [NSMutableArray array];
- }
- return _remoteMemberArray;
- }
- - (UIView *)messageContentView {
- if (!_messageContentView) {
- _messageContentView = [[UIView alloc] init];
- [_messageContentView setBackgroundColor: [UIColor clearColor]];
- }
- return _messageContentView;
- }
- - (NSMutableArray<KSRCMessageModel *> *)conversationDataRepository {
- if (!_conversationDataRepository) {
- _conversationDataRepository = [NSMutableArray array];
- }
- return _conversationDataRepository;
- }
- - (KSChatInputBarControl *)inputBar {
- if (!_inputBar) {
- _inputBar = [[KSChatInputBarControl alloc] initWithStatus:KSBottomBarStatusDefault];
- [_inputBar setDelegate:self];
- }
- return _inputBar;
- }
- - (UITableView *)conversationMessageTableView {
- if (!_conversationMessageTableView) {
- _conversationMessageTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
- _conversationMessageTableView.backgroundColor = [UIColor clearColor];
- _conversationMessageTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
- _conversationMessageTableView.dataSource = self;
- _conversationMessageTableView.delegate = self;
- _conversationMessageTableView.rowHeight = UITableViewAutomaticDimension;
- _conversationMessageTableView.estimatedRowHeight = 40.0f;
- _conversationMessageTableView.showsVerticalScrollIndicator = NO;
- [_conversationMessageTableView registerClass:[KSChatroomTextCell class] forCellReuseIdentifier:@"KSChatroomTextCell"];
- }
- return _conversationMessageTableView;
- }
- - (SeatContentView *)seatContainer {
- if (!_seatContainer) {
- _seatContainer = [[SeatContentView alloc] init];
- }
- return _seatContainer;
- }
- - (UIView *)seatCtrlView {
- if (!_seatCtrlView) {
- _seatCtrlView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, KPortraitHeight)];
- _seatCtrlView.backgroundColor = [UIColor clearColor];
- self.gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideSeatCtrlView)];
- self.gesture.delegate = self;
- [_seatCtrlView addGestureRecognizer:self.gesture];
- [_seatCtrlView addSubview:self.seatActionView];
- UIView *headView = [[UIView alloc] initWithFrame:CGRectMake(0, KPortraitHeight - 300 - iPhoneXSafeBottomMargin - 16, KPortraitWidth, 16)];
- headView.backgroundColor = [UIColor whiteColor];
- [_seatCtrlView addSubview:headView];
- if (@available(iOS 11.0, *)) {
- headView.layer.cornerRadius = 8;
- headView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; // 左上圆角
- }
- else {
- UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:headView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(8, 8)];
- CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
- maskLayer.frame = headView.bounds;
- maskLayer.path = path.CGPath;
- headView.layer.mask = maskLayer;
- }
-
- }
- return _seatCtrlView;
- }
- - (void)hideSeatCtrlView {
- if (_seatCtrlView) {
- [_seatCtrlView removeFromSuperview];
- }
- }
- - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
- if (gestureRecognizer == self.gesture) {
- if ([touch.view isDescendantOfView:self.seatActionView]) {
- return NO;
- }
- }
-
- return YES;
- }
- - (LiveSeatActionView *)seatActionView {
- if (!_seatActionView) {
- _seatActionView = [[LiveSeatActionView alloc] initWithFrame:CGRectMake(0, kScreenHeight - 300 - iPhoneXSafeBottomMargin, kScreenWidth, 300 + iPhoneXSafeBottomMargin)];
- MJWeakSelf;
- [_seatActionView opreationCallback:^(LIVESECONTROL action, LiveSeatMember * _Nonnull member) {
- [weakSelf opreationSeatApplyAction:action member:member];
- }];
- }
- return _seatActionView;
- }
- - (void)opreationSeatApplyAction:(LIVESECONTROL)control member:(LiveSeatMember *)member {
- switch (control) {
- case LIVESECONTROL_ALLOW: // 允许连麦
- {
- RCChatroomSeatsControl *message = [[RCChatroomSeatsControl alloc] init];
- message.userId = self.createrId;
- message.userName = self.createrName;
- message.seatBan = NO;
- [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
-
- }];
- }
- break;
- case LIVESECONTROL_FORBIDDEN: // 禁止连麦
- {
- RCChatroomSeatsControl *message = [[RCChatroomSeatsControl alloc] init];
- message.userId = self.createrId;
- message.userName = self.createrName;
- message.seatBan = YES;
- MJWeakSelf;
- [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
- [weakSelf removeSeatMember:YES];
- }];
- }
- break;
- case LIVESECONTROL_APPROVE: // 上麦
- {
- if (member) {
- // 判断连麦人数超过4人 无法点击
- NSInteger count = [self queryConnectingCount];
- if (count >= 4) {
- [self MBPShow:@"最多可连麦4人"];
- return;
- }
- KSLiveChatroomSeatResponse *responseMessage = [[KSLiveChatroomSeatResponse alloc] init];
- responseMessage.type = SEATRESPONSE_TEACHERAPPROVE;
- responseMessage.teacherId = self.createrId;
- responseMessage.teacherName = self.createrName;
- responseMessage.audienceId = member.userId;
- responseMessage.audienceName = member.name;
- MJWeakSelf;
- [self sendMessage:responseMessage displayMessage:NO callback:^(BOOL success) {
- [weakSelf refreshSeatArrayRemoveMember:NO member:member];
- }];
- }
- }
- break;
- case LIVESECONTROL_DOWNSEAT: // 下麦
- {
- if (member) {
- KSLiveChatroomSeatApply *kickSeatMessage = [[KSLiveChatroomSeatApply alloc] init];
- kickSeatMessage.type = SEATHANDLE_KICKSEAT;
- kickSeatMessage.teacherId = self.createrId;
- kickSeatMessage.teacherName = self.createrName;
- kickSeatMessage.audienceId = member.userId;
- kickSeatMessage.audienceName = member.name;
-
- MJWeakSelf;
- [self sendMessage:kickSeatMessage displayMessage:NO callback:^(BOOL success) {
- [weakSelf refreshSeatArrayRemoveMember:YES member:member];
- }];
- }
- }
- break;
- case LIVESECONTROL_DOWNSEATALL:
- {
- KSDownSeatAllMessage *message = [[KSDownSeatAllMessage alloc] init];
- MJWeakSelf;
- [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
- [weakSelf removeSeatMember:NO];
- }];
- }
- break;
- case LIVESECONTROL_REFUSEALL:
- {
- KSRejectAllSeatMessage *message = [[KSRejectAllSeatMessage alloc] init];
- MJWeakSelf;
- [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
- [weakSelf removeSeatMember:YES];
- }];
- }
- break;
-
- default:
- break;
- }
- }
- - (void)removeSeatMember:(BOOL)isApply {
- NSMutableArray *seatArray = [self.seatApplyArray mutableCopy];
- if (isApply) {
- NSMutableArray *array = [NSMutableArray array];
- for (LiveSeatMember *member in seatArray) {
- if (member.isConnected == YES) {
- [array addObject:member];
- }
- }
- self.seatApplyArray = [NSMutableArray arrayWithArray:array];
- }
- else {
- NSMutableArray *array = [NSMutableArray array];
- for (LiveSeatMember *member in seatArray) {
- if (member.isConnected == NO) {
- [array addObject:member];
- }
- }
- self.seatApplyArray = [NSMutableArray arrayWithArray:array];
- }
- [self refreshSeatApplyView];
- }
- - (void)refreshSeatArrayRemoveMember:(BOOL)isRemove member:(LiveSeatMember *)member {
- if (isRemove) {
- [self.seatApplyArray removeObject:member];
- }
- else {
- member.isConnected = YES;
- if (![self judgeContainMember:member.userId]) {
- [self.seatApplyArray addObject:member];
- NSLog(@"hah--------");
- }
- }
- [self refreshSeatApplyView];
- }
- - (NSMutableArray *)seatApplyArray {
- if (!_seatApplyArray) {
- _seatApplyArray = [NSMutableArray array];
- }
- return _seatApplyArray;
- }
- - (LiveMoreDisplayView *)moreView {
- if (!_moreView) {
- _moreView = [LiveMoreDisplayView shareInstance];
- _moreView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
- MJWeakSelf;
- [_moreView operationQuitAction:^(BOOL isCloseRoom) {
- [weakSelf leaveRoom:isCloseRoom];
- }];
- }
- return _moreView;
- }
- - (void)leaveRoom:(BOOL)closeRoom {
- if (closeRoom) {
- [self closeRoomAction];
- }
- else {
- [self pauseAction];
- }
- }
- - (LiveroomTimeManager *)timeManager {
- if (!_timeManager) {
- _timeManager = [[LiveroomTimeManager alloc] initWithDelegate:self];
- }
- return _timeManager;
- }
- - (NSInteger)getCloseTime {
- return self.expiredCloseMinute;
- }
- - (void)dealloc {
- if (_timeManager) {
- [_timeManager stopDurationTimer];
- }
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- if (_timer) {
- dispatch_source_cancel(_timer);
- _timer = nil;
- }
- }
- - (dispatch_source_t)timer {
- if (!_timer) {
- _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
- uint64_t interval = (uint64_t)(10 * NSEC_PER_SEC);
- dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, interval, 0);
- MJWeakSelf;
- dispatch_source_set_event_handler(_timer, ^{
- dispatch_async(dispatch_get_main_queue(), ^{
- [weakSelf syncLikeCount];
- });
- });
- }
- return _timer;
- }
- - (void)showAnimationView:(BOOL)isJoinRoom showMessag:(NSString *)message {
- if (self.animationView && self.animationView.isShow) {
- return;
- }
- else {
- if (self.pageType == LIVEPAGE_PREVIEW) {
- return;
- }
- ANIMATIONTYPE type = isJoinRoom ? ANIMATIONTYPE_JOIN : ANIMATIONTYPE_RUSH;
- self.animationView = [[LiveAnimationView alloc] initWithTitle:message animationType:type];
- [self.view addSubview:self.animationView];
- [self.animationView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.right.mas_equalTo(self.view);
- make.width.mas_equalTo(KPortraitWidth);
- make.height.mas_equalTo(24.0f);
- make.bottom.mas_equalTo(self.messageContentView.mas_top).offset(-6);
- }];
- [self.view bringSubviewToFront:self.animationView];
- NSLog(@"------- start animation ");
- MJWeakSelf;
- [self.animationView startAnimationEndCallback:^{
- NSLog(@"----- hide ");
- weakSelf.animationView.isShow = YES;
- weakSelf.animationView = nil;
- }];
- }
- }
- #pragma mark ---- 同步点赞数据
- - (void)syncLikeCount {
- if (self.isOtherLogin) {
- return;
- }
- [KSNetworkingManager syncLikeRequest:KS_GET likeNum:self.likeCount roomUid:self.roomId success:^(NSDictionary * _Nonnull dic) {
- if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
- [self notiferLikeStatusToAudience];
- }
- } faliure:^(NSError * _Nonnull error) {
-
- }];
- }
- - (void)notiferLikeStatusToAudience {
- RCChatroomLikeCount *likeCountMsg = [[RCChatroomLikeCount alloc] init];
- likeCountMsg.count = self.likeCount;
-
- [self sendMessage:likeCountMsg displayMessage:NO callback:^(BOOL success) {
- }];
- }
- /*
- #pragma mark - Navigation
- // In a storyboard-based application, you will often want 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
|