webRtcPlayerViewController.m 42 KB

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