webRtcPlayerViewController.m 43 KB

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