webRtcPlayerViewController.m 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  1. //
  2. // webRtcPlayerViewController.m
  3. // 双子星云手机
  4. //
  5. // Created by xd h on 2024/9/2.
  6. //
  7. #import "webRtcPlayerViewController.h"
  8. #import "webRtcPlayerViewController+AdjustBtnFrame.h"
  9. #import "webRtcPlayerViewController+AdjustPlayerViewFrame.h"
  10. #import "webRtcPlayerViewController+AppDelegate.h"
  11. #import "UIInterface+HXRotation.h"
  12. #import "playerSetView.h"
  13. @interface webRtcPlayerViewController ()<MediaStreamClientEventsDelegate>
  14. {
  15. BOOL outputVolumeKVO;/*标记声音监听通知*/
  16. double lastTimestamp;/*最后一帧时间戳*/
  17. NSNumber *lastBytesReceived;/*最后一帧数据量*/
  18. UILabel* netWorkInfoLabel;//网络延时等信息 正式环境屏蔽
  19. //记录上次 线性增长接收包数
  20. long lasPacketsReceived;
  21. //记录上次 总丢包数据
  22. long lastAlllostData;
  23. BOOL isExitType;//退出云机
  24. }
  25. @property (nonatomic, copy) NSTimer *playerSecondTimer; // 定时器-控制按钮
  26. @property (nonatomic, assign) RTCIceConnectionState linkState;
  27. @property (nonatomic, assign) BOOL didHandleRotation;//第一次处理旋转
  28. @property (nonatomic, assign) BOOL needToReportWebRtcType;//上报打洞是否成功
  29. @end
  30. @implementation webRtcPlayerViewController
  31. @synthesize controlBtn;
  32. - (void)viewDidLoad {
  33. [super viewDidLoad];
  34. // Do any additional setup after loading the view.
  35. [self.toolBar setHidden:YES];
  36. [self.navigationBar setHidden:YES];
  37. [self.navBarBGView setHidden:YES];
  38. [self.view setBackgroundColor:[UIColor blackColor]];
  39. if([DFPlayer sharedPlayer].state == DFPlayerStateBuffering
  40. ||[DFPlayer sharedPlayer].state == DFPlayerStatePlaying){
  41. _isCodeSuspendAudioType = YES;
  42. [[DFPlayer sharedPlayer] df_pause];
  43. }
  44. }
  45. - (void)viewWillAppear:(BOOL)animated {
  46. [super viewWillAppear:animated];
  47. // 屏幕常亮
  48. [UIApplication sharedApplication].idleTimerDisabled = YES;
  49. [[UIApplication sharedApplication] setStatusBarHidden:YES];
  50. }
  51. - (void)viewDidAppear:(BOOL)animated
  52. {
  53. [super viewDidAppear:animated];
  54. [self noEnablePanRightBack];
  55. [self addKVOObserverFun];
  56. ksharedAppDelegate.supportScreenRotateType = YES;
  57. }
  58. - (void)viewDidDisappear:(BOOL)animated{
  59. [super viewDidDisappear:animated];
  60. [UIApplication sharedApplication].idleTimerDisabled = NO;
  61. [[UIApplication sharedApplication] setStatusBarHidden:NO];
  62. isExitType = YES;
  63. [_mediaStream disconnect];
  64. _mediaStream = nil;
  65. [self enablePanRightBack];
  66. [self removeKVOObserverFun];
  67. ksharedAppDelegate.supportScreenRotateType = NO;
  68. [self removeNewIndicator];
  69. [_playerSecondTimer invalidate];
  70. _webRtcMsgMod = nil;
  71. }
  72. - (void)setWebRtcMsgMod:(webRtcMsgModel *)webRtcMsgMod
  73. {
  74. _webRtcMsgMod = webRtcMsgMod;
  75. [self beginWebRtcPlayFun];
  76. }
  77. #pragma mark 开始拉流
  78. - (void)beginWebRtcPlayFun
  79. {
  80. if(_mediaStream){
  81. //[_mediaStream disconnect];
  82. //[_mediaStream removeFromSuperview];
  83. //_mediaStream = nil;
  84. }
  85. _mediaStream = [[RTC_OBJC_TYPE(AMediaStream) alloc] initWithFrame:CGRectZero];
  86. [_mediaStream setEventDelegate:self];
  87. [self.view addSubview:_mediaStream];
  88. HLog(@"_mediaStream:%@",_mediaStream)
  89. [_mediaStream mas_makeConstraints:^(MASConstraintMaker *make) {
  90. make.left.mas_equalTo(0.f);
  91. make.bottom.mas_equalTo(0.f);
  92. make.right.mas_equalTo(0.f);
  93. make.top.mas_equalTo(0.f);
  94. }];
  95. //判断是否是全屏
  96. BOOL fullscreenType = [HWDataManager getBoolWithKey:Consn_player_full_screen_show];
  97. CGSize phoneSize = CGSizeMake(1080.0, 1920.0);
  98. if(fullscreenType){
  99. phoneSize = [RCCommandHelp commondToSetFullScreenPhoneSizeBySize];
  100. }
  101. [self linkWebRtcFunWithSize:phoneSize];
  102. [self initBaseUIFun];
  103. [self setTimerCountDown];
  104. //CGFloat curRate = 1080.0/1920.0;
  105. //CGFloat curRate = phoneSize.width/phoneSize.height;
  106. [self showNewIndicatorWithCanBack:YES canTouch:NO];
  107. }
  108. #pragma mark 链接webrtc
  109. - (void)linkWebRtcFunWithSize:(CGSize)phoneSize
  110. {
  111. //链接用
  112. NSString *signallingUrl = [[NSString alloc] initWithFormat:@"%@:%@",_webRtcMsgMod.data.signalling.domainName,_webRtcMsgMod.data.signalling.port];
  113. NSURL *url = [NSURL URLWithString:signallingUrl];
  114. //ice用
  115. NSString *iceUrl = [[NSString alloc] initWithFormat:@"%@:%@",_webRtcMsgMod.data.turn.domainName,_webRtcMsgMod.data.turn.port];
  116. NSMutableDictionary *ice = [NSMutableDictionary new];
  117. if(iceUrl){
  118. [ice setValue:iceUrl forKey:@"CHINANET"];
  119. [ice setValue:iceUrl forKey:@"CMNET"];
  120. [ice setValue:iceUrl forKey:@"UNICOM"];
  121. }
  122. NSString *roomName = _webRtcMsgMod.data.uniqueIdentifier;
  123. NSInteger result = [_mediaStream start:url
  124. ice:ice
  125. sn:roomName
  126. direct:0
  127. fmt:1//1(h264) 5(h265)
  128. videoWidth:(NSInteger)phoneSize.width
  129. videoHeight:(NSInteger)phoneSize.height
  130. fps:30
  131. bitrate:3000
  132. cardWidth:0//1080//0
  133. cardHeight:0//1920//0
  134. cardDensity:0
  135. token:@"vclusters"];
  136. HLog(@"result:%ld",result)
  137. [_mediaStream setShouldGetStats:YES];
  138. }
  139. #pragma mark 重连
  140. - (void)relinkWebRtcFun
  141. {
  142. // if(_linkState == RTCIceConnectionStateConnected
  143. // || _linkState == RTCIceConnectionStateCompleted)
  144. // {//链接中 不处理重连事件
  145. // HLog(@"链接中 不处理重连事件")
  146. // return;
  147. // }
  148. if(isExitType){
  149. return;
  150. }
  151. HLog(@"发起重连 ......")
  152. KWeakSelf
  153. mainBlock(^{
  154. [weakSelf showNewIndicatorWithCanBack:YES canTouch:NO];
  155. //判断是否是全屏
  156. BOOL fullscreenType = [HWDataManager getBoolWithKey:Consn_player_full_screen_show];
  157. CGSize phoneSize = CGSizeMake(1080.0, 1920.0);
  158. if(fullscreenType){
  159. phoneSize = [RCCommandHelp commondToSetFullScreenPhoneSizeBySize];
  160. }
  161. [weakSelf linkWebRtcFunWithSize:phoneSize];
  162. });
  163. }
  164. #pragma mark 初始化其他UI
  165. - (void)initBaseUIFun
  166. {
  167. if(netWorkInfoLabel){
  168. [netWorkInfoLabel removeFromSuperview];
  169. netWorkInfoLabel = nil;
  170. }
  171. netWorkInfoLabel = [[UILabel alloc] init];
  172. [netWorkInfoLabel setTextColor:[UIColor greenColor]];
  173. [netWorkInfoLabel setBackgroundColor:HW000000Color60];
  174. [netWorkInfoLabel setFont:[UIFont systemFontOfSize:17]];
  175. [netWorkInfoLabel setNumberOfLines:0];
  176. [self.view addSubview:netWorkInfoLabel];
  177. [netWorkInfoLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  178. make.top.mas_equalTo(80);
  179. make.left.mas_equalTo(20);
  180. }];
  181. if(_bottomContrView){
  182. [_bottomContrView removeFromSuperview];
  183. _bottomContrView = nil;
  184. }
  185. _bottomContrView = [[webRtcPlayerBottomContrView alloc] init];
  186. [self.view addSubview:_bottomContrView];
  187. [self getPlayerBottomNavShowOrHidefun];
  188. KWeakSelf
  189. _bottomContrView.didClickButtonFun = ^(NSInteger tag) {
  190. [weakSelf didClickBottomFunBy:tag];
  191. };
  192. /*控制按钮*/
  193. if(controlBtn){
  194. [controlBtn removeFromSuperview];
  195. controlBtn = nil;
  196. }
  197. UIImage *driftBtnImage = [UIImage imageNamed:@"you_icon"];
  198. controlBtn = [[UIButton alloc] init];
  199. [controlBtn setBackgroundColor:[UIColor clearColor]];
  200. [controlBtn setBackgroundImage:driftBtnImage forState:(UIControlStateNormal)];
  201. [controlBtn addTarget:self
  202. action:@selector(controlBtnPressed:)
  203. forControlEvents:(UIControlEventTouchUpInside)];
  204. [self.view addSubview:controlBtn];
  205. //拖拽事件等
  206. UIPanGestureRecognizer *gester = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(controlBtnPanGestureCallback:)];
  207. [controlBtn addGestureRecognizer:gester];
  208. //gester.delegate = self;
  209. [self initPointForControlBtnFun];
  210. }
  211. #pragma mark 设置 controlBtn 的初始位置
  212. - (void)initPointForControlBtnFun
  213. {
  214. CGFloat h_w_controlBtn = 60.f;
  215. /*区分横竖屏*/
  216. if (_mediaStream.hw_w > _mediaStream.hw_h){
  217. [controlBtn setFrame:CGRectMake((_mediaStream.hw_w - h_w_controlBtn)/2.f, _mediaStream.hw_h - h_w_controlBtn - 20.f, h_w_controlBtn, h_w_controlBtn)];
  218. }else{
  219. //默认居右
  220. //[mPlayerView.controlBtn setFrame:CGRectMake(mPlayerView.width - h_w_controlBtn - 20.f, (SCREEN_H - h_w_controlBtn)/2.f, h_w_controlBtn, h_w_controlBtn)];
  221. //默认居左
  222. [controlBtn setFrame:CGRectMake( h_w_controlBtn + 10.f, (SCREEN_H - h_w_controlBtn)/2.f, h_w_controlBtn, h_w_controlBtn)];
  223. }
  224. }
  225. #pragma mark 定时器
  226. - (void)setTimerCountDown {
  227. HLog(@"开启一个");
  228. if (_playerSecondTimer) {
  229. // 取消定时器
  230. [_playerSecondTimer invalidate];
  231. _playerSecondTimer = nil;
  232. }
  233. // 初始化值计时数据
  234. //self.adjustTime = 1;
  235. //self.concentTime = [iTools getNowTimeStamp];
  236. _playerSecondTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(timerChange) userInfo:nil repeats:YES];
  237. [[NSRunLoop currentRunLoop] addTimer:_playerSecondTimer forMode:NSRunLoopCommonModes];
  238. }
  239. #pragma mark 定时器响应事件
  240. - (void)timerChange {
  241. [self extensionAdjustBtnFrameCheckAdjustTime];// 1、悬浮球3s后 自动靠边隐藏
  242. //[self checkConcentTime];// 3、30s之后 没有收到拉流数据 自动断开链接
  243. }
  244. #pragma mark 控制按钮点击事件
  245. - (void)controlBtnPressed:(UIButton*)but
  246. {
  247. playerSetView *nextVC = [[playerSetView alloc] init];
  248. [ksharedAppDelegate.window addSubview:nextVC];
  249. [nextVC mas_makeConstraints:^(MASConstraintMaker *make) {
  250. make.left.mas_equalTo(0);
  251. make.right.mas_equalTo(0);
  252. make.top.mas_equalTo(0.f);
  253. make.bottom.mas_equalTo(0.f);
  254. }];
  255. KWeakSelf
  256. nextVC.didClickButtonFun = ^(NSInteger tag) {
  257. switch (tag) {
  258. case 10:
  259. {//截图
  260. //self->needScreenShotType = YES;
  261. }
  262. break;
  263. #pragma mark 重启盒子
  264. case 11:
  265. {
  266. [weakSelf didClickRestartFun];
  267. }
  268. break;
  269. case 12:
  270. {//退出云机
  271. [weakSelf exitCloudPhoneFun];
  272. }
  273. break;
  274. case 100:
  275. {
  276. BOOL fullscreenType = [HWDataManager getBoolWithKey:Consn_player_full_screen_show];
  277. if(fullscreenType){
  278. [weakSelf showOpenTVP2PFun];
  279. }
  280. else{
  281. [weakSelf openTvShowFun];
  282. }
  283. }
  284. break;
  285. case 101:
  286. {
  287. weakSelf.controlBtn.userInteractionEnabled = NO;
  288. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  289. self->controlBtn.userInteractionEnabled = YES;
  290. });
  291. [weakSelf showCloseTVP2PFun];
  292. }
  293. break;
  294. default:
  295. break;
  296. }
  297. };
  298. }
  299. #pragma mark 点击了重启云机
  300. - (void)didClickRestartFun
  301. {
  302. KWeakSelf
  303. /*弹窗提示重启*/
  304. ComontAlretViewController *nextVC = [[ComontAlretViewController alloc] initWithTiTle:NSLocalizedString(@"my_set_no_restart_phone_tips",nil)
  305. msg:@""
  306. imageStr:@""
  307. cancelTitle:NSLocalizedString(@"other_cancel",nil)
  308. okTitle:NSLocalizedString(@"my_set_no_restart_phone_btn_ok",nil) isOkBtnHighlight:NO
  309. didClickOk:^{
  310. [weakSelf needToRebootFun];
  311. //提示语
  312. [[iToast makeText:NSLocalizedString(@"player_link_rebooting_Tips",nil)] show];
  313. } didClickCancel:^{
  314. }];
  315. nextVC.modalPresentationStyle = UIModalPresentationCustom;
  316. [self presentViewController:nextVC animated:YES completion:^{
  317. nextVC.view.superview.backgroundColor = [UIColor clearColor];
  318. }];
  319. }
  320. #pragma mark p2p通道 重启云机
  321. - (void)needToRebootFun
  322. {
  323. [[webRtcManager shareManager] needToRebootFun];
  324. [self startForceStartTimerFun];
  325. //[self pauseStream];
  326. [webRtcManager shareManager].isRebootIngType = YES;
  327. [self showNewIndicatorWithCanBack:YES canTouch:NO];
  328. }
  329. #pragma mark X 秒后检查是否软件重启成功
  330. - (void)startForceStartTimerFun
  331. {
  332. KWeakSelf
  333. //1. 5秒后跟硬件发起硬重启
  334. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  335. [weakSelf updateForceStartFun];
  336. });
  337. //2. 20秒后尝试重连
  338. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  339. [weakSelf relinkWebRtcFun];
  340. [[webRtcManager shareManager] relinkWebRtcFun];
  341. });
  342. }
  343. #pragma mark 需要强制重启
  344. - (void)updateForceStartFun{
  345. NSString* curSn = ksharedAppDelegate.DeviceThirdIdMod.data.changeSn;
  346. NSMutableDictionary *paraDict = [NSMutableDictionary dictionary];
  347. [paraDict setValue:curSn forKey:@"sn"];
  348. [paraDict setValue:[NSNumber numberWithBool:YES] forKey:@"isForceStart"];
  349. [[netWorkManager shareInstance] CommonPostCallBackCode:updateForceStart Parameters:paraDict success:^(id _Nonnull responseObject) {
  350. SuperModel *model = [[SuperModel alloc] initWithDictionary:responseObject error:nil];
  351. if (model.status == 0) {
  352. }
  353. else
  354. {
  355. }
  356. } failure:^(NSError * _Nonnull error) {
  357. HLog(@"%@", error);
  358. }];
  359. }
  360. #pragma mark 退出云机
  361. - (void)exitCloudPhoneFun
  362. {
  363. //[self setShowImgAndVoiceTypeFun:NO];
  364. if(_isCodeSuspendAudioType){
  365. [[DFPlayer sharedPlayer] df_play];
  366. }
  367. [self.navigationController popViewControllerAnimated:YES];
  368. }
  369. #pragma mark 显示关闭投屏提示语
  370. - (void)showOpenTVP2PFun{
  371. /*弹窗提示TV投屏*/
  372. ComontAlretViewController *nextVC = [[ComontAlretViewController alloc] initWithTiTle:NSLocalizedString(@"File_upload_Record_clear_Tip_title",nil)
  373. msg:NSLocalizedString(@"cloudPhone_fullscreen_tvshow_tip",nil)
  374. imageStr:@""
  375. cancelTitle:NSLocalizedString(@"other_cancel",nil)
  376. okTitle:NSLocalizedString(@"my_set_TVP2P_Open_sure",nil) isOkBtnHighlight:YES
  377. didClickOk:^{
  378. [self openTvShowFun];
  379. //关闭全屏屏
  380. [HWDataManager setBoolWithKey:Consn_player_full_screen_show value:NO];
  381. [self setPlayerFullScreenNotFun];
  382. } didClickCancel:^{
  383. }];
  384. nextVC.modalPresentationStyle = UIModalPresentationCustom;
  385. [self presentViewController:nextVC animated:YES completion:^{
  386. nextVC.view.superview.backgroundColor = [UIColor clearColor];
  387. }];
  388. }
  389. #pragma mark 开始投屏
  390. - (void)openTvShowFun
  391. {
  392. self.controlBtn.userInteractionEnabled = NO;
  393. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  394. self->controlBtn.userInteractionEnabled = YES;
  395. });
  396. [[webRtcManager shareManager] onTvFun];
  397. [[iToast makeText:NSLocalizedString(@"cloudPhone_TV_show_tip",nil)] show];
  398. //数据埋点
  399. [[netWorkManager shareInstance] DataEmbeddingPointBy:3 withEventValue:@"Cloud_tv"];
  400. }
  401. #pragma mark 显示关闭投屏提示语
  402. - (void)showCloseTVP2PFun{
  403. /*弹窗提示TV投屏*/
  404. ComontAlretViewController *nextVC = [[ComontAlretViewController alloc] initWithTiTle:NSLocalizedString(@"my_set_no_close_TV_p2p_tip",nil)
  405. msg:@""
  406. imageStr:@""
  407. cancelTitle:NSLocalizedString(@"other_cancel",nil)
  408. okTitle:NSLocalizedString(@"my_set_TVP2P_Open_sure",nil) isOkBtnHighlight:YES
  409. didClickOk:^{
  410. [self gotoCloseTVP2PFun];
  411. } didClickCancel:^{
  412. //HLog(@"2222");
  413. }];
  414. nextVC.modalPresentationStyle = UIModalPresentationCustom;
  415. [self presentViewController:nextVC animated:YES completion:^{
  416. nextVC.view.superview.backgroundColor = [UIColor clearColor];
  417. }];
  418. }
  419. #pragma mark 确认开始TV投屏
  420. -(void)gotoCloseTVP2PFun
  421. {
  422. [[webRtcManager shareManager] offTvFun];
  423. }
  424. #pragma mark 挤下线功能
  425. -(void)offlineOtherPhoneFun
  426. {
  427. NSString *curOaidStr = [RcGameWQKeyChain getOaidStringFun];
  428. if(!curOaidStr){
  429. curOaidStr = @"";
  430. }
  431. NSString *commondStr = [[NSString alloc] initWithFormat:@"{\"type\":\"login\",\"value\":\"%@\"}",curOaidStr];
  432. [self send_dataInPlayer:commondStr];
  433. }
  434. #pragma mark 单点登录被挤下线弹框
  435. - (void)LogoutByOtherFun:(NSString*)oaid
  436. {
  437. if(logoutAlertVC){
  438. return;
  439. }
  440. NSString *curOaidStr = [RcGameWQKeyChain getOaidStringFun];
  441. if(oaid
  442. && oaid.length >0
  443. && [oaid isEqualToString:curOaidStr]){
  444. return;
  445. }
  446. //[self didReceiveLogoutMsgFun];
  447. //yyyy-MM-dd HH:mm:ss
  448. NSString*dateStr = [iTools getNowTimeString2];
  449. if(dateStr && dateStr.length == 19){
  450. dateStr = [dateStr substringWithRange:NSMakeRange(11, 5)];
  451. }
  452. NSString *LogoutTimerStr = [[NSString alloc] initWithFormat:@"%@%@%@",NSLocalizedString(@"single_sign_on_Tips_one",nil),dateStr,NSLocalizedString(@"single_sign_on_Tips_two",nil)];
  453. NSString * loginAgainStr = NSLocalizedString(@"single_sign_on_login_again",nil);
  454. BOOL isOkBtnHighlight = YES;
  455. if(!ksharedAppDelegate.DeviceThirdIdMod.data.isPrivacyMode){
  456. loginAgainStr = @"";
  457. isOkBtnHighlight = NO;
  458. }
  459. KWeakSelf
  460. if(ksharedAppDelegate.isDidShowPwdType){
  461. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  462. [weakSelf LogoutByOtherFun:oaid];
  463. HLog(@"weakSelf LogoutByOtherFun")
  464. });
  465. return;
  466. }
  467. //被挤下线 停止拉流
  468. [self pauseStream];
  469. /*弹窗提示重启*/
  470. //KWeakSelf
  471. logoutAlertVC = [[ComontAlretViewController alloc] initWithTiTle:NSLocalizedString(@"single_sign_on_Tips_logout",nil)
  472. msg:LogoutTimerStr
  473. imageStr:@""
  474. cancelTitle:NSLocalizedString(@"single_sign_on_exit",nil)
  475. okTitle:loginAgainStr isOkBtnHighlight:isOkBtnHighlight
  476. didClickOk:^{
  477. self->logoutAlertVC = nil;
  478. [[NSNotificationCenter defaultCenter] postNotificationName:lockBypwdNotification object:nil];
  479. } didClickCancel:^{
  480. exit(0);/*强制退出app*/
  481. }];
  482. logoutAlertVC.modalPresentationStyle = UIModalPresentationCustom;
  483. [[iTools appRootViewController] presentViewController:logoutAlertVC animated:YES completion:^{
  484. self->logoutAlertVC.view.superview.backgroundColor = [UIColor clearColor];
  485. }];
  486. }
  487. #pragma mark 底部按钮事件
  488. - (void)didClickBottomFunBy:(NSInteger)tag
  489. {
  490. int keyType = 0;
  491. if(tag == 1){//task
  492. keyType = 187;
  493. }
  494. else if(tag == 2){//home
  495. keyType = 3;
  496. }
  497. else if(tag == 3){//back
  498. keyType = 4;
  499. }
  500. if(keyType > 0){
  501. [self didClickKeyEventFunBy:keyType];
  502. }
  503. }
  504. #pragma mark 按键事件
  505. // home 3 back 4 task 187 volumeUp 24 volumeDown 25
  506. - (void)didClickKeyEventFunBy:(int)keyType
  507. {
  508. [_mediaStream sendKey:keyType];
  509. }
  510. #pragma mark 云机交互的消息发送 走P2P通道
  511. -(void)send_data:(NSString*)commandStr
  512. {
  513. [[webRtcManager shareManager] send_data:commandStr];
  514. }
  515. #pragma mark 云机交互的消息发送 走音视频推拉流通道
  516. -(void)send_dataInPlayer:(NSString*)commandStr
  517. {
  518. [_mediaStream sendData:commandStr];
  519. }
  520. #pragma mark -- /*底部导航栏开关通知*/
  521. - (void)getPlayerBottomNavShowOrHidefun
  522. {
  523. BOOL haveShowBottonNavType = ![HWDataManager getBoolWithKey:Consn_player_Nav_hide];
  524. if(haveShowBottonNavType){
  525. _bottomContrView.hidden = NO;
  526. }
  527. else{
  528. _bottomContrView.hidden = YES;
  529. }
  530. }
  531. #pragma mark -- /*全面屏开关通知*/
  532. - (void)setPlayerFullScreenNotFun
  533. {
  534. BOOL fullscreenType = [HWDataManager getBoolWithKey:Consn_player_full_screen_show];
  535. CGFloat tempRate = 0.0;
  536. //重新设置分辨率
  537. if(fullscreenType){
  538. NSInteger cardDensity = 380;//480;//422;//380;//460;
  539. CGSize size = [RCCommandHelp commondToSetFullScreenPhoneSizeBySize];
  540. if(isLan){
  541. if(size.width < size.height){
  542. size = CGSizeMake(size.height,size.width);
  543. }
  544. }
  545. [self setCardSize:size.width cardHeight:size.height cardDensity:cardDensity];
  546. tempRate = (size.width *1.0)/(size.height *1.0);
  547. }
  548. else{
  549. CGSize size = CGSizeMake(1080.0, 1920.0);
  550. if(isLan){
  551. size = CGSizeMake(1920.0, 1080.0);
  552. }
  553. [self setCardSize:(NSInteger)size.width cardHeight:(NSInteger)size.height cardDensity:480];
  554. tempRate = size.width/size.height;
  555. }
  556. //dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  557. if (tempRate > 1) {/*横屏*/
  558. [self setLanMas_makeWithImageRate:tempRate];
  559. }else{/*竖屏*/
  560. [self setPoMas_makeWithImageRate:tempRate];
  561. }
  562. // });
  563. }
  564. #pragma mark -- /*推流中修改卡的分辨率*/
  565. - (void)setCardSize:(NSInteger)cardWidth
  566. cardHeight:(NSInteger)cardHeight
  567. cardDensity:(NSInteger)cardDensit
  568. {
  569. if(isLan){
  570. HLog(@"云机屏幕 设置 宽:%ld 高:%ld",cardHeight,cardWidth);
  571. [_mediaStream setCardSize:cardHeight cardHeight:cardWidth cardDensity:cardDensit];
  572. [_mediaStream setVideoSize:cardHeight videoHeight:cardWidth];
  573. }
  574. else{
  575. HLog(@"云机屏幕 设置 宽:%ld 高:%ld",cardWidth,cardHeight);
  576. [_mediaStream setCardSize:cardWidth cardHeight:cardHeight cardDensity:cardDensit];
  577. [_mediaStream setVideoSize:cardWidth videoHeight:cardHeight];
  578. }
  579. }
  580. #pragma mark -- /*通知添加与移除*/
  581. - (void)addKVOObserverFun
  582. {
  583. outputVolumeKVO = YES;
  584. [[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:(void *)[AVAudioSession sharedInstance]];
  585. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getPlayerBottomNavShowOrHidefun) name:getPlayerBottomNavNotification object:nil];
  586. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setPlayerFullScreenNotFun) name:setPlayerFullScreenNotification object:nil];
  587. //监听系统 前后台事件
  588. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
  589. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
  590. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
  591. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
  592. //输入密码完成
  593. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didInpuPwdOkFun) name:didInputPWDNotification object:nil];
  594. }
  595. - (void)removeKVOObserverFun
  596. {
  597. if (outputVolumeKVO)
  598. {
  599. [[AVAudioSession sharedInstance] removeObserver:self forKeyPath:@"outputVolume" context:(void *)[AVAudioSession sharedInstance]];
  600. outputVolumeKVO = NO;
  601. }
  602. [[NSNotificationCenter defaultCenter] removeObserver:self];
  603. }
  604. #pragma mark 系统音量键监听
  605. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
  606. if(context == (__bridge void *)[AVAudioSession sharedInstance])
  607. {
  608. /*音量开关打开时 允许发送指令 否则直接返回*/
  609. float newValue = [[change objectForKey:@"new"] floatValue];
  610. float oldValue = [[change objectForKey:@"old"] floatValue];
  611. //HLog(@"音量 --old: %f ---new: %f",oldValue,newValue)
  612. if (newValue > oldValue)
  613. {
  614. HLog(@"\n-----音量增加");
  615. [self didClickKeyEventFunBy:24];
  616. }
  617. else
  618. {
  619. HLog(@"\n-----音量降低");
  620. [self didClickKeyEventFunBy:25];
  621. }
  622. }
  623. }
  624. #pragma mark 监听到云机的宽高以及屏幕方向
  625. - (void)handlUIAfterGetCloudPhoneVideoWidth:(int)videoWidth videoHeight:(int)videoHeight rotation:(int)rotation
  626. {
  627. HLog(@"云机屏幕 回调 宽:%d 高:%d 横竖屏:%d",videoWidth,videoHeight,rotation);
  628. CGFloat curRate = (CGFloat)videoWidth/(CGFloat)videoHeight;
  629. if(lastVideoWHRate == curRate){
  630. return;
  631. }
  632. didAdjusBtnType = NO;
  633. if(rotation == 0){//竖屏
  634. //切换到竖屏
  635. isLan = NO;
  636. [self hx_rotateToInterfaceOrientation:UIInterfaceOrientationPortrait];
  637. [self setPoMas_makeWithImageRate:curRate];
  638. }
  639. else if(rotation == 1){//横屏
  640. //切换到横屏屏
  641. isLan = YES;
  642. [self hx_rotateToInterfaceOrientation:UIInterfaceOrientationLandscapeRight];
  643. [self setLanMas_makeWithImageRate:curRate];
  644. }
  645. _didHandleRotation = YES;
  646. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  647. [self extensionAdjustBtnFrameCheckAdjustTime];
  648. });
  649. }
  650. #pragma mark WebRTC 回调 MediaStreamClientEventsDelegate
  651. #pragma mark - 宽高变化
  652. -(void)onFrameResolutionChangedFromPeerName:(NSString*)peerName videoWidth:(int)videoWidth videoHeight:(int)videoHeight rotation:(int)rotation {
  653. HLog(@"推拉流 onFrameResolutionChangedFromPeerName:%@---%d---%d--%d",peerName,videoWidth,videoHeight,rotation)
  654. HLog(@"ok _mediaStream:%@",_mediaStream)
  655. mainBlock(^{
  656. [self handlUIAfterGetCloudPhoneVideoWidth:videoWidth videoHeight:videoHeight rotation:rotation];
  657. });
  658. }
  659. //code 0 成功 1失败
  660. -(void)onAuthResultFromPeerName:(NSString*)peerName code:(int)code descriptions:(NSString*)descriptions
  661. {
  662. HLog(@"onAuthResultFromPeerName:%@---%d---%@",peerName,code,descriptions)
  663. }
  664. #pragma mark 链接发生变化
  665. -(void)onChangeConnectionStateFromPeerName:(NSString*)peerName didChangeIceConnectionState:(RTCIceConnectionState)state
  666. {
  667. HLog(@"推拉流 onChangeConnectionStateFromPeerName: state:%ld",state)
  668. _linkState = state;
  669. switch (state) {
  670. case RTCIceConnectionStateConnected:{
  671. //链接成功
  672. mainBlock(^{
  673. [self removeNewIndicator];
  674. });
  675. }
  676. break;
  677. case RTCIceConnectionStateCompleted:
  678. //链接完成
  679. break;
  680. case RTCIceConnectionStateFailed:
  681. case RTCIceConnectionStateDisconnected:
  682. case RTCIceConnectionStateClosed:
  683. //链接关闭
  684. [self relinkWebRtcFun];
  685. break;
  686. default:
  687. break;
  688. }
  689. }
  690. - (void)dataChannelDidChangeFromPeerName:(NSString*)peerName State:(RTCDataChannelState)state;
  691. {
  692. HLog(@"推拉流 dataChannelDidChangeFromPeerName: state:%ld",state)
  693. switch (state) {
  694. case RTCDataChannelStateConnecting:
  695. {
  696. }
  697. break;
  698. case RTCDataChannelStateOpen:
  699. {
  700. //链接成功
  701. [self offlineOtherPhoneFun];
  702. }
  703. break;
  704. case RTCDataChannelStateClosing:
  705. {
  706. }
  707. break;
  708. case RTCDataChannelStateClosed:
  709. {
  710. //链接断开
  711. [self relinkWebRtcFun];
  712. }
  713. break;
  714. default:
  715. break;
  716. }
  717. }
  718. -(void)onChannelDataFromPeerName:(NSString*)peerName buffer:(RTC_OBJC_TYPE(RTCDataBuffer) *)buffer
  719. {
  720. //HLog(@"onIceConnectedFromPeerName:%@",buffer.data);
  721. if(buffer && buffer.data){
  722. KWeakSelf
  723. mainBlock(^{
  724. [weakSelf handleWebRtcMsgResponseBy:buffer.data];
  725. });
  726. }
  727. }
  728. -(void)didGetStats:(NSString*)peerName stats:(RTC_OBJC_TYPE(RTCStatisticsReport) *)stats {
  729. if(!_needToReportWebRtcType){
  730. [[webRtcManager shareManager] reportWebRtcRePoportTypeIsChannel:NO withStats:stats];
  731. _needToReportWebRtcType = YES;
  732. }
  733. NSString *selectedCandidatePairId = nil;
  734. NSString *localCandidateId = nil;
  735. NSString *remoteCandidateId = nil;
  736. /*延时数据*/
  737. NSNumber *currentRoundTripTime = nil;
  738. //线性增长接收包数
  739. long packetsReceived = 0;
  740. //视频丢包数据
  741. long videolostData = 0;
  742. //音频丢包数据
  743. long audiolostData = 0;
  744. //总丢包数据
  745. long alllostData = 0;
  746. //每秒帧数 ----界面展示的帧率
  747. NSInteger framesPerSecond = 0;
  748. //计算传输速度
  749. long preReceive = 0;
  750. KWeakSelf
  751. for (NSString *key in [stats.statistics allKeys]) {
  752. RTCStatistics *rtcStatistics = [stats.statistics objectForKey:key];
  753. //HLog(@"hxd11111---->%@",rtcStatistics.type);
  754. if ([rtcStatistics.type isEqualToString:@"transport"]) {
  755. //HLog(@"传输数据---->%@",rtcStatistics.values);
  756. double timestamp = rtcStatistics.timestamp_us;
  757. NSNumber *bytesReceived = [rtcStatistics.values objectForKey:@"bytesReceived"];
  758. NSNumber *packetsReceivedNumber = [rtcStatistics.values objectForKey:@"packetsReceived"];
  759. packetsReceived = [packetsReceivedNumber longValue];
  760. if (lastTimestamp > 0) {
  761. long diffReceive = [bytesReceived longValue] - [lastBytesReceived longValue];
  762. double diffTime = timestamp - lastTimestamp;
  763. preReceive = (diffReceive / diffTime) * 1000000;
  764. //HLog(@"传输数据速度---->%ld",preReceive);
  765. // mainBlock((^{
  766. // if (self->mPlayerView.upControlView.hidden == NO){
  767. // NSString *str = [NSString stringWithFormat:@"清晰度 %ldk/s",preReceive/1024];
  768. // NSMutableAttributedString *underAttr = [[NSMutableAttributedString alloc] initWithString:str attributes:@{NSForegroundColorAttributeName:[UIColor hwColor:@"#FFFFFF"]}];
  769. // [underAttr addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12]} range:NSMakeRange(0, str.length - 2)];
  770. // [underAttr addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:10]} range:NSMakeRange(str.length - 2,2)];
  771. // [self->mPlayerView.upControlView.articulationBtn setAttributedTitle:underAttr forState:(UIControlStateNormal)];
  772. // }else{
  773. // NSString *str = [NSString stringWithFormat:@"%ldk/s",preReceive/1024];
  774. // NSMutableAttributedString *underAttr = [[NSMutableAttributedString alloc] initWithString:str attributes:@{NSForegroundColorAttributeName:[UIColor hwColor:@"#FFFFFF"]}];
  775. // [underAttr addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12]} range:NSMakeRange(0, str.length - 2)];
  776. // [underAttr addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:10]} range:NSMakeRange(str.length - 2,2)];
  777. // [self->mPlayerView.controlBtn setAttributedTitle:underAttr forState:(UIControlStateNormal)];
  778. // }
  779. // }));
  780. }else{
  781. lastTimestamp = timestamp;
  782. lastBytesReceived = bytesReceived;
  783. }
  784. selectedCandidatePairId = [rtcStatistics.values objectForKey:@"selectedCandidatePairId"];
  785. //HLog(@"三网数据--selectedCandidatePairId-->%@",selectedCandidatePairId);
  786. }
  787. /*丢包数据*/
  788. if ([rtcStatistics.type isEqualToString:@"inbound-rtp"]) {
  789. NSString *kind = [rtcStatistics.values objectForKey:@"kind"];
  790. if([kind isEqualToString:@"video"]){
  791. NSNumber*videolostDataNumber = [rtcStatistics.values objectForKey:@"packetsLost"];
  792. videolostData = [videolostDataNumber longValue];
  793. NSNumber*framesPerSecondNumber = [rtcStatistics.values objectForKey:@"framesPerSecond"];
  794. framesPerSecond = [framesPerSecondNumber integerValue];
  795. }
  796. else if([kind isEqualToString:@"audio"]){
  797. NSNumber*audiolostDataNumber = [rtcStatistics.values objectForKey:@"packetsLost"];
  798. audiolostData = [audiolostDataNumber longValue];
  799. }
  800. }
  801. for (NSString *keyin in [rtcStatistics.values allKeys]) {
  802. if ([keyin isEqualToString:@"currentRoundTripTime"]){
  803. /*延时数据*/
  804. currentRoundTripTime = [rtcStatistics.values objectForKey:@"currentRoundTripTime"];
  805. //[self updateAutoRateAndNetWorkStatesWithDelatyMS:(NSInteger)currentRoundTripTime.floatValue*1000];
  806. break;
  807. }
  808. }
  809. }
  810. //netWorkInfoLabel 网络信息 测试用
  811. if (selectedCandidatePairId) {
  812. for (NSString *key in [stats.statistics allKeys]) {
  813. RTCStatistics *rtcStatistics = [stats.statistics objectForKey:key];
  814. if ([rtcStatistics.type isEqualToString:@"candidate-pair"]){
  815. NSString *tempselectedCandidatePairId = rtcStatistics.id;
  816. if ([tempselectedCandidatePairId isEqualToString:selectedCandidatePairId]) {
  817. localCandidateId = [rtcStatistics.values objectForKey:@"localCandidateId"];
  818. remoteCandidateId = [rtcStatistics.values objectForKey:@"remoteCandidateId"];
  819. // HLog(@"三网数据--localCandidateId-->%@",localCandidateId);
  820. // HLog(@"三网数据--remoteCandidateId-->%@",remoteCandidateId);
  821. }
  822. }
  823. }
  824. }
  825. NSString *remoteCandidateStr = nil;
  826. NSString *localCandidateStr = nil;
  827. if (localCandidateId && remoteCandidateId) {
  828. for (NSString *key in [stats.statistics allKeys]) {
  829. RTCStatistics *rtcStatistics = [stats.statistics objectForKey:key];
  830. if ([rtcStatistics.type isEqualToString:@"local-candidate"]){
  831. NSString *templocalCandidateId = rtcStatistics.id;
  832. if ([templocalCandidateId isEqualToString:localCandidateId]) {
  833. //HLog(@"三网数据--localCandidateIdInfo-->%@",rtcStatistics.values);
  834. localCandidateStr = @"本地\n";
  835. NSString *candidateType = [rtcStatistics.values objectForKey:@"candidateType"];
  836. if (candidateType) {
  837. localCandidateStr = [localCandidateStr stringByAppendingString:[NSString stringWithFormat:@"candidateType:%@",candidateType]];
  838. localCandidateStr = [localCandidateStr stringByAppendingString:@"\n"];
  839. }
  840. NSString *address = [rtcStatistics.values objectForKey:@"address"];
  841. if (address) {
  842. localCandidateStr = [localCandidateStr stringByAppendingString:[NSString stringWithFormat:@"address:%@",address]];
  843. localCandidateStr = [localCandidateStr stringByAppendingString:@"\n"];
  844. }
  845. NSString *ip = [rtcStatistics.values objectForKey:@"ip"];
  846. if (ip) {
  847. localCandidateStr = [localCandidateStr stringByAppendingString:[NSString stringWithFormat:@"ip:%@",ip]];
  848. localCandidateStr = [localCandidateStr stringByAppendingString:@"\n"];
  849. }
  850. NSString *relatedAddress = [rtcStatistics.values objectForKey:@"relatedAddress"];
  851. if (relatedAddress) {
  852. localCandidateStr = [localCandidateStr stringByAppendingString:[NSString stringWithFormat:@"relatedAddress:%@",relatedAddress]];
  853. localCandidateStr = [localCandidateStr stringByAppendingString:@"\n"];
  854. }
  855. }
  856. }else if ([rtcStatistics.type isEqualToString:@"remote-candidate"]){
  857. NSString *tempRemoteCandidateId = rtcStatistics.id;
  858. if ([tempRemoteCandidateId isEqualToString:remoteCandidateId]) {
  859. //HLog(@"三网数据--remoteCandidateIdInfo-->%@",rtcStatistics.values);
  860. remoteCandidateStr = @"远端\n";
  861. NSString *candidateType = [rtcStatistics.values objectForKey:@"candidateType"];
  862. if (candidateType) {
  863. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:[NSString stringWithFormat:@"candidateType:%@",candidateType]];
  864. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:@"\n"];
  865. }
  866. NSString *address = [rtcStatistics.values objectForKey:@"address"];
  867. if (address) {
  868. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:[NSString stringWithFormat:@"address:%@",address]];
  869. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:@"\n"];
  870. }
  871. NSString *ip = [rtcStatistics.values objectForKey:@"ip"];
  872. if (ip) {
  873. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:[NSString stringWithFormat:@"ip:%@",ip]];
  874. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:@"\n"];
  875. }
  876. NSString *relatedAddress = [rtcStatistics.values objectForKey:@"relatedAddress"];
  877. if (relatedAddress) {
  878. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:[NSString stringWithFormat:@"relatedAddress:%@",relatedAddress]];
  879. remoteCandidateStr = [remoteCandidateStr stringByAppendingString:@"\n"];
  880. }
  881. }
  882. }
  883. }
  884. }
  885. NSString *showStr = @"";
  886. if (localCandidateStr) {
  887. showStr = [showStr stringByAppendingString:localCandidateStr];
  888. }
  889. if (remoteCandidateStr) {
  890. showStr = [showStr stringByAppendingString:remoteCandidateStr];
  891. }
  892. //网络延迟, 丢包率,FPS,网速 分辨率 流量
  893. //延时数据
  894. NSString*currentRoundTripTimeStr = [[NSString alloc] initWithFormat:@"延时:%ldms\n",(NSInteger)(currentRoundTripTime.floatValue*1000)];
  895. showStr = [showStr stringByAppendingString:currentRoundTripTimeStr];
  896. //计算上次报道到这一次的丢包率---------界面展示百分比丢包率
  897. long allPacketsReceived = packetsReceived - lasPacketsReceived;
  898. alllostData = audiolostData + videolostData;
  899. NSInteger lostRate = ((alllostData - lastAlllostData) *1.0 / (allPacketsReceived + (alllostData - lastAlllostData))) *100;
  900. //记录上一次丢包数
  901. lastAlllostData = alllostData;
  902. //记录上一次接收包数
  903. lasPacketsReceived = packetsReceived;
  904. NSString*lostDataStr = [[NSString alloc] initWithFormat:@"丢包率:(%ld/%ld) %ld%%\n",alllostData - lastAlllostData,allPacketsReceived + alllostData - lastAlllostData,lostRate];
  905. showStr = [showStr stringByAppendingString:lostDataStr];
  906. //FPS
  907. NSString*FPSStr = [[NSString alloc] initWithFormat:@"FPS:%ld\n",framesPerSecond];
  908. showStr = [showStr stringByAppendingString:FPSStr];
  909. //网速 传输数据速度
  910. NSString *netDataSpeedStr = [NSString stringWithFormat:@"传输数据速度:%ldk/s\n",preReceive/1024];
  911. showStr = [showStr stringByAppendingString:netDataSpeedStr];
  912. mainBlock(^{
  913. [self->netWorkInfoLabel setText:showStr];
  914. });
  915. }
  916. #pragma mark 收到的webrtc消息处理
  917. - (void)handleWebRtcMsgResponseBy:(NSData*)message
  918. {
  919. if([message isKindOfClass:[NSMutableString class]] || [message isKindOfClass:[NSString class]])
  920. {
  921. message = [(NSString *)message dataUsingEncoding:(NSUTF8StringEncoding)];
  922. }
  923. NSError *error = nil;
  924. NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:message options:NSJSONReadingMutableContainers error:&error];
  925. HLog(@"webRtc 音视频推拉流 通道接收消息:------------------%@",dataDict);
  926. if(!dataDict){
  927. //[weakSelf handleDownloadResponseFunBy:message];
  928. return;
  929. }
  930. if(![dataDict isKindOfClass:[NSDictionary class]]){
  931. //[__NSCFString allKeys] unrecognized selector sent to ins
  932. return;
  933. }
  934. if(![[dataDict allKeys] containsObject:@"type"]){
  935. return;
  936. }
  937. NSString *messageType = dataDict[@"type"];
  938. if ([messageType isEqualToString:@"login"]) {
  939. if([[dataDict allKeys] containsObject:@"value"]){
  940. NSString *value = dataDict[@"value"];
  941. [self LogoutByOtherFun:value];
  942. }
  943. }
  944. }
  945. @end