BGKSYLiveController.m 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174
  1. //
  2. // BGKSYLiveController.m
  3. // FanweApp
  4. //
  5. // Created by xfg on 2017/2/10.
  6. // Copyright © 2017年 xfg. All rights reserved.
  7. // 金山云直播,只处理与SDK有关的业务
  8. #import "BGKSYLiveController.h"
  9. #import "HostCheckMickAlertView.h"
  10. #define kPlayContrainerHeight 30
  11. @interface BGKSYLiveController ()
  12. @end
  13. @implementation BGKSYLiveController
  14. #pragma mark - ----------------------- 添加UI -----------------------
  15. #pragma mark - UI respond : gpu filters
  16. - (void)onFilterChange:(id)sender
  17. {
  18. // if (self.mickType == FW_MICK_TYPE_KSY)
  19. // {
  20. // [_ksyLinkMicStreamerController.gPUStreamerKit setupRtcFilter:_beautyView.curFilter];
  21. // }
  22. // else
  23. if (self.mickType == FW_MICK_TYPE_AGORA)
  24. {
  25. #if TARGET_IPHONE_SIMULATOR
  26. #else
  27. [_agoraLinkMicStreamerController.gPUStreamerKit setupRtcFilter:_beautyView.curFilter];
  28. #endif
  29. }
  30. }
  31. - (void)addSubViews
  32. {
  33. if (self.liveType == FW_LIVE_TYPE_HOST)
  34. {
  35. _beautyView = [[BGSettingBeautyView alloc]initWithFrame:CGRectMake(0, 0, kScreenW, kScreenH)];
  36. [self.liveServiceController.liveUIViewController.liveView addSubview:_beautyView];
  37. __weak typeof(self) ws = self;
  38. _beautyView.onBtnBlock = ^(id sender) {
  39. [ws onFilterChange:sender];
  40. };
  41. _beautyView.hidden = YES;
  42. }
  43. if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  44. {
  45. self.backVerticalBtn = [[UIButton alloc]initWithFrame:CGRectMake(15, 15, 35, 35)];
  46. [self.backVerticalBtn setImage:[UIImage imageNamed:@"com_arrow_vc_back_2"] forState:UIControlStateNormal];
  47. [self.backVerticalBtn addTarget:self action:@selector(goVerticalScreen) forControlEvents:UIControlEventTouchUpInside];
  48. [self.view addSubview:self.backVerticalBtn];
  49. self.backVerticalBtn.hidden = YES;
  50. }
  51. }
  52. #pragma mark 添加视频
  53. - (void)initLive
  54. {
  55. // 付费直播控制云直播声音
  56. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(voiceNotice:) name:@"closeAndOpenVoice" object:nil];
  57. // 音量监听
  58. [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  59. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
  60. // 屏幕旋转监听
  61. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
  62. [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onPKViewChange:) name:@"onPKViewChange" object:nil];
  63. // PK连麦
  64. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(PKWithRoomID:) name:@"KPKWithRoomID" object:nil];
  65. if (self.liveType == FW_LIVE_TYPE_HOST)
  66. {
  67. // if (self.mickType == FW_MICK_TYPE_KSY)
  68. // {
  69. // _ksyLinkMicStreamerController = [[BGKSYLinkMicStreamerController alloc] init];
  70. // _ksyLinkMicStreamerController.delegate = self;
  71. // _ksyLinkMicStreamerController.linkMicPublishDelegate = self;
  72. // [self addChild:_ksyLinkMicStreamerController inRect:self.view.bounds];
  73. // [self.view sendSubviewToBack:_ksyLinkMicStreamerController.view];
  74. // } else
  75. if(self.mickType == FW_MICK_TYPE_AGORA)
  76. {
  77. _agoraLinkMicStreamerController = [[BGKSYAgoraLinkMicStreamerController alloc] init];
  78. _agoraLinkMicStreamerController.liveType = self.liveType;
  79. _agoraLinkMicStreamerController.delegate = self;
  80. [self addChild:_agoraLinkMicStreamerController inRect:self.view.bounds];
  81. [self.view sendSubviewToBack:_agoraLinkMicStreamerController.view];
  82. }
  83. }
  84. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  85. {
  86. // if (self.mickType == FW_MICK_TYPE_KSY)
  87. // {
  88. // _ksyLinkMicPlayerController = [[BGKSYLinkMicPlayerController alloc] init];
  89. // _ksyLinkMicPlayerController.liveType = self.liveType;
  90. // _ksyLinkMicPlayerController.delegate = self;
  91. // _ksyLinkMicPlayerController.linkMicPlayDelegate = self;
  92. // [self addChild:_ksyLinkMicPlayerController inRect:self.view.bounds];
  93. // [self.view sendSubviewToBack:_ksyLinkMicPlayerController.view];
  94. // }else
  95. if(self.mickType == FW_MICK_TYPE_AGORA)
  96. {
  97. _agoraLinkMicPlayerController = [[BGKSYAgoraLinkMicPlayerController alloc] init];
  98. _agoraLinkMicPlayerController.playLiveType = self.liveType;
  99. _agoraLinkMicPlayerController.delegate = self;
  100. [self addChild:_agoraLinkMicPlayerController inRect:self.view.bounds];
  101. [self.view sendSubviewToBack:_agoraLinkMicPlayerController.view];
  102. // _agoraLinkMicPlayerController.txLivePlayer.delegate = self;
  103. }
  104. }
  105. UIView *leftView = [[UIView alloc] init];
  106. leftView.backgroundColor = RGB(32, 23, 68);
  107. leftView.frame = CGRectMake(0, 0, self.view.width/2, self.view.height);
  108. [self.view addSubview:leftView];
  109. [self.view sendSubviewToBack:leftView];
  110. UIView *rightView = [[UIView alloc] init];
  111. rightView.backgroundColor = RGB(65, 11, 34);
  112. rightView.frame = CGRectMake(self.view.width/2, 0, self.view.width/2, self.view.height);
  113. [self.view addSubview:rightView];
  114. [self.view sendSubviewToBack:rightView];
  115. [self setSDKMirror:NO]; //默认关闭镜像
  116. }
  117. //该参数就是发送过来的通知,接到通知后执行的方法
  118. - (void)onPKViewChange:(NSNotification *)notify
  119. {
  120. int isFull = [[notify.userInfo valueForKey:@"isFull"] intValue];
  121. if(isFull == 1)
  122. {
  123. //模拟动态修改
  124. //关闭连麦
  125. [self getPlayViewBottomView].frame = self.view.bounds;
  126. if(_isHost)
  127. {
  128. #if TARGET_IPHONE_SIMULATOR
  129. #else
  130. _agoraLinkMicStreamerController.gPUStreamerKit.winPKRect = CGRectMake(0, 0, 1, 1);
  131. [_agoraLinkMicStreamerController.gPUStreamerKit setPKModel:NO];
  132. [_agoraLinkMicStreamerController.gPUStreamerKit leaveChannel];
  133. #endif
  134. }
  135. }
  136. else if(isFull == 3)
  137. {
  138. [self getPlayViewBottomView].frame = CGRectMake(0, kStatusBarHeight + 53 + 55, kScreenW, kScreenH/2-40);
  139. if(_isHost)
  140. {
  141. #if TARGET_IPHONE_SIMULATOR
  142. #else
  143. _agoraLinkMicStreamerController.gPUStreamerKit.winRect = CGRectMake(0.5, 0, 0.5, 0.5);
  144. _agoraLinkMicStreamerController.gPUStreamerKit.winPKRect = CGRectMake(0, 0, 0.5, 0.5);
  145. [_agoraLinkMicStreamerController.gPUStreamerKit setPKModel:YES];
  146. #endif
  147. }
  148. }
  149. else if(isFull == 0)
  150. {
  151. [self getPlayViewBottomView].frame = CGRectMake(0, kStatusBarHeight + 53 + 55, kScreenW, kScreenH/2-40);
  152. if(_isHost)
  153. {
  154. #if TARGET_IPHONE_SIMULATOR
  155. #else
  156. _agoraLinkMicStreamerController.gPUStreamerKit.winRect = CGRectMake(0.5, 0, 0.5, 0.5);
  157. _agoraLinkMicStreamerController.gPUStreamerKit.winPKRect = CGRectMake(0, 0, 0.5, 0.5);
  158. [_agoraLinkMicStreamerController.gPUStreamerKit setPKModel:YES];
  159. #endif
  160. }
  161. }
  162. }
  163. - (void)PKWithRoomID:(NSNotification *)notification{
  164. NSDictionary * infoDic = notification.userInfo;
  165. NSString *roomId = [infoDic valueForKey:@"roomid"];
  166. #if TARGET_IPHONE_SIMULATOR
  167. #else
  168. [_agoraLinkMicStreamerController.gPUStreamerKit joinChannel:roomId];
  169. #endif
  170. }
  171. #pragma mark 添加直播间逻辑、视图
  172. - (void)addServiceController
  173. {
  174. if (!_liveServiceController)
  175. {
  176. _liveServiceController = [[BGLiveServiceController alloc]initWith:self.liveItem liveController:self];
  177. _liveServiceController.delegate = self;
  178. _liveServiceController.pluginCenterView.toolsView.toSDKdelegate = self;
  179. _liveServiceController.liveUIViewController.liveView.sdkDelegate = self;
  180. _liveServiceController.liveUIViewController.liveView.topView.toSDKDelegate = self;
  181. [LIVE_CENTER_MANAGER.stSuspensionWindow setDelegate:self ];
  182. [self addChild:_liveServiceController inRect:self.view.bounds];
  183. }
  184. }
  185. #pragma mark - ----------------------- 重写父方法 -----------------------
  186. - (void)viewWillAppear:(BOOL)animated
  187. {
  188. [super viewWillAppear:animated];
  189. }
  190. - (void)viewWillDisappear:(BOOL)animated
  191. {
  192. [super viewWillDisappear:animated];
  193. }
  194. - (instancetype)initWith:(id<FWShowLiveRoomAble>)liveItem modelArr:(NSArray *)modelArr
  195. {
  196. if (self = [super initWith:liveItem modelArr:modelArr])
  197. {
  198. [self addServiceController];
  199. [self addSubViews];
  200. }
  201. return self;
  202. }
  203. - (void)refreshLiveItem:(id<FWShowLiveRoomAble>)liveItem liveInfo:(CurrentLiveInfo *)liveInfo
  204. {
  205. [super refreshLiveItem:liveItem liveInfo:liveInfo];
  206. [_liveServiceController refreshLiveItem:liveItem liveInfo:liveInfo];
  207. }
  208. - (void)viewDidLoad
  209. {
  210. [super viewDidLoad];
  211. _mickUserMArray = [NSMutableArray array];
  212. _registerMickUserMArray = [NSMutableArray array];
  213. if (self.BuguLive.appModel.mic_max_num >= 3 || self.BuguLive.appModel.mic_max_num == 0)
  214. {
  215. _micMaxNum = 3;
  216. }
  217. else
  218. {
  219. _micMaxNum = self.BuguLive.appModel.mic_max_num;
  220. }
  221. self.view.backgroundColor = kBlackColor;
  222. //初始化直播
  223. [self initLive];
  224. }
  225. #pragma mark 腾讯云直播开始进入直播间:根据是否传入了聊天组ID选择对应的进入直播间的方案
  226. - (void)startEnterChatGroup:(NSString *)chatGroupID succ:(FWVoidBlock)succ failed:(FWErrorBlock)failed
  227. {
  228. FWWeakify(self)
  229. [_liveServiceController getVideo:^(CurrentLiveInfo *liveInfo) {
  230. FWStrongify(self)
  231. if (liveInfo)
  232. {
  233. self.liveInfo = liveInfo;
  234. self.hasVideoControl = liveInfo.has_video_control ? YES : NO;
  235. self.reLiveProgressView.hidden = YES;
  236. self.liveServiceController.liveUIViewController.livePay.payDelegate = self;
  237. if (![BGUtils isBlankString:liveInfo.push_rtmp] || ![BGUtils isBlankString:liveInfo.play_url])
  238. {
  239. [self beginPlayVideo:liveInfo];
  240. }
  241. if (liveInfo.is_live_pay == 1 && liveInfo.is_pay_over == 0 && ![liveInfo.podcast.user.user_id isEqualToString:[[IMAPlatform sharedInstance].host imUserId]])
  242. {
  243. if (succ)
  244. {
  245. succ();
  246. }
  247. }
  248. else
  249. {
  250. [super startEnterChatGroup:liveInfo.group_id succ:^{
  251. [self getVideoState:1];
  252. if (succ)
  253. {
  254. succ();
  255. }
  256. } failed:^(int errId, NSString *errMsg) {
  257. [self getVideoState:0];
  258. if (failed)
  259. {
  260. failed(errId, errMsg);
  261. }
  262. }];
  263. }
  264. }
  265. else
  266. {
  267. [self setGetVideoFailed:nil];
  268. if (failed)
  269. {
  270. failed(FWCode_Net_Error, ASLocalizedString(@"获取到的liveInfo为空"));
  271. }
  272. }
  273. } roomID:@"" failed:^(int errId, NSString *errMsg) {
  274. FWStrongify(self)
  275. [self setGetVideoFailed:errMsg];
  276. if (failed)
  277. {
  278. failed(errId, errMsg);
  279. }
  280. DebugLog(@"=========加载get_video接口出错 code: %d , msg = %@", errId, errMsg);
  281. }];
  282. }
  283. #pragma mark 加入聊天组成功
  284. - (void)enterChatGroupSucc:(CurrentLiveInfo *)liveInfo
  285. {
  286. [super enterChatGroupSucc:liveInfo];
  287. if (!_isHost && (_liveInfo.join_room_prompt == 1 || [[IMAPlatform sharedInstance].host getUserRank] >= self.BuguLive.appModel.jr_user_level))
  288. {
  289. _liveServiceController.liveUIViewController.liveView.canShowLightMessage = YES;
  290. }
  291. }
  292. #pragma mark 重写父方法: 业务上退出直播:退出的时候分SDK退出和业务退出,减少退出等待时间
  293. - (void)onServiceExitLive:(BOOL)isDirectCloseLive succ:(FWVoidBlock)succ failed:(FWErrorBlock)failed
  294. {
  295. [_liveServiceController endLive];
  296. if (SUS_WINDOW.liveType == FW_LIVE_TYPE_HOST) // 主播
  297. {
  298. [_liveServiceController showHostFinishView:@"" andVote:@"" andHasDel:NO];
  299. FWWeakify(self)
  300. [_liveServiceController hostExitLive:^{
  301. FWStrongify(self)
  302. if(isDirectCloseLive)
  303. {
  304. [self onExitLiveUI];
  305. }
  306. if (succ)
  307. {
  308. succ();
  309. }
  310. } failed:^(int errId, NSString *errMsg) {
  311. if(isDirectCloseLive)
  312. {
  313. [self onExitLiveUI];
  314. }
  315. if (failed)
  316. {
  317. failed(errId, errMsg);
  318. }
  319. }];
  320. // if (self.mickType == FW_MICK_TYPE_KSY)
  321. // {
  322. // [_ksyLinkMicStreamerController stopRtmp];
  323. // }else
  324. if(self.mickType == FW_MICK_TYPE_AGORA)
  325. {
  326. [_agoraLinkMicStreamerController stopRtmp];
  327. }
  328. }
  329. else
  330. {
  331. if (SUS_WINDOW.liveType == FW_LIVE_TYPE_AUDIENCE)
  332. {
  333. // if (self.mickType == FW_MICK_TYPE_KSY)
  334. // {
  335. // [_ksyLinkMicPlayerController stopPlay];
  336. // }else
  337. if(self.mickType == FW_MICK_TYPE_AGORA)
  338. {
  339. [_agoraLinkMicPlayerController stopRtmp];
  340. }
  341. [self cancelMickingAlert];
  342. }
  343. if(isDirectCloseLive)
  344. {
  345. [self onExitLiveUI];
  346. if (succ)
  347. {
  348. succ();
  349. }
  350. }
  351. }
  352. }
  353. #pragma mark 是否需要打断视频
  354. - (void)interruptionLiveIng:(BOOL)interruptioning
  355. {
  356. if (interruptioning)
  357. {
  358. [_liveServiceController pauseLive];
  359. if (self.liveType == FW_LIVE_TYPE_HOST)
  360. {
  361. [_ksyLinkMicStreamerController.gPUStreamerKit appEnterBackground];
  362. }
  363. else if(self.liveType == FW_LIVE_TYPE_AUDIENCE)
  364. {
  365. // if (self.mickType == FW_MICK_TYPE_KSY)
  366. // {
  367. // [_ksyLinkMicPlayerController pausePlay];
  368. // }else
  369. if(self.mickType == FW_MICK_TYPE_AGORA)
  370. {
  371. [_agoraLinkMicPlayerController.txLivePlayer pause];
  372. }
  373. }
  374. }
  375. else
  376. {
  377. [_liveServiceController resumeLive];
  378. if (self.liveType == FW_LIVE_TYPE_HOST)
  379. {
  380. [_ksyLinkMicStreamerController.gPUStreamerKit appBecomeActive];
  381. }
  382. else if(self.liveType == FW_LIVE_TYPE_AUDIENCE)
  383. {
  384. // if (self.mickType == FW_MICK_TYPE_KSY)
  385. // {
  386. // [_ksyLinkMicPlayerController resumePlay];
  387. // }else
  388. if(self.mickType == FW_MICK_TYPE_AGORA)
  389. {
  390. [_agoraLinkMicPlayerController.txLivePlayer resume];
  391. }
  392. }
  393. }
  394. }
  395. #pragma mark 是否正在被电话打断
  396. - (void)phoneInterruptioning:(BOOL)interruptioning
  397. {
  398. [super phoneInterruptioning:interruptioning];
  399. [self interruptionLiveIng:interruptioning];
  400. }
  401. #pragma mark app进入前台
  402. - (void)onAppEnterForeground
  403. {
  404. if (_isHost)
  405. {
  406. [super onAppEnterForeground];
  407. }
  408. [self interruptionLiveIng:NO];
  409. }
  410. #pragma mark app进入后台
  411. - (void)onAppEnterBackground
  412. {
  413. if (_isHost)
  414. {
  415. [super onAppEnterBackground];
  416. }
  417. if (_toolsView)
  418. {
  419. // 关闭LED
  420. [BGUtils turnOnFlash:NO];
  421. ToolsCollectionViewCell *cell = (ToolsCollectionViewCell *)[_toolsView.toolsCollectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:4 inSection:0]];
  422. if (cell)
  423. {
  424. cell.toolImgView.image = [UIImage imageNamed:@"lr_plugin_flash_unsel"];
  425. }
  426. }
  427. [self interruptionLiveIng:YES];
  428. }
  429. #pragma mark 重写退出方法
  430. - (void)onExitLiveUI
  431. {
  432. [super onExitLiveUI];
  433. // 执行下 悬浮参数退出
  434. if (SUS_WINDOW.isSusWindow && SUS_WINDOW.isDirectCloseLive)
  435. {
  436. [[LiveCenterManager sharedInstance] resetSuswindowPramaComple:^(BOOL finished) {
  437. }];
  438. }
  439. [_liveServiceController endLive];
  440. _liveServiceController = nil;
  441. if (_ksyLinkMicStreamerController)
  442. {
  443. _ksyLinkMicStreamerController = nil;
  444. }
  445. if (_agoraLinkMicStreamerController)
  446. {
  447. _agoraLinkMicStreamerController = nil;
  448. }
  449. if (_ksyPlayerController)
  450. {
  451. _ksyPlayerController = nil;
  452. }
  453. if (_ksyLinkMicPlayerController)
  454. {
  455. _ksyLinkMicPlayerController = nil;
  456. }
  457. if (_agoraLinkMicPlayerController)
  458. {
  459. _agoraLinkMicPlayerController = nil;
  460. }
  461. if (!SUS_WINDOW.isSusWindow)
  462. {
  463. self.navigationController.navigationBarHidden = NO;
  464. [self.navigationController popViewControllerAnimated:YES];
  465. }
  466. }
  467. #pragma mark 重写声音打断监听
  468. - (void)onAudioInterruption:(NSNotification *)notification
  469. {
  470. [super onAudioInterruption:notification];
  471. if(self.liveType == FW_LIVE_TYPE_AUDIENCE)
  472. {
  473. // [_ksyLinkMicPlayerController onAudioInterruption:notification];
  474. }
  475. }
  476. #pragma mark 监听耳机插入和拔出
  477. - (void)audioRouteChangeListenerCallback:(NSNotification *)notification
  478. {
  479. [super audioRouteChangeListenerCallback:notification];
  480. NSDictionary *interuptionDict = notification.userInfo;
  481. NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
  482. switch (routeChangeReason)
  483. {
  484. case AVAudioSessionRouteChangeReasonNewDeviceAvailable: // 耳机插入
  485. // if (self.mickType == FW_MICK_TYPE_KSY)
  486. // {
  487. // // 开启耳返功能
  488. // _ksyLinkMicStreamerController.gPUStreamerKit.aCapDev.bPlayCapturedAudio = YES;
  489. // _ksyLinkMicStreamerController.gPUStreamerKit.aCapDev.micVolume = 0.8;
  490. // // 混响类型
  491. // _ksyLinkMicStreamerController.gPUStreamerKit.aCapDev.reverbType = 2;
  492. // }else
  493. if(self.mickType == FW_MICK_TYPE_AGORA)
  494. {
  495. // 开启耳返功能
  496. _agoraLinkMicStreamerController.gPUStreamerKit.aCapDev.bPlayCapturedAudio = YES;
  497. _agoraLinkMicStreamerController.gPUStreamerKit.aCapDev.micVolume = 0.8;
  498. // 混响类型
  499. _agoraLinkMicStreamerController.gPUStreamerKit.aCapDev.reverbType = 2;
  500. }
  501. break;
  502. case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: // 耳机拔出,停止播放操作
  503. // if (self.mickType == FW_MICK_TYPE_KSY)
  504. // {
  505. // // 关闭耳返功能
  506. // _ksyLinkMicStreamerController.gPUStreamerKit.aCapDev.bPlayCapturedAudio = NO;
  507. // // 混响类型
  508. // _ksyLinkMicStreamerController.gPUStreamerKit.aCapDev.reverbType = 0;
  509. // }else
  510. if(self.mickType == FW_MICK_TYPE_AGORA)
  511. {
  512. // 关闭耳返功能
  513. _agoraLinkMicStreamerController.gPUStreamerKit.aCapDev.bPlayCapturedAudio = NO;
  514. // 混响类型
  515. _agoraLinkMicStreamerController.gPUStreamerKit.aCapDev.reverbType = 0;
  516. }
  517. break;
  518. case AVAudioSessionRouteChangeReasonCategoryChange:
  519. // called at start - also when other audio wants to play
  520. NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
  521. break;
  522. }
  523. }
  524. #pragma mark 重写弹出退出或直接退出
  525. /**
  526. * @brief: 重写 弹出退出或直接退出
  527. *
  528. * @prama: isDirectCloseLive
  529. * @prama: isHostShowAlert
  530. * @prama: succ
  531. * @prama: failed
  532. *
  533. * @discussion:1.BGLiveBaseController 重写里面的 弹出退出或直接退出 因为
  534. *
  535. */
  536. - (void)alertExitLive:(BOOL)isDirectCloseLive isHostShowAlert:(BOOL)isHostShowAlert succ:(FWVoidBlock)succ failed:(FWErrorBlock)failed
  537. {
  538. //在后面退出 基础类需要 这个判断 需不需要 Finish界面
  539. self.isDirectCloseLive = isDirectCloseLive;
  540. // isHostShowAlert 暂时没处理
  541. [[LiveCenterManager sharedInstance] closeLiveOfPramaOfLiveViewController:self paiTimeNum:nil alertExitLive:isDirectCloseLive isHostShowAlert:isHostShowAlert colseLivecomplete:^(BOOL finished) {
  542. if (finished)
  543. {
  544. if (succ)
  545. {
  546. succ();
  547. }
  548. }
  549. else
  550. {
  551. if (failed)
  552. {
  553. failed(FWCode_Normal_Error, @"");
  554. }
  555. }
  556. }];
  557. }
  558. #pragma mark - ----------------------- 部分业务逻辑 -----------------------
  559. #pragma mark 请求get_video接口失败的情况
  560. - (void)setGetVideoFailed:(NSString *)errMsg
  561. {
  562. NSString *errStr = errMsg;
  563. if ([BGUtils isBlankString:errStr])
  564. {
  565. errStr = ASLocalizedString(@"获取聊天室信息失败,请稍候尝试");
  566. }
  567. [self getVideoState:0];
  568. __weak typeof(self) ws = self;
  569. [BGHUDHelper alert:errStr action:^{
  570. [ws onExitLiveUI];
  571. }];
  572. }
  573. #pragma mark 真正开始播放
  574. - (void)beginPlayVideo:(CurrentLiveInfo *)liveInfo
  575. {
  576. _iMMsgHandler.isEnterRooming = NO;
  577. __weak typeof(self) ws = self;
  578. if (self.liveType == FW_LIVE_TYPE_HOST)
  579. {
  580. if (liveInfo.push_rtmp && ![liveInfo.push_rtmp isEqualToString:@""])
  581. {
  582. // if (self.mickType == FW_MICK_TYPE_KSY)
  583. // {
  584. // _ksyLinkMicStreamerController.pushUrl = [NSURL URLWithString:liveInfo.push_rtmp];
  585. // [_ksyLinkMicStreamerController.gPUStreamerKit setupFilter:_beautyView.curFilter];
  586. // [_ksyLinkMicStreamerController startRtmp];
  587. // }else
  588. if(self.mickType == FW_MICK_TYPE_AGORA)
  589. {
  590. _agoraLinkMicStreamerController.pushUrl = [NSURL URLWithString:liveInfo.push_rtmp];
  591. [_agoraLinkMicStreamerController.gPUStreamerKit setupFilter:_beautyView.curFilter];
  592. [_agoraLinkMicStreamerController startRtmp];
  593. }
  594. }
  595. else
  596. {
  597. [BGHUDHelper alert:ASLocalizedString(@"抱歉,推流地址为空,请稍后尝试")action:^{
  598. [ws alertExitLive:YES isHostShowAlert:NO succ:nil failed:nil];
  599. }];
  600. }
  601. }
  602. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  603. {
  604. if (liveInfo.play_url && ![liveInfo.play_url isEqualToString:@""])
  605. {
  606. // if (!([self.BuguLive.appModel.open_vip intValue] == 1 && liveInfo.is_vip == 0))
  607. // {
  608. // if (self.mickType == FW_MICK_TYPE_KSY)
  609. // {
  610. // [_ksyLinkMicPlayerController initPlayerWithUrl:[NSURL URLWithString:liveInfo.play_url] createType:liveInfo.create_type];
  611. // }else
  612. if(self.mickType == FW_MICK_TYPE_AGORA)
  613. {
  614. _agoraLinkMicPlayerController.playUrlStr = liveInfo.play_url;
  615. [_agoraLinkMicPlayerController startRtmp:1];
  616. // [_agoraLinkMicPlayerController.txLivePlayer startPlay:liveInfo.play_url type:PLAY_TYPE_LIVE_RTMP];
  617. // [_agoraLinkMicPlayerController initPlayerWithUrl:[NSURL URLWithString:liveInfo.play_url] createType:liveInfo.create_type];
  618. }
  619. // }
  620. }
  621. else
  622. {
  623. [BGHUDHelper alert:ASLocalizedString(@"抱歉,播放地址为空,请稍后尝试")action:^{
  624. [ws alertExitLive:YES isHostShowAlert:NO succ:nil failed:nil];
  625. }];
  626. }
  627. }
  628. if (_isHost)
  629. {
  630. [_liveServiceController startLiveTimer];
  631. }
  632. }
  633. #pragma mark 请求video_cstatus接口来获取直播间信息
  634. - (void)getVideoState:(NSInteger)state
  635. {
  636. NSMutableDictionary *mDict = [NSMutableDictionary dictionary];
  637. [mDict setObject:@"video" forKey:@"ctl"];
  638. [mDict setObject:@"video_cstatus" forKey:@"act"];
  639. [mDict setObject:[NSString stringWithFormat:@"%d",[self.liveItem liveAVRoomId]] forKey:@"room_id"];
  640. [mDict setObject:StringFromInteger(state) forKey:@"status"];
  641. if ([self.liveItem liveIMChatRoomId] && ![[self.liveItem liveIMChatRoomId] isEqualToString:@""])
  642. {
  643. [mDict setObject:[self.liveItem liveIMChatRoomId] forKey:@"group_id"];
  644. }
  645. [_liveServiceController getVideoState:mDict];
  646. }
  647. #pragma mark - ----------------------- 金山云连麦独有模块 -----------------------
  648. #pragma mark 处理鉴权回调
  649. /*
  650. * 主播端鉴权回调
  651. * status:鉴权回调码
  652. * responderId:接收连麦者ID
  653. */
  654. - (void)registerResult:(int)status registerUserId:(NSString *)responderId
  655. {
  656. if (_customApplicantModel && status == 200)
  657. {
  658. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  659. sendCustomMsgModel.msgType = MSG_RECEIVE_MIKE;
  660. sendCustomMsgModel.msgReceiver = _customApplicantModel.sender;
  661. [_iMMsgHandler sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  662. [_registerMickUserMArray addObject:responderId];
  663. [_ksyLinkMicStreamerController startRegister:_customApplicantModel.sender.user_id];
  664. }
  665. }
  666. #pragma mark 处理反鉴权回调
  667. /*
  668. * 主播端反鉴权回调
  669. * status:反鉴权回调码
  670. * responderId:接收连麦者ID
  671. */
  672. - (void)unRegisterResult:(int)status registerUserId:(NSString *)responderId
  673. {
  674. if ([_registerMickUserMArray containsObject:responderId])
  675. {
  676. [_registerMickUserMArray removeObject:responderId];
  677. }
  678. }
  679. #pragma mark 处理鉴权回调
  680. /*
  681. * 辅播端(即连麦观众)鉴权回调
  682. * status:鉴权回调码
  683. * applicantId:申请连麦者ID
  684. */
  685. - (void)registerResult2:(int)status registerUserId:(NSString *)applicantId
  686. {
  687. if (applicantId && _customResponderModel.sender.user_id && status == 200)
  688. {
  689. [_ksyLinkMicPlayerController startLinkMic:applicantId andResponderId:_customResponderModel.sender.user_id];
  690. }
  691. }
  692. #pragma mark 处理反鉴权回调
  693. /*
  694. * 辅播端(即连麦观众)反鉴权回调
  695. * status:反鉴权回调码
  696. * applicantId:申请连麦者ID
  697. */
  698. - (void)unRegisterResult2:(int)status registerUserId:(NSString *)applicantId
  699. {
  700. if ([_registerMickUserMArray containsObject:applicantId])
  701. {
  702. [_registerMickUserMArray removeObject:applicantId];
  703. }
  704. }
  705. - (void)doMyUnregisterRTC
  706. {
  707. if ([_registerMickUserMArray count])
  708. {
  709. if (_isHost)
  710. {
  711. // [_ksyLinkMicStreamerController.gPUStreamerKit.rtcClient unRegisterRTC];
  712. }
  713. else
  714. {
  715. // [_ksyLinkMicPlayerController.gPUStreamerKit.rtcClient unRegisterRTC];
  716. }
  717. }
  718. }
  719. #pragma mark 获取鉴权串
  720. - (void)getRegisterIdStr:(CustomMessageModel *)customMessageModel
  721. {
  722. NSMutableDictionary *mDict = [NSMutableDictionary dictionary];
  723. [mDict setObject:@"video" forKey:@"ctl"];
  724. [mDict setObject:@"ks_auth" forKey:@"act"];
  725. FWWeakify(self)
  726. [self.httpsManager POSTWithParameters:mDict SuccessBlock:^(NSDictionary *responseJson) {
  727. FWStrongify(self)
  728. if ([responseJson toInt:@"status"] == 1)
  729. {
  730. [self doMyUnregisterRTC];
  731. if (self.isHost)
  732. {
  733. // self.ksyLinkMicStreamerController.gPUStreamerKit.rtcClient.authString = [NSString stringWithFormat:@"https://rtc.vcloud.ks-live.com:6001/auth?%@",[responseJson toString:@"auth_string"]];
  734. // self.ksyLinkMicStreamerController.gPUStreamerKit.rtcClient.localId = [responseJson toString:@"uid"];
  735. // [self.ksyLinkMicStreamerController.gPUStreamerKit.rtcClient registerRTC];
  736. }
  737. else
  738. {
  739. // self.ksyLinkMicPlayerController.gPUStreamerKit.rtcClient.authString = [NSString stringWithFormat:@"https://rtc.vcloud.ks-live.com:6001/auth?%@",[responseJson toString:@"auth_string"]];
  740. // self.ksyLinkMicPlayerController.gPUStreamerKit.rtcClient.localId = [responseJson toString:@"uid"];
  741. // [self.ksyLinkMicPlayerController.gPUStreamerKit.rtcClient registerRTC];
  742. }
  743. }
  744. } FailureBlock:^(NSError *error) {
  745. }];
  746. }
  747. #pragma mark - ----------------------- 连麦 -----------------------
  748. #pragma mark 观众检查是否有连麦权限(主播不需要此操作)
  749. - (void)startLianmai:(CustomMessageModel *)customMessageModel
  750. {
  751. NSMutableDictionary *mDict = [NSMutableDictionary dictionary];
  752. [mDict setObject:@"video" forKey:@"ctl"];
  753. [mDict setObject:@"start_lianmai" forKey:@"act"];
  754. [mDict setObject:_roomIDStr forKey:@"room_id"];
  755. [mDict setObject:customMessageModel.sender.user_id forKey:@"to_user_id"];
  756. FWWeakify(self)
  757. [self.httpsManager POSTWithParameters:mDict SuccessBlock:^(NSDictionary *responseJson) {
  758. FWStrongify(self)
  759. if ([responseJson toInt:@"status"] == 1)
  760. {
  761. // if (self.mickType == FW_MICK_TYPE_KSY)
  762. // {
  763. // [self getRegisterIdStr:customMessageModel];
  764. // }else
  765. if (self.mickType == FW_MICK_TYPE_AGORA)
  766. {
  767. self.agoraLinkMicPlayerController.linkMicBaseController.delegate = self;
  768. [self.agoraLinkMicPlayerController startLinkMic:[[IMAPlatform sharedInstance].host imUserId] andResponderId:self.customResponderModel.sender.user_id roomId:self.roomIDStr];
  769. }
  770. }
  771. } FailureBlock:^(NSError *error) {
  772. }];
  773. }
  774. #pragma mark 主播收到观众连麦请求
  775. - (void)onRecvGuestApply:(CustomMessageModel *)customMessageModel
  776. {
  777. SenderModel *sender = customMessageModel.sender;
  778. if (_mikeCount >= _micMaxNum || _hostMickingAlert)
  779. {
  780. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  781. sendCustomMsgModel.msgType = MSG_REFUSE_MIKE;
  782. sendCustomMsgModel.msgReceiver = customMessageModel.sender;
  783. if (_hostMickingAlert)
  784. {
  785. sendCustomMsgModel.msg = ASLocalizedString(@"主播有未处理的连麦请求,请稍候再试");
  786. [_iMMsgHandler sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  787. }
  788. else
  789. {
  790. DebugLog(@"已达到请求上限,不能再请求");
  791. sendCustomMsgModel.msg = ASLocalizedString(@"当前主播主播连麦数已上限,请稍后尝试");
  792. [_iMMsgHandler sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  793. }
  794. }
  795. else
  796. {
  797. __weak BGIMMsgHandler *wm = (BGIMMsgHandler *)_iMMsgHandler;
  798. NSString *text = [NSString stringWithFormat:ASLocalizedString(@"观众(%@)申请参加您的互动直播"), [sender imUserName]];
  799. FWWeakify(self)
  800. _hostMickingAlert = [FanweMessage alert:ASLocalizedString(@"互动直播申请")message:text destructiveTitle:ASLocalizedString(@"同意")destructiveAction:^{
  801. FWStrongify(self)
  802. // 同意
  803. // if (self.mickType == FW_MICK_TYPE_KSY)
  804. // {
  805. // [self getRegisterIdStr:customMessageModel];
  806. // }else
  807. if (self.mickType == FW_MICK_TYPE_AGORA)
  808. {
  809. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  810. sendCustomMsgModel.msgType = MSG_RECEIVE_MIKE;
  811. sendCustomMsgModel.msgReceiver = _customApplicantModel.sender;
  812. [wm sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  813. [self.agoraLinkMicStreamerController startLinkMic:self.customApplicantModel.sender.user_id andResponderId:[[IMAPlatform sharedInstance].host imUserId] roomId:self.roomIDStr];
  814. }
  815. [self performSelector:@selector(releaseHostMickingAlert) withObject:nil afterDelay:0.2];
  816. } cancelTitle:ASLocalizedString(@"拒绝")cancelAction:^{
  817. FWStrongify(self)
  818. // 拒绝
  819. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  820. sendCustomMsgModel.msgType = MSG_REFUSE_MIKE;
  821. sendCustomMsgModel.msgReceiver = customMessageModel.sender;
  822. [wm sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  823. [self performSelector:@selector(releaseHostMickingAlert) withObject:nil afterDelay:0.2];
  824. }];
  825. }
  826. }
  827. #pragma mark 主播未处理连麦申请时,kApplyMikeTime秒后关闭申请连麦弹出框
  828. - (void)closeAlertView
  829. {
  830. if (_hostMickingAlert)
  831. {
  832. [_hostMickingAlert hide];
  833. [self performSelector:@selector(releaseHostMickingAlert) withObject:nil afterDelay:0.2];
  834. }
  835. }
  836. #pragma mark 判断是否互动观众
  837. - (BOOL)isInteractUser:(NSString *)userId
  838. {
  839. if (userId)
  840. {
  841. for (NSString *tmpUserId in _mickUserMArray)
  842. {
  843. if ([userId isEqualToString:tmpUserId])
  844. {
  845. return YES;
  846. }
  847. }
  848. }
  849. return NO;
  850. }
  851. #pragma mark TCShowLiveViewToSDKDelegate
  852. - (void)hideReLiveSlide:(BOOL)isHided
  853. {
  854. if (isHided)
  855. {
  856. _reLiveProgressView.hidden = YES;
  857. }
  858. else
  859. {
  860. if (self.hasVideoControl)
  861. {
  862. _reLiveProgressView.hidden = NO;
  863. }
  864. }
  865. }
  866. #pragma mark 主播点击屏幕时,判断是否点击了连麦窗口
  867. - (void)hostReceiveTouch:(UITouch *)touch
  868. {
  869. if ([self.mickUserMArray count])
  870. {
  871. for (NSString *user in self.mickUserMArray)
  872. {
  873. CGRect mickUserRect = CGRectMake(kScreenW * kLinkMickXRate, kScreenH * kLinkMickYRate, kScreenW * kLinkMickWRate, kScreenH * kLinkMickHRate);
  874. if(CGRectContainsPoint(mickUserRect, [touch locationInView:self.view]))
  875. {
  876. UserModel *userModel;
  877. for (UserModel *tmpModel in _liveServiceController.liveUIViewController.liveView.topView.userArray)
  878. {
  879. if ([tmpModel.user_id isEqualToString:user])
  880. {
  881. userModel = tmpModel;
  882. break;
  883. }
  884. }
  885. if (!userModel)
  886. {
  887. userModel = [[UserModel alloc]init];
  888. userModel.user_id = user;
  889. }
  890. MMPopupCompletionBlock completeBlock = ^(MMPopupView *popupView, BOOL finished){
  891. NSLog(@"animation complete");
  892. };
  893. HostCheckMickAlertView *view = [[HostCheckMickAlertView alloc] initAlertView:userModel closeMickBlock:^(UserModel *userModel) {
  894. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  895. sendCustomMsgModel.msgType = MSG_BREAK_MIKE;
  896. sendCustomMsgModel.msgReceiver = userModel;
  897. [[BGIMMsgHandler sharedInstance] sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  898. // if (self.mickType == FW_MICK_TYPE_AGORA)
  899. // {
  900. //// [_agoraLinkMicStreamerController.gPUStreamerKit leaveChannel];
  901. // [_agoraLinkMicStreamesrController stopLinkMic:[[IMAPlatform sharedInstance].host imUserId]];
  902. // }
  903. }];
  904. [view showWithBlock:completeBlock];
  905. }
  906. }
  907. }
  908. }
  909. #pragma mark 观众发起连麦,关闭连麦
  910. - (void)openOrCloseMike:(BGLiveServiceController *)liveServiceController
  911. {
  912. if (_ksyLinkMicPlayerController.isWaitingResponse)
  913. {
  914. [FanweMessage alertHUD:ASLocalizedString(@"连麦申请中...")];
  915. return;
  916. }
  917. __weak typeof(self) ws = self;
  918. if ([self isInteractUser:[[IMAPlatform sharedInstance].host imUserId]])
  919. {
  920. [FanweMessage alert:nil message:ASLocalizedString(@"是否结束与主播的互动直播?")destructiveAction:^{
  921. // if (self.mickType == FW_MICK_TYPE_KSY)
  922. // {
  923. // [ws.ksyLinkMicPlayerController stopLinkMic:[[IMAPlatform sharedInstance].host imUserId]];
  924. // }else
  925. if (self.mickType == FW_MICK_TYPE_AGORA)
  926. {
  927. [ws.agoraLinkMicPlayerController stopLinkMic:[[IMAPlatform sharedInstance].host imUserId]];
  928. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  929. sendCustomMsgModel.msgType = MSG_BREAK_MIKE;
  930. sendCustomMsgModel.msgReceiver = [ws.liveItem liveHost];
  931. [[BGIMMsgHandler sharedInstance] sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  932. }
  933. } cancelAction:^{
  934. }];
  935. }
  936. else
  937. {
  938. __weak BGIMMsgHandler *wd = _iMMsgHandler;
  939. [FanweMessage alert:nil message:ASLocalizedString(@"是否请求与主播连麦?")destructiveAction:^{
  940. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  941. sendCustomMsgModel.msgType = MSG_APPLY_MIKE;
  942. sendCustomMsgModel.msgReceiver = [ws.liveItem liveHost];
  943. [wd sendCustomC2CMsg:sendCustomMsgModel succ:^{
  944. [ws performSelector:@selector(alertLinkMicking) withObject:nil afterDelay:0.2];
  945. } fail:^(int code, NSString *msg) {
  946. [FanweMessage alertHUD:ASLocalizedString(@"您的连麦申请发送失败")];
  947. }];
  948. } cancelAction:^{
  949. }];
  950. }
  951. }
  952. #pragma mark 申请连麦中,等待对方应答...
  953. - (void)alertLinkMicking
  954. {
  955. _isApplyMicking = YES;
  956. FWWeakify(self)
  957. _applyMickingAlert = [FanweMessage alert:ASLocalizedString(@"提示")message:ASLocalizedString(@"申请连麦中,等待对方应答...")isHideTitle:NO destructiveTitle:ASLocalizedString(@"取消连麦")destructiveAction:^{
  958. FWStrongify(self)
  959. self.isApplyMicking = NO;
  960. [self performSelector:@selector(releaseMickingAlert) withObject:nil afterDelay:0.5];
  961. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  962. sendCustomMsgModel.msgType = MSG_BREAK_MIKE;
  963. sendCustomMsgModel.msgReceiver = [self.liveItem liveHost];
  964. [self.iMMsgHandler sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  965. //
  966. //
  967. // FWStrongify(self)
  968. // self.isApplyMicking = NO;
  969. // [self performSelector:@selector(releaseMickingAlert) withObject:nil afterDelay:0.5];
  970. }];
  971. }
  972. #pragma mark 关闭申请连麦中的提示
  973. - (void)cancelMickingAlert
  974. {
  975. if (_applyMickingAlert)
  976. {
  977. _isApplyMicking = NO;
  978. [_applyMickingAlert hide];
  979. [self performSelector:@selector(releaseMickingAlert) withObject:nil afterDelay:0.5];
  980. }
  981. }
  982. - (void)releaseMickingAlert
  983. {
  984. if (_applyMickingAlert)
  985. {
  986. _applyMickingAlert = nil;
  987. }
  988. }
  989. - (void)releaseHostMickingAlert
  990. {
  991. if (_hostMickingAlert)
  992. {
  993. _hostMickingAlert = nil;
  994. }
  995. }
  996. - (void)showRefuseHud:(NSString *)refuseStr
  997. {
  998. if (![BGUtils isBlankString:refuseStr])
  999. {
  1000. [FanweMessage alert:refuseStr];
  1001. }
  1002. }
  1003. #pragma mark 观众端连麦结果
  1004. /*
  1005. * 观众端连麦结果
  1006. * isSucc:是否上麦
  1007. * applicantId:申请连麦者ID
  1008. */
  1009. - (void)applicantLinkMickResult:(BOOL)isSucc applicantId:(NSString *)applicantId
  1010. {
  1011. if (![BGUtils isBlankString:applicantId])
  1012. {
  1013. if (isSucc)
  1014. {
  1015. [_mickUserMArray addObject:applicantId];
  1016. }
  1017. else
  1018. {
  1019. if ([_mickUserMArray containsObject:applicantId])
  1020. {
  1021. [_mickUserMArray removeObject:applicantId];
  1022. SendCustomMsgModel *sendCustomMsgModel = [[SendCustomMsgModel alloc] init];
  1023. sendCustomMsgModel.msgType = MSG_BREAK_MIKE;
  1024. sendCustomMsgModel.msgReceiver = [self.liveItem liveHost];
  1025. [_iMMsgHandler sendCustomC2CMsg:sendCustomMsgModel succ:nil fail:nil];
  1026. }
  1027. if ([_registerMickUserMArray containsObject:applicantId])
  1028. {
  1029. [_registerMickUserMArray removeObject:applicantId];
  1030. }
  1031. }
  1032. }
  1033. }
  1034. #pragma mark 主播端连麦结果
  1035. /*
  1036. * 主播端连麦结果
  1037. * isSucc:YES:连麦 NO:断开连麦
  1038. * applicantId:申请连麦者ID
  1039. */
  1040. - (void)responderLinkMickResult:(BOOL)isSucc applicantId:(NSString *)applicantId
  1041. {
  1042. if (![BGUtils isBlankString:applicantId])
  1043. {
  1044. if (isSucc)
  1045. {
  1046. [_mickUserMArray addObject:applicantId];
  1047. }
  1048. else
  1049. {
  1050. if ([_mickUserMArray containsObject:applicantId])
  1051. {
  1052. [_mickUserMArray removeObject:applicantId];
  1053. }
  1054. if ([_registerMickUserMArray containsObject:applicantId])
  1055. {
  1056. [_registerMickUserMArray removeObject:applicantId];
  1057. }
  1058. }
  1059. }
  1060. }
  1061. #pragma mark 声网连麦/断开连麦
  1062. /*
  1063. * 声网连麦/断开连麦
  1064. * isLinked:YES:连麦 NO:断开连麦
  1065. * applicantId:申请连麦者ID
  1066. */
  1067. - (void)linkOrBreakMick:(BOOL)isLinked applicantId:(NSString *)applicantId
  1068. {
  1069. if (isLinked)
  1070. {
  1071. if(applicantId != nil)
  1072. {
  1073. [_mickUserMArray addObject:applicantId];
  1074. }
  1075. }
  1076. else
  1077. {
  1078. if(applicantId !=nil)
  1079. {
  1080. if ([_mickUserMArray containsObject:applicantId])
  1081. {
  1082. [_mickUserMArray removeObject:applicantId];
  1083. }
  1084. }
  1085. }
  1086. }
  1087. #pragma mark - ----------------------- 横竖屏 -----------------------
  1088. - (void)goVerticalScreen
  1089. {
  1090. [self interfaceOrientation:UIInterfaceOrientationPortrait];
  1091. }
  1092. #pragma mark PC直播或者PC回播,观众端的点击全屏事件
  1093. - (void)clickFullScreen
  1094. {
  1095. [self interfaceOrientation:UIInterfaceOrientationLandscapeRight];
  1096. }
  1097. - (void)interfaceOrientation:(UIInterfaceOrientation)orientation
  1098. {
  1099. if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
  1100. {
  1101. SEL selector = NSSelectorFromString(@"setOrientation:");
  1102. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
  1103. [invocation setSelector:selector];
  1104. [invocation setTarget:[UIDevice currentDevice]];
  1105. int val = orientation;
  1106. [invocation setArgument:&val atIndex:2];
  1107. [invocation invoke];
  1108. }
  1109. }
  1110. - (void)deviceOrientationDidChange
  1111. {
  1112. if (self.liveInfo.create_type == 1)
  1113. {
  1114. NSLog(@"deviceOrientationDidChange:%ld",(long)[UIDevice currentDevice].orientation);
  1115. if([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait)
  1116. {
  1117. [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
  1118. [self orientationChange:kDirectionTypeDefault];
  1119. }
  1120. else if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft)
  1121. {
  1122. [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
  1123. [self orientationChange:kDirectionTypeLeft];
  1124. }
  1125. }
  1126. }
  1127. - (void)orientationChange:(kDirectionType)landscape
  1128. {
  1129. if (landscape == kDirectionTypeDefault)
  1130. {
  1131. [[UIApplication sharedApplication] setStatusBarHidden:NO];
  1132. _liveServiceController.liveUIViewController.liveView.hidden = NO;
  1133. _liveServiceController.closeBtn.hidden = NO;
  1134. [UIView animateWithDuration:0.2f animations:^{
  1135. self.view.transform = CGAffineTransformMakeRotation(0);
  1136. self.view.bounds = CGRectMake(0, 0, kScreenW, kScreenH);
  1137. if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1138. {
  1139. // if (self.mickType == FW_MICK_TYPE_KSY)
  1140. // {
  1141. // _ksyLinkMicPlayerController.videoContrainerView.frame = CGRectMake(0, 0, kScreenW, kScreenH);
  1142. // _ksyLinkMicPlayerController.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
  1143. // self.backVerticalBtn.hidden = YES;
  1144. // }else
  1145. if(self.mickType == FW_MICK_TYPE_AGORA)
  1146. {
  1147. _agoraLinkMicPlayerController.videoContrainerView.frame = CGRectMake(0, 0, kScreenW, kScreenH);
  1148. // _agoraLinkMicPlayerController.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
  1149. self.backVerticalBtn.hidden = YES;
  1150. }
  1151. }
  1152. }];
  1153. }
  1154. else if (landscape == kDirectionTypeLeft)
  1155. {
  1156. [[UIApplication sharedApplication] setStatusBarHidden:YES];
  1157. _liveServiceController.liveUIViewController.liveView.hidden = YES;
  1158. _liveServiceController.closeBtn.hidden = YES;
  1159. [UIView animateWithDuration:0.2f animations:^{
  1160. self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
  1161. self.view.bounds = CGRectMake(0, 0, kScreenW, kScreenH);
  1162. if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1163. {
  1164. // if (self.mickType == FW_MICK_TYPE_KSY)
  1165. // {
  1166. // _ksyLinkMicPlayerController.videoContrainerView.frame = CGRectMake(0, 0, kScreenW, kScreenH);
  1167. // _ksyLinkMicPlayerController.moviePlayer.scalingMode = MPMovieScalingModeFill;
  1168. // self.backVerticalBtn.hidden = NO;
  1169. // }else
  1170. if(self.mickType == FW_MICK_TYPE_AGORA)
  1171. {
  1172. _agoraLinkMicPlayerController.videoContrainerView.frame = CGRectMake(0, 0, kScreenW, kScreenH);
  1173. // _agoraLinkMicPlayerController.txLivePlayer.scalingMode = MPMovieScalingModeFill;
  1174. self.backVerticalBtn.hidden = NO;
  1175. }
  1176. }
  1177. }];
  1178. }
  1179. }
  1180. #pragma mark - ----------------------- 代理方法 -----------------------
  1181. #pragma mark FWLiveServiceControllerDelegate
  1182. #pragma mark 收到自定义C2C消息
  1183. - (void)recvCustomC2C:(id<AVIMMsgAble>)msg
  1184. {
  1185. if (![msg isKindOfClass:[CustomMessageModel class]])
  1186. {
  1187. return;
  1188. }
  1189. CustomMessageModel *customMessageModel = (CustomMessageModel *)msg;
  1190. switch (customMessageModel.type)
  1191. {
  1192. case MSG_APPLY_MIKE: // 观众申请连麦(主播收到观众连麦请求消息)
  1193. {
  1194. _customApplicantModel = customMessageModel;
  1195. // 关闭键盘
  1196. [BGUtils closeKeyboard];
  1197. _ksyLinkMicPlayerController.isWaitingResponse = YES;
  1198. [self onRecvGuestApply:customMessageModel];
  1199. }
  1200. break;
  1201. case MSG_RECEIVE_MIKE: // 主播接受连麦(观众收到主播接受连麦消息)
  1202. {
  1203. if (_isApplyMicking)
  1204. {
  1205. _customResponderModel = customMessageModel;
  1206. // 关闭键盘
  1207. [BGUtils closeKeyboard];
  1208. // 关闭Alert窗口
  1209. [self cancelMickingAlert];
  1210. // if (self.mickType == FW_MICK_TYPE_KSY)
  1211. // {
  1212. // [_ksyLinkMicPlayerController startRegister:[[IMAPlatform sharedInstance].host imUserId]];
  1213. // [self getRegisterIdStr:customMessageModel];
  1214. // }else
  1215. if (self.mickType == FW_MICK_TYPE_AGORA)
  1216. {
  1217. [self startLianmai:customMessageModel];
  1218. }
  1219. }
  1220. }
  1221. break;
  1222. case MSG_REFUSE_MIKE: // 主播拒绝连麦(观众收到主播拒绝连麦消息)
  1223. {
  1224. [self cancelMickingAlert];
  1225. _ksyLinkMicPlayerController.isWaitingResponse = NO;
  1226. NSString *refuseStr = ASLocalizedString(@"主播拒绝了您的连麦请求");
  1227. if (![BGUtils isBlankString:customMessageModel.msg])
  1228. {
  1229. refuseStr = customMessageModel.msg;
  1230. }
  1231. [self performSelector:@selector(showRefuseHud:) withObject:refuseStr afterDelay:0.8];
  1232. }
  1233. break;
  1234. case MSG_BREAK_MIKE: // 断开连麦(观众收到主播断开连麦消息 或者 主播收到观众主动断开连麦消息)
  1235. {
  1236. // if (self.mickType == FW_MICK_TYPE_KSY)
  1237. // {
  1238. // [_ksyLinkMicPlayerController stopLinkMic:[[IMAPlatform sharedInstance].host imUserId]];
  1239. // }else
  1240. if (self.mickType == FW_MICK_TYPE_AGORA)
  1241. {
  1242. if (_isHost)
  1243. {
  1244. [_agoraLinkMicStreamerController stopLinkMic:[[IMAPlatform sharedInstance].host imUserId]];
  1245. }
  1246. else
  1247. {
  1248. [_agoraLinkMicPlayerController stopLinkMic:[[IMAPlatform sharedInstance].host imUserId]];
  1249. }
  1250. }
  1251. }
  1252. break;
  1253. default:
  1254. break;
  1255. }
  1256. }
  1257. #pragma mark 请求完接口后,刷新直播间相关信息
  1258. - (void)refreshCurrentLiveItem:(id<FWShowLiveRoomAble>)liveItem liveInfo:(CurrentLiveInfo *)liveInfo
  1259. {
  1260. [self refreshLiveItem:liveItem liveInfo:liveInfo];
  1261. }
  1262. #pragma mark 点击飞屏模式,切换直播间(因切换房间涉及到比较多的逻辑,比如:付费、游戏,所以该方法暂时不用)
  1263. - (void)switchLiveRoom
  1264. {
  1265. [self stopLiveRtmp];
  1266. [self startEnterChatGroup:nil succ:^{
  1267. NSLog(@"11111");
  1268. } failed:^(int errId, NSString *errMsg) {
  1269. NSLog(@"22222");
  1270. }];
  1271. }
  1272. #pragma mark 关闭直播间代理事件
  1273. - (void)clickCloseLive:(BOOL)isDirectCloseLive isHostShowAlert:(BOOL)isHostShowAlert
  1274. {
  1275. [self alertExitLive:isDirectCloseLive isHostShowAlert:isHostShowAlert succ:nil failed:nil];
  1276. }
  1277. #pragma mark 结束界面点击“返回首页”
  1278. - (void)finishViewClose:(BGLiveServiceController *)liveServiceController
  1279. {
  1280. // 已经走到这里了 必然更改记录
  1281. SUS_WINDOW.isDirectCloseLive = YES;
  1282. [self onExitLiveUI];
  1283. }
  1284. #pragma mark PlayControllerDelegate 结束回播,用来判断是否还有下一段回播
  1285. - (void)stopReLive
  1286. {
  1287. // 暂时不用做什么操作
  1288. }
  1289. #pragma mark ToolsViewDelegate
  1290. - (void)selectToolsItemWith:(ToolsView *)toolsView selectIndex:(NSInteger)index isSelected:(BOOL)isSelected
  1291. {
  1292. _toolsView = toolsView;
  1293. if (index == 0)
  1294. { // 音乐
  1295. [[[YunMusicPlayVC alloc] init] showYunMusicPlayInVC:self inview:self.liveServiceController.liveUIViewController.liveView showframe:CGRectMake(0,200, self.view.bounds.size.width,130) myPlayType:1];
  1296. // [FanweMessage alert:ASLocalizedString(@"亲,音乐模块后期开放,敬请期待...")];
  1297. // [choseMuiscVC showMuisChoseVCOnSuperVC:self inSuperView:<#(UIView *)#> frame:<#(CGRect)#> completion:<#^(BOOL finished)block#>]
  1298. // [choseMuiscVC showMuisChoseVCOnSuperVC:self frame:CGRectMake(0, 0,kScreenW,kScreenH) completion:^(BOOL finished) {
  1299. //
  1300. // }];
  1301. // [choseMuiscVC showMuisChoseVCOnSuperVC:self inSuperView:self.view frame:CGRectMake(0, 0,kScreenW,kScreenH) completion:^(BOOL finished) {
  1302. //
  1303. // }];
  1304. }
  1305. else if (index == 1)
  1306. { // 美颜
  1307. _beautyView.hidden = NO;
  1308. }
  1309. else if (index == 2)
  1310. { // 麦克风
  1311. if (isSelected == YES)
  1312. {
  1313. [FanweMessage alert:ASLocalizedString(@"已打开麦克风")];
  1314. _isMuted = NO;
  1315. [self setSDKMute:YES];
  1316. }
  1317. else
  1318. {
  1319. [FanweMessage alert:ASLocalizedString(@"已关闭麦克风")];
  1320. _isMuted = YES;
  1321. [self setSDKMute:NO];
  1322. }
  1323. }
  1324. else if (index == 3)
  1325. { // 切换摄像
  1326. // if (self.mickType == FW_MICK_TYPE_KSY)
  1327. // {
  1328. // if (_ksyLinkMicStreamerController.gPUStreamerKit.cameraPosition == AVCaptureDevicePositionBack)
  1329. // {
  1330. // // 关闭LED
  1331. // [BGUtils turnOnFlash:NO];
  1332. // [toolsView.toolsCollectionView deselectItemAtIndexPath:[NSIndexPath indexPathWithIndex:4] animated:NO];
  1333. // }
  1334. // [_ksyLinkMicStreamerController.gPUStreamerKit switchCamera];
  1335. // } else
  1336. if(self.mickType == FW_MICK_TYPE_AGORA)
  1337. {
  1338. if (_agoraLinkMicStreamerController.gPUStreamerKit.cameraPosition == AVCaptureDevicePositionBack)
  1339. {
  1340. // 关闭LED
  1341. [BGUtils turnOnFlash:NO];
  1342. [toolsView.toolsCollectionView deselectItemAtIndexPath:[NSIndexPath indexPathWithIndex:4] animated:NO];
  1343. }
  1344. [_agoraLinkMicStreamerController.gPUStreamerKit switchCamera];
  1345. }
  1346. }
  1347. else if (index == 4)
  1348. { // 关闭闪光
  1349. // if (self.mickType == FW_MICK_TYPE_KSY)
  1350. // {
  1351. // if (_ksyLinkMicStreamerController.gPUStreamerKit.cameraPosition == AVCaptureDevicePositionFront)
  1352. // {
  1353. // [FanweMessage alert:ASLocalizedString(@"前置摄像头下暂时不能打开闪光灯")];
  1354. // return;
  1355. // }
  1356. //
  1357. // // 打开、关闭LED
  1358. // [_ksyLinkMicStreamerController.gPUStreamerKit toggleTorch];
  1359. // }else
  1360. if(self.mickType == FW_MICK_TYPE_AGORA)
  1361. {
  1362. if (_agoraLinkMicStreamerController.gPUStreamerKit.cameraPosition == AVCaptureDevicePositionFront)
  1363. {
  1364. [FanweMessage alert:ASLocalizedString(@"前置摄像头下暂时不能打开闪光灯")];
  1365. return;
  1366. }
  1367. // 打开、关闭LED
  1368. [_agoraLinkMicStreamerController.gPUStreamerKit toggleTorch];
  1369. }
  1370. }
  1371. else if (index == 5)
  1372. {
  1373. if (isSelected == YES)
  1374. {
  1375. [FanweMessage alert:ASLocalizedString(@"已打开镜像")];
  1376. }
  1377. else
  1378. {
  1379. [FanweMessage alert:ASLocalizedString(@"已关闭镜像")];
  1380. }
  1381. [self setSDKMirror:isSelected];
  1382. }
  1383. }
  1384. #pragma mark TCShowLiveViewOfBeautyDelegate
  1385. #pragma mark -美颜美白
  1386. - (void)onBeautySetSkinOfCarevalue:(CGFloat)buffingOfCarevalue skinOfCarevalue:(CGFloat)skinOfCarevalue skinOfWhiteValue:(CGFloat)skinOfWhiteValue
  1387. {
  1388. KSYBeautifyProFilter *proFilter =[[KSYBeautifyProFilter alloc]init];
  1389. // 磨皮
  1390. proFilter.grindRatio = buffingOfCarevalue;
  1391. // 美白
  1392. proFilter.whitenRatio = skinOfCarevalue;
  1393. // 红润
  1394. proFilter.ruddyRatio = skinOfWhiteValue;
  1395. [self.ksyLinkMicStreamerController.gPUStreamerKit setupFilter:proFilter];
  1396. }
  1397. #pragma mark FWKSYAgoraStreamerBaseControllerDelegate
  1398. #pragma mark 首帧回调
  1399. - (void)firstAgoraFrame:(BGKSYAgoraStreamerBaseController *)publishVC
  1400. {
  1401. if (!_hasShowVagueImg)
  1402. {
  1403. [self hideVagueImgView];
  1404. SUS_WINDOW.isPushStreamIng = YES;
  1405. }
  1406. }
  1407. #pragma mark 网络断连,且经多次重连抢救无效后退出直播
  1408. - (void)exitAgoraPublish:(BGKSYAgoraStreamerBaseController *)publishVC
  1409. {
  1410. [self alertExitLive:NO isHostShowAlert:NO succ:nil failed:nil];
  1411. }
  1412. #pragma mark FWTPlayControllerDelegate
  1413. #pragma mark 腾讯云直播的观众、回播首帧回调
  1414. - (void)firstFrame:(BGTPlayController*)playVC
  1415. {
  1416. [self hideVagueImgView];
  1417. }
  1418. #pragma mark 拉流时,网络断连,重连
  1419. - (void)playAgain:(BGTPlayController *)publishVC isHideLeaveTip:(BOOL)isHideLeaveTip
  1420. {
  1421. if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1422. {
  1423. // if (self.mickType == FW_MICK_TYPE_KSY)
  1424. // {
  1425. // [_ksyLinkMicPlayerController reloadPlay];
  1426. // }else
  1427. if(self.mickType == FW_MICK_TYPE_AGORA)
  1428. {
  1429. [_agoraLinkMicPlayerController reloadPlay];
  1430. }
  1431. }
  1432. if (!_liveServiceController.anchorLeaveTipLabel.isHidden && isHideLeaveTip)
  1433. {
  1434. _liveServiceController.anchorLeaveTipLabel.hidden = YES;
  1435. }
  1436. }
  1437. #pragma mark 拉流时,网络断连,且经多次重连抢救无效后退出app
  1438. - (void)exitPlayAndApp:(BGTPlayController *)publishVC
  1439. {
  1440. [self alertExitLive:YES isHostShowAlert:NO succ:nil failed:nil];
  1441. }
  1442. #pragma mark 首帧回调
  1443. - (void)firstIFrame:(BGKSYStreamerController *)publishVC
  1444. {
  1445. [self hideVagueImgView];
  1446. SUS_WINDOW.isPushStreamIng = YES;
  1447. }
  1448. #pragma mark 网络断连,且经多次重连抢救无效后退出app
  1449. - (void)exitPublishAndApp:(BGKSYStreamerController *)publishVC
  1450. {
  1451. [self alertExitLive:NO isHostShowAlert:NO succ:nil failed:nil];
  1452. }
  1453. #pragma mark livePayDelegate
  1454. #pragma mark 付费直播是否加载直播间视频的代理
  1455. - (void)livePayLoadVedioIsComfirm:(BOOL)isComfirm
  1456. {
  1457. if (isComfirm)
  1458. {
  1459. if (!self.hasEnterChatGroup)
  1460. {
  1461. [self.ksyLinkMicPlayerController stopPlay];
  1462. [self.liveServiceController.liveUIViewController dealLivepayTComfirm];
  1463. FWWeakify(self)
  1464. [self.liveServiceController getVideo:^(CurrentLiveInfo *liveInfo) {
  1465. FWStrongify(self)
  1466. self.liveInfo = liveInfo;
  1467. [self beginPlayVideo:liveInfo];
  1468. self.hasVideoControl = liveInfo.has_video_control ? YES : NO;
  1469. [super startEnterChatGroup:_liveInfo.group_id succ:nil failed:nil];
  1470. } roomID:@"" failed:^(int errId, NSString *errMsg) {
  1471. }];
  1472. }
  1473. }
  1474. else
  1475. {
  1476. [self alertExitLive:YES isHostShowAlert:NO succ:nil failed:nil];
  1477. }
  1478. }
  1479. #pragma mark 付费直播关闭直播间的声音
  1480. - (void)voiceNotice:(NSNotification*)notification
  1481. {
  1482. NSMutableDictionary *dictM = [notification object];
  1483. if ([dictM toInt:@"type"] == 0)//关闭声音
  1484. {
  1485. [self setSDKMute:YES];
  1486. }
  1487. else if ([dictM toInt:@"type"] == 1)//打开声音
  1488. {
  1489. [self setSDKMute:NO];
  1490. }
  1491. }
  1492. #pragma mark - ----------------------- 实现FWLiveControllerAble协议 -----------------------
  1493. #pragma mark 开始推流、拉流
  1494. - (void)startLiveRtmp:(NSString *)playUrlStr
  1495. {
  1496. if (![BGUtils isBlankString:playUrlStr])
  1497. {
  1498. if (self.liveType == FW_LIVE_TYPE_HOST)
  1499. {
  1500. // if (self.mickType == FW_MICK_TYPE_KSY)
  1501. // {
  1502. // _ksyLinkMicStreamerController.pushUrl = [NSURL URLWithString:playUrlStr];
  1503. // [_ksyLinkMicStreamerController startRtmp];
  1504. // }else
  1505. if(self.mickType == FW_MICK_TYPE_AGORA)
  1506. {
  1507. _agoraLinkMicStreamerController.pushUrl = [NSURL URLWithString:playUrlStr];
  1508. [_agoraLinkMicStreamerController startRtmp];
  1509. }
  1510. }
  1511. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1512. {
  1513. // if (self.mickType == FW_MICK_TYPE_KSY)
  1514. // {
  1515. // [_ksyLinkMicPlayerController initPlayerWithUrl:[NSURL URLWithString:playUrlStr] createType:_liveInfo.create_type];
  1516. // }else
  1517. if(self.mickType == FW_MICK_TYPE_AGORA)
  1518. {
  1519. // [_agoraLinkMicPlayerController.txLivePlayer startPlay:playUrlStr type:PLAY_TYPE_LIVE_RTMP];
  1520. _agoraLinkMicPlayerController.playUrlStr = playUrlStr;
  1521. [_agoraLinkMicPlayerController startRtmp:PLAY_TYPE_LIVE_RTMP];
  1522. // [_agoraLinkMicPlayerController initPlayerWithUrl:[NSURL URLWithString:playUrlStr] createType:_liveInfo.create_type];
  1523. }
  1524. }
  1525. }
  1526. }
  1527. #pragma mark 结束推流、拉流
  1528. - (void)stopLiveRtmp
  1529. {
  1530. if (self.liveType == FW_LIVE_TYPE_HOST)
  1531. {
  1532. // if (self.mickType == FW_MICK_TYPE_KSY)
  1533. // {
  1534. // [_ksyLinkMicStreamerController stopRtmp];
  1535. // }else
  1536. if(self.mickType == FW_MICK_TYPE_AGORA)
  1537. {
  1538. [_agoraLinkMicStreamerController stopRtmp];
  1539. }
  1540. }
  1541. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1542. {
  1543. // if (self.mickType == FW_MICK_TYPE_KSY)
  1544. // {
  1545. // [_ksyLinkMicPlayerController stopPlay];
  1546. // }else
  1547. if(self.mickType == FW_MICK_TYPE_AGORA)
  1548. {
  1549. [_agoraLinkMicPlayerController.txLivePlayer stopPlay];
  1550. }
  1551. }
  1552. }
  1553. #pragma mark 获取当前视频容器视图的父视图
  1554. - (UIView *)getPlayViewBottomView
  1555. {
  1556. if (self.liveType == FW_LIVE_TYPE_HOST)
  1557. {
  1558. // if (self.mickType == FW_MICK_TYPE_KSY)
  1559. // {
  1560. // return _ksyLinkMicStreamerController.view;
  1561. // }else
  1562. if(self.mickType == FW_MICK_TYPE_AGORA)
  1563. {
  1564. return _agoraLinkMicStreamerController.view;
  1565. }
  1566. }
  1567. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1568. {
  1569. // if (self.mickType == FW_MICK_TYPE_KSY)
  1570. // {
  1571. // return _ksyLinkMicPlayerController.view;
  1572. // }else
  1573. if(self.mickType == FW_MICK_TYPE_AGORA)
  1574. {
  1575. return _agoraLinkMicPlayerController.view;
  1576. }
  1577. }
  1578. return nil;
  1579. }
  1580. #pragma mark 设置静音 YES:设置为静音
  1581. - (void)setSDKMute:(BOOL)bEnable
  1582. {
  1583. if (self.liveType == FW_LIVE_TYPE_HOST)
  1584. {
  1585. if (bEnable)
  1586. {
  1587. // if (self.mickType == FW_MICK_TYPE_KSY)
  1588. // {
  1589. // _ksyLinkMicStreamerController.gPUStreamerKit.aCapDev.micVolume = 1;
  1590. // // [[_ksyLinkMicStreamerController.gPUStreamerKit aCapDev] resumeCapture];
  1591. // }else
  1592. if(self.mickType == FW_MICK_TYPE_AGORA)
  1593. {
  1594. _agoraLinkMicStreamerController.gPUStreamerKit.aCapDev.micVolume = 1;
  1595. // [[_agoraLinkMicStreamerController.gPUStreamerKit aCapDev] resumeCapture];
  1596. }
  1597. }
  1598. else
  1599. {
  1600. // if (self.mickType == FW_MICK_TYPE_KSY)
  1601. // {
  1602. // _ksyLinkMicStreamerController.gPUStreamerKit.aCapDev.micVolume = 0;
  1603. // // [[_ksyLinkMicStreamerController.gPUStreamerKit aCapDev] pauseWithMuteData];
  1604. // }else
  1605. if(self.mickType == FW_MICK_TYPE_AGORA)
  1606. {
  1607. _agoraLinkMicStreamerController.gPUStreamerKit.aCapDev.micVolume = 0;
  1608. // [[_agoraLinkMicStreamerController.gPUStreamerKit aCapDev] pauseWithMuteData];
  1609. }
  1610. }
  1611. }
  1612. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1613. {
  1614. // if (self.mickType == FW_MICK_TYPE_KSY)
  1615. // {
  1616. // [_ksyLinkMicPlayerController.moviePlayer setShouldMute:bEnable];
  1617. // }else
  1618. if(self.mickType == FW_MICK_TYPE_AGORA)
  1619. {
  1620. [_agoraLinkMicPlayerController.txLivePlayer setMute:bEnable];
  1621. }
  1622. }
  1623. }
  1624. #pragma mark 设置镜像
  1625. - (void)setSDKMirror:(BOOL)bEnable
  1626. {
  1627. // if (self.mickType == FW_MICK_TYPE_KSY)
  1628. // {
  1629. // _ksyLinkMicStreamerController.gPUStreamerKit.streamerMirrored = bEnable;
  1630. // }else
  1631. if(self.mickType == FW_MICK_TYPE_AGORA)
  1632. {
  1633. _agoraLinkMicStreamerController.gPUStreamerKit.streamerMirrored = bEnable;
  1634. }
  1635. }
  1636. #pragma mark 获取当前直播质量
  1637. - (NSString *)getLiveQuality
  1638. {
  1639. KSYQosInfo *qosInfo;
  1640. NSMutableDictionary *mDict = [NSMutableDictionary dictionary];
  1641. // 设备类型
  1642. [mDict setObject:@"Ios" forKey:@"device"];
  1643. // app占用CPU
  1644. [mDict setObject:[NSString stringWithFormat:@"%f",[BGUtils getAppCpuUsage]] forKey:@"appCPURate"];
  1645. // // 系统占用CPU
  1646. // if ([tmpDict toFloat:NET_STATUS_CPU_USAGE])
  1647. // {
  1648. // [mDict setObject:[NSString stringWithFormat:@"%f",[tmpDict toFloat:NET_STATUS_CPU_USAGE]*100] forKey:@"sysCPURate"];
  1649. // }
  1650. if (self.liveType == FW_LIVE_TYPE_HOST)
  1651. {
  1652. // 实时帧率
  1653. double encFps = _deltaS.encodedFrames / _deltaS.timeSecond;
  1654. [mDict setObject:[NSString stringWithFormat:@"%f",encFps] forKey:@"fps"];
  1655. // 发送码率(每秒钟发送、接收的数据量)
  1656. double realTKbps = _deltaS.uploadKByte*8 / _deltaS.timeSecond;
  1657. [mDict setObject:[NSString stringWithFormat:@"%f",realTKbps] forKey:@"sendKBps"];
  1658. // 视频丢帧百分率
  1659. double dropPercent = _deltaS.droppedVFrames * 100.0 /MAX(_curState.encodedFrames, 1);
  1660. [mDict setObject:[NSString stringWithFormat:@"%f",dropPercent] forKey:@"sendLossRate"];
  1661. }
  1662. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1663. {
  1664. // if (self.mickType == FW_MICK_TYPE_KSY)
  1665. // {
  1666. // qosInfo = _ksyLinkMicPlayerController.moviePlayer.qosInfo;
  1667. // }else
  1668. if(self.mickType == FW_MICK_TYPE_AGORA)
  1669. {
  1670. // qosInfo = _agoraLinkMicPlayerController.moviePlayer.qosInfo;
  1671. }
  1672. // 画面帧率,如:25
  1673. if (qosInfo.videoRefreshFPS)
  1674. {
  1675. [mDict setObject:[NSString stringWithFormat:@"%f",qosInfo.videoRefreshFPS] forKey:@"fps"];
  1676. }
  1677. // 接收码率(每秒钟发送、接收的数据量)
  1678. // [mDict setObject:StringFromInt(totalkb) forKey:@"recvKBps"];
  1679. // 视频丢帧百分率
  1680. // [mDict setObject:[NSString stringWithFormat:@"%f",loss_rate_send] forKey:@"recvLossRate"];
  1681. }
  1682. NSString *sendMessage = [BGUtils dataTOjsonString:mDict];
  1683. if (sendMessage)
  1684. {
  1685. return sendMessage;
  1686. }
  1687. else
  1688. {
  1689. return @"";
  1690. }
  1691. return @"";
  1692. }
  1693. #pragma mark - ----------------------- sdk实时参数 -----------------------
  1694. #pragma mark 获取sdk相关试试参数
  1695. - (void)getStreamState
  1696. {
  1697. KSYStreamerBase *streamerBase;
  1698. // if (self.mickType == FW_MICK_TYPE_KSY)
  1699. // {
  1700. // streamerBase = _ksyLinkMicStreamerController.gPUStreamerKit.streamerBase;
  1701. // }else
  1702. if(self.mickType == FW_MICK_TYPE_AGORA)
  1703. {
  1704. streamerBase = _agoraLinkMicStreamerController.gPUStreamerKit.streamerBase;
  1705. }
  1706. StreamState curState = {0};
  1707. curState.timeSecond = [[NSDate date]timeIntervalSince1970];
  1708. curState.uploadKByte = [streamerBase uploadedKByte];
  1709. curState.encodedFrames = [streamerBase encodedFrames];
  1710. curState.droppedVFrames = [streamerBase droppedVideoFrames];
  1711. _curState = curState;
  1712. StreamState deltaS = {0};
  1713. deltaS.timeSecond = curState.timeSecond -_lastStD.timeSecond ;
  1714. deltaS.uploadKByte = curState.uploadKByte -_lastStD.uploadKByte ;
  1715. deltaS.encodedFrames = curState.encodedFrames -_lastStD.encodedFrames ;
  1716. deltaS.droppedVFrames= curState.droppedVFrames-_lastStD.droppedVFrames;
  1717. _deltaS = deltaS;
  1718. _lastStD = curState;
  1719. }
  1720. #pragma mark TCShowLiveTopViewToSDKDelegate
  1721. #pragma mark 推拉流请求所的码率
  1722. - (void)refreshKBPS:(TCShowLiveTopView *)topView
  1723. {
  1724. [self getStreamState];
  1725. double speedK = 0;
  1726. if (self.liveType == FW_LIVE_TYPE_HOST)
  1727. {
  1728. speedK = _deltaS.uploadKByte * 8;
  1729. // 视频丢帧百分率
  1730. double dropPercent = _deltaS.droppedVFrames * 100.0 /MAX(_curState.encodedFrames, 1);
  1731. if (dropPercent <= 0.2)
  1732. {
  1733. _lossRateSendTipLabel.hidden = YES;
  1734. }
  1735. else if(dropPercent > 0.2 && dropPercent < 0.3)
  1736. {
  1737. _lossRateSendTipLabel.hidden = NO;
  1738. _lossRateSendTipLabel.text = kHostNetLowTip1;
  1739. _lossRateSendTipLabel.textColor = kYellowColor;
  1740. }
  1741. else
  1742. {
  1743. _lossRateSendTipLabel.hidden = NO;
  1744. _lossRateSendTipLabel.text = kHostNetLowTip2;
  1745. _lossRateSendTipLabel.textColor = kRedColor;
  1746. }
  1747. }
  1748. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1749. {
  1750. // if (self.mickType == FW_MICK_TYPE_KSY)
  1751. // {
  1752. // speedK = [_ksyLinkMicPlayerController speedK];
  1753. // }else
  1754. if(self.mickType == FW_MICK_TYPE_AGORA)
  1755. {
  1756. // speedK = [_agoraLinkMicPlayerController];
  1757. }
  1758. }
  1759. long totalkb = speedK / 8;
  1760. if (totalkb)
  1761. {
  1762. topView.kbpsSendLabel.hidden = NO;
  1763. topView.kbpsRecvLabel.hidden = YES;
  1764. CGRect newFrame = topView.kbpsSendLabel.frame;
  1765. newFrame.origin.y = CGRectGetHeight(topView.kbpsContainerView.frame)/4;
  1766. topView.kbpsSendLabel.frame = newFrame;
  1767. topView.kbpsSendLabel.text = [NSString stringWithFormat:@"%@%ldk",self.liveType == 0 ? @"↑" : @"↓" ,totalkb];
  1768. }
  1769. else
  1770. {
  1771. topView.kbpsSendLabel.hidden = YES;
  1772. topView.kbpsRecvLabel.hidden = YES;
  1773. }
  1774. }
  1775. #pragma mark - ----------------------- 其他 -----------------------
  1776. #pragma mark 悬浮window相关delegate
  1777. + (UIViewController *)showLiveViewCwith:(TCShowLiveListItem *)liveListItem
  1778. {
  1779. if (!liveListItem)
  1780. {
  1781. return nil;
  1782. }
  1783. else
  1784. {
  1785. return [[BGKSYLiveController alloc]initWith:liveListItem modelArr:nil];
  1786. }
  1787. }
  1788. #pragma mark 满屏处理完毕
  1789. - (void)showFullScreenFinished:(void (^)(BOOL))block{
  1790. }
  1791. - (void)showAnimationComplete:(void (^)(BOOL))block{
  1792. BOOL isSmallScreen;
  1793. // 小屏幕->满屏幕
  1794. if(LIVE_CENTER_MANAGER.liveWindowType == liveWindowTypeOfSusOfFullSize)
  1795. {
  1796. isSmallScreen = NO;
  1797. }
  1798. // 慢屏幕->小屏幕
  1799. else if( LIVE_CENTER_MANAGER.liveWindowType == LiveWindowTypeOfSusSmallSize)
  1800. {
  1801. isSmallScreen = YES;
  1802. }
  1803. else
  1804. {
  1805. // 非悬浮或扩展其他悬浮 下一步代码,当前不支持,请核对代码
  1806. isSmallScreen = NO;
  1807. if (block)
  1808. {
  1809. block(NO);
  1810. }
  1811. return;
  1812. }
  1813. // 公有特性
  1814. _liveServiceController.liveUIViewController.panGestureRec.enabled = isSmallScreen;
  1815. _liveServiceController.liveUIViewController.liveView.hidden = isSmallScreen;
  1816. if (block)
  1817. {
  1818. block(YES);
  1819. }
  1820. }
  1821. #pragma mark------------------------------------- 直播退出 私有方法
  1822. - (void)showCloseLiveSDKInFullScreenComplete:(void (^)(BOOL finished))block{
  1823. [self alertExitLive:YES isHostShowAlert:YES succ:^{
  1824. // 退出后直播管理层
  1825. NSLog(ASLocalizedString(@"退出后直播管理层"));
  1826. } failed:^(int errId, NSString *errMsg) {
  1827. // 退出失败
  1828. }];
  1829. }
  1830. #pragma mark 解决不能调为最小音量问题
  1831. - (void)volumeChanged:(NSNotification *)noti
  1832. {
  1833. NSDictionary *tmpDict = noti.userInfo;
  1834. if (tmpDict && [tmpDict isKindOfClass:[NSDictionary class]])
  1835. {
  1836. if ([[tmpDict toString:@"AVSystemController_AudioVolumeChangeReasonNotificationParameter"] isEqualToString:@"ExplicitVolumeChange"] && !_isMuted)
  1837. {
  1838. float volume = [[tmpDict objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
  1839. if (volume <= 0.062500)
  1840. {
  1841. if (self.liveType == FW_LIVE_TYPE_HOST)
  1842. {
  1843. }
  1844. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1845. {
  1846. // if (self.mickType == FW_MICK_TYPE_KSY)
  1847. // {
  1848. //
  1849. // }else
  1850. if(self.mickType == FW_MICK_TYPE_AGORA)
  1851. {
  1852. }
  1853. }
  1854. }
  1855. else
  1856. {
  1857. if (self.liveType == FW_LIVE_TYPE_HOST)
  1858. {
  1859. }
  1860. else if (self.liveType == FW_LIVE_TYPE_AUDIENCE)
  1861. {
  1862. // if (self.mickType == FW_MICK_TYPE_KSY)
  1863. // {
  1864. //
  1865. // }else
  1866. if(self.mickType == FW_MICK_TYPE_AGORA)
  1867. {
  1868. }
  1869. }
  1870. }
  1871. }
  1872. }
  1873. }
  1874. - (void)dealloc
  1875. {
  1876. [[NSNotificationCenter defaultCenter]removeObserver:self];
  1877. }
  1878. @end