//
//  ViewController.m
//  VideoTest
//
//  Created by APPLE on 2019/5/29.
//  Copyright © 2019 APPLE. All rights reserved.
//

#import "PlayerViewController.h"
#import "PlayerViewController+TouchPointXD.h"
#import "PlayerViewController+AdjustBtnFrame.h"
#import "PlayerViewController+AppDelegate.h"
#import "PlayerViewController+otherDelegate.h"

#import "AFNetworkReachabilityManager.h"
#import <AVFoundation/AVFoundation.h>

#import <ifaddrs.h>
#import <arpa/inet.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import <SDWebImage.h>
#import "FLAnimatedImage.h"

#import<objc/runtime.h>

#import "BGTool.h"

#import "AppDelegate.h"

#import <RCCloudPhoneSDK/RCAudioPlayer.h>
#import <RCCloudPhoneSDK/RCRecordManager.h>
//#import <RCCloudPhoneSDK/RCCommandChannel.h>
#import <RCCloudPhoneSDK/RCLiveSteamManager.h>
#import "ShortcutManager.h"
#import "RCCommandHelp.h"
#import "UIView+View.h"
#import "SafeForKey.h"
#import "CloudPhoneAPI.h"

#import "MySetViewController.h"
#import "PhoneTimeInfoModel.h"
#import "connectDeviceManager.h"
#import "ComontAlretViewController.h"


typedef enum : NSUInteger {
    BITRATE_EXTREME_SPEED = 2,//极速
    //    BITRATE_HIGH_SPEED = 843000,//高速
    BITRATE_AUTO = 6,//自动
//    BITRATE_STANDARD_CLEARING = 2,//wwan标清
//    BITRATE_HD = 3,//wwan高清
    BITRATE_WIFI_STANDARD_CLEARING = 3, //wifi标清
    BITRATE_WIFI_HD = 4, //wifi高清
} BITRATE_TYPE;

//当手机采用wifi时不做码率调整，当手机采用流量时，高清采用2052000，标清采用1652000调整（默认）
///*测试*/
//#include "socket.h"


CGFloat w_h_rate;

PlayerViewController * _Nullable mySelf;

BOOL isLan;

//PlayerViewController *mySelf;

int portConnect;
NSString *ipConnect;

@interface PlayerViewController ()
<PlayerViewDelegate,
RecoderManagerDelegate,
AudioRecoderMamagerDelegate,
RCLiveSteamManagerDelegate,
UITextFieldDelegate,
ComontAlretViewControllerDelegate>
{
//    __block int _ihandle;
    
    int rate;/*0:极速  1:高速  2:高清  3:标清  4:d自动*/
    NSUInteger rateForAuto;
    
    
    BOOL showWattingViewImageView;
    
    RCPCMPlayer *pcmPlayer;
    
    NSInteger gpsOnOff;
    
    BOOL canRate;
    
    CIContext *videoContext;
    
    NSInteger reConnectAccount;/*记录重连次数*/
    
    BOOL isInPan;/*标记是否有手指在活动*/
    
    int socketFortest;
        
    UIView *loadingWithTipsView;
    
    NSInteger netWorkStates;/*0很差 1较差 2流畅*/
    
    
    BOOL outputVolumeKVO;/*标记声音监听通知*/
    
    NSDate *rootSetTime;
    
    UITextField *hidenTextField;
    NSString *hidenTextFieldOldStr;
    
    PhoneTimeInfoDataModel *phoneTimeInfoDataModel;
    
    /*弹窗提示重启*/
    ComontAlretViewController *logoutAlertVC;
    /*弹窗提示链接失败 网络或者云机*/
    ComontAlretViewController *linkFailAlretVC;
    
    NSTimer *forceStartTimer;//请知重启timer
}
@property (nonatomic, strong, nullable) RCVideoRecoderManager *recoderManager;
@property (nonatomic, strong, nullable) RCAudioRecoderMamager *audioRecoderMamager;

@property (nonatomic, strong) RCLiveSteamManager *liveStreamManager;
//@property (nonatomic, strong) RCCommandChannelManager *commandChannelManager;//指令通道
//@property (nonatomic, strong) RCCommandChannelManager *businessCommandChannelManager;//业务通道

//需不需要显示音量条
@property (nonatomic, assign) BOOL isNeedShowVoiceBar;

//切换云手机 保存切换过的云手机数组， 返回的时刷新对应的云机websorket封面
@property (nonatomic, strong) NSMutableArray *switchCloudPhoneArray;

@property (nonatomic, copy)   NSString           *screenShotFileName;

@property (nonatomic, copy)   NSTimer            *timer; // 定时器-控制按钮
/**30s后 渲染时间戳无更新 自动断开链接*/
@property (nonatomic, assign) NSInteger          concentTime; // 拉流数据 渲染更新时间戳
/**定时器计数*/
@property (nonatomic, assign) NSInteger          currentTime;

/**是否是收入进入云手机*/
@property (nonatomic, assign) BOOL          isFirstEnterPhone;

@property (nonatomic, strong)   NSTimer            *checkThridConnectTimer; // 检查瑞云那边连接完成没
@property (nonatomic, assign) NSInteger          checkThridConnectNum;//

//音频和图片是否可以刷新
@property (nonatomic, assign) BOOL canShowImgAndVoiceType;

@property (nonatomic, copy)   NSString*LogoutTimerStr;//单点登出时间
@property (nonatomic, assign) BOOL needShowLogoutDelayType;//是否是延时显示单点登出
@property (nonatomic, assign) BOOL isRebootIngType;//是否为重启中
@property (nonatomic, assign) BOOL isResetingType;//是否为恢复出厂中
@end

@implementation PlayerViewController
@synthesize internetVideoPort;
@synthesize ip;
@synthesize canControl;
@synthesize deviceId;
@synthesize vpnStatus;
@synthesize internetHttp;
@synthesize rbdNotification;

- (void)viewDidLoad {
    
    [super viewDidLoad];
    if (@available(iOS 11.0, *)) {  // 兼容低版本ios
        [self setNeedsUpdateOfHomeIndicatorAutoHidden];
    }
    canControl = YES;
    _canShowImgAndVoiceType = NO;
    //[self opencommandChannelManagerrc_openURL];
    //[self openbusinessCommandChannelManagerrc_openURL];

    portConnect = [self->internetVideoPort intValue];
    ipConnect   = self->ip;
    
    isLan = NO;
    
    globalBlock(^{
        // 初始化成功后连接
        @synchronized (self) {
            if ([self initVideoServer])
            {
                [self connectVideoServer];
            }
        }
    });
    outputVolumeKVO = NO;
    
    rbdNotification = 0;
    
    // 初始化
    self.isNeedRecyclResource = YES;
    self.isFirstEnterPhone = YES;

    [self initData];
    
    self.toolBar.hidden = YES;
    self.navigationBar.hidden = YES;
    
    [self drawView];
    
    [self showNewIndicator];
    
    mySelf   = self;
    haveBack = NO;
    
    [self   startCheckThridRuiYunTimerFun];
}

#pragma mark 启动检测瑞云的timer
 - (void)startCheckThridRuiYunTimerFun
{
    if(_checkThridConnectTimer ){
        [_checkThridConnectTimer invalidate];
    }
    
    _checkThridConnectNum = 0;
    
    _checkThridConnectTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkThridRuiYunFun) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_checkThridConnectTimer forMode:NSRunLoopCommonModes];
}

#pragma mark 检测融云链接是否完成
- (void)checkThridRuiYunFun{
    
    _checkThridConnectNum += 1;
    
    if(_checkThridConnectNum == 30 && [[connectDeviceManager shareInstance] curConnectDeviceState] <= 3 ){
        [self showNetErrorAlertFun:11];
        
//        [_checkThridConnectTimer invalidate];
//        return;
    }
    
    //HLog(@"局域网是否能ping通:%d",[connectDeviceManager shareInstance].DeviceThirdIdMod.data.isPingOk);
    HLog(@"瑞云连接状态:%d",[[connectDeviceManager shareInstance] curConnectDeviceState]);
    
    //第一次进 先输入密码才能连接
    if([connectDeviceManager shareInstance].isFirstInputPwdDone){
        if([connectDeviceManager shareInstance].DeviceThirdIdMod.data.isPingOk){
            ip = [connectDeviceManager shareInstance].DeviceThirdIdMod.data.ip;
            internetVideoPort = @"9100";
            [self didCanConnectServerFun];
        }
        else{
            if([[connectDeviceManager shareInstance] curConnectDeviceState] == DeviceConnectDeciceOk){
                ip = @"127.0.0.1";
                internetVideoPort = [[connectDeviceManager shareInstance] tcpPortStr];
                [self didCanConnectServerFun];
            }
        }
    }
    
    
}

#pragma mark 走局域网或者瑞云SDK链接OK
- (void)didCanConnectServerFun{
    [_checkThridConnectTimer invalidate];
    
    //做版本检测
    [self checkVersionFun];
    
    [self connectVideoServer];
    [self opencommandChannelManagerrc_openURL];
    
//    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerChange) userInfo:nil repeats:YES];
//    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}

- (void)initData
{
    isInPan = NO;
    reConnectAccount = 0;
    netWorkStates = 0;
    
    canRate = NO;
    rate = -1;
    isLan = NO;
    
//    _ihandle = -1;
    [hidenTextField resignFirstResponder];
    hidenTextField.text = @"";
    hidenTextFieldOldStr = nil;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // 屏幕常亮
    [UIApplication sharedApplication].idleTimerDisabled = YES;
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    
    [self setTimerCountDown];
    
    [self setShowImgAndVoiceTypeFun:YES];
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    
    if (mPlayerView.controlBtn) {
        [self.navigationController.view bringSubviewToFront:mPlayerView.controlBtn];
    }
}

- (void)viewWillDisappear:(BOOL)animated {
    // 退出控制器 回收资源
    [self recyclResource];
    AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
//    app.allowAutoRotate = NO;
    
    [super viewWillDisappear:animated];
    
    [self setShowImgAndVoiceTypeFun:NO];
}
 
// 退出控制器 回收资源
- (void)recyclResource {
    
    // 移除Alert
    if (self.presentedViewController) {
        [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
    }
    [mPlayerView.controlBtn removeFromSuperview];
    if ([[[UIApplication sharedApplication] keyWindow] viewWithTag:1235]) {
        [[[[UIApplication sharedApplication] keyWindow] viewWithTag:1235] removeFromSuperview];
    }
    
    // 销毁定时器
    [self cancelTimer];
    
    [self enablePanRightBack];
    
    // 播放器内部页面跳转-不能回收的资源
    if (self.isNeedRecyclResource) {
        // 屏幕常亮
        [UIApplication sharedApplication].idleTimerDisabled = NO;
        [[UIApplication sharedApplication] setStatusBarHidden:NO];
        
        if (USEAAC)
        {
            if (aacPlayer)
            {
                [aacPlayer stop];
           
                aacPlayer = nil;
            }
        }
        else
        {
            if (pcmPlayer)
            {
                [pcmPlayer stop];

                pcmPlayer = nil;
            }
        }
        
        [self toStopRecoder];
        [self toStopAudioRecoder];

        [self removeNSNotification];
        
        //清空WebSocket连接
        [self.commandChannelManager rc_close];
        [self.businessCommandChannelManager rc_close];
        
        globalBlock(^{
            [self.liveStreamManager rc_release];
        });
    }
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
//    app.allowAutoRotate = YES;
    
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    
    [self noEnablePanRightBack];
    
    [self.navigationController.view addSubview:mPlayerView.controlBtn];
    [self.navigationController.view bringSubviewToFront:mPlayerView.controlBtn];
    
        if (self.isNeedRecyclResource) {
            self.liveStreamManager = [[RCLiveSteamManager alloc] init];
            self.liveStreamManager.delegate = self;
            
            //[self opencommandChannelManagerrc_openURL];
            //[self openbusinessCommandChannelManagerrc_openURL];

            portConnect = [internetVideoPort intValue];
            ipConnect   = ip;
            
            isLan = NO;
            
            globalBlock(^{
                // 初始化成功后连接
                @synchronized (self) {
                    if ([self initVideoServer])
                    {
                        [self connectVideoServer];
                    }
                }
            });

            [self addNSNotification];
        }
        
        self.isNeedRecyclResource = YES;
}

- (void)opencommandChannelManagerrc_openURL
{
    
    if(self.commandChannelManager){
        [self.commandChannelManager rc_close];
        
        self.commandChannelManager = nil;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self opencommandChannelManagerrc_openURL];
        });
        
        return;
    }
    
    KWeakSelf
    //初始化指令通道
    self.commandChannelManager = [[RCCommandChannelManager alloc] init];
    NSString *instructionsChannelUrl = [NSString stringWithFormat:@"ws://%@:%@/businessChannel",ip,internetVideoPort];
    
    if([connectDeviceManager shareInstance].DeviceThirdIdMod.data.isPingOk){
        instructionsChannelUrl = [NSString stringWithFormat:@"ws://%@:%@/businessChannel",ip,@"9300"];
    }
    
    if (instructionsChannelUrl && instructionsChannelUrl.length > 0) { //当都有值才可连接
        HLog(@"WebSocket11111指令通道连接开始11111 url = %@ ",instructionsChannelUrl);
        [self.commandChannelManager rc_openURL:instructionsChannelUrl connected:^{
            HLog(@"WebSocket11111指令通道连接成功11111 url = %@ ",instructionsChannelUrl);
            if (weakSelf.commandChannelManager.rc_socketStatus == RCSocketCloudPhoneStatusConnected){
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    [weakSelf handlAllMsgAfterDidLinkFun];
                    
                    //设置分辨率
//                    NSString *commondStr  = @"{\"data\":{\"height\":1920,\"width\":1080,\"dpi\":480},\"type\":\"setPhoneSize\"}";
//                    [weakSelf send_data:commondStr];
                    
                    
//                    /*获取自己的用户名(电话号码)*/
//                    NSString *selfUseName = nil;
//                    NSDictionary *dict111 = [[UseAccountManage shareInstance] getLoginInfo];
//                    if ([[dict111 allKeys] containsObject:@"userName"]) {
//                        selfUseName = [dict111 valueForKey:@"userName"];
//                        /*查询是否有设备在远程控制*/
//                        [self.commandChannelManager rc_sendData:[RCCommandHelp askControllcommandWithUseName:selfUseName]];
//                    }
                    
//                    if (USELOCALKEYBOARD){
//                        /*开启输入法透传*/
//                        NSString *dataStr = [RCCommandHelp commandOpenLoaclKeyboad];
//                        [self.commandChannelManager rc_sendData:dataStr];
//                    }else{
//                        /*关闭输入法透传*/
//                        NSString *dataStr = [RCCommandHelp commandCloseLoaclKeyboad];
//                        [self.commandChannelManager rc_sendData:dataStr];
//                    }
                });
            }
        } receive:^(id message, FLSocketCloudPhoneReceiveType type) {
            
            if([message isKindOfClass:[NSData class]] && [message length] == 0){
                return;
            }
            
            HLog(@"webSocket指令通道接收消息:------------------\n%@",message);
            
            if([message isKindOfClass:[NSMutableString class]] || [message isKindOfClass:[NSString class]])
            {
                message = [(NSString *)message dataUsingEncoding:(NSUTF8StringEncoding)];
            }
            
            NSError *error = nil;
            NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:message options:NSJSONReadingMutableContainers error:&error];
            
            if(!dataDict){
                return;
            }
            
            if(![dataDict isKindOfClass:[NSDictionary class]]){
                //[__NSCFString allKeys] unrecognized selector sent to ins
                return;
            }
            
            NSString *messageType = dataDict[@"type"];
            
            if ([messageType isEqualToString:@"cutting"]) {
                //[[iToast makeText:@"复制成功"] show];
            }
            else if ([messageType isEqualToString:@"forwardMsg"]){/*转发*/
                /*获取指令类型*/
                NSString *code = nil;
                if ([[dataDict allKeys] containsObject:@"data"]) {
                    NSDictionary *data = dataDict[@"data"];
                    
                     if([data isKindOfClass:[NSString class]]){
                        NSString * dataStr = (NSString*)data;
                        if([dataStr isEqualToString:@"offline_notification"]){
                            HLog(@"被别人挤下线了");
                            [self LogoutByOtherFun];
                        }
                         
                         return;
                    }
                    else if ([data isKindOfClass:[NSDictionary class]] && [[data allKeys] containsObject:@"code"]) {
                        code = [data objectForKey:@"code"];
                        
                        if (![code isKindOfClass:[NSString class]]) {
                            code = [NSString stringWithFormat:@"%ld",[code integerValue]];
                        }
                    }
                }
                
                /*获取用户名*/
                NSString *useName = nil;
                if ([[dataDict allKeys] containsObject:@"data"]) {
                    NSDictionary *data = dataDict[@"data"];
                    if ([[data allKeys] containsObject:@"userName"]) {
                        useName = [data objectForKey:@"userName"];
                    }
                }
                
                
                /*无控制权提示*/
                //- (void)tipsNoDeviceContrWithPhoneIndex:(NSInteger)phoneIndex
                /*提醒拿回控制权*/
                //- (void)tipsGetBackDeviceContrWithPhoneIndex:(NSInteger)phoneIndex
                /*提醒控制权被拿回*/
                //- (void)tipsMainUserGetDeviceAuthBack
                
//                if ([code isEqualToString:@"3000"]) {/*有人询问控制权情况*/
//                    if (self->deviceModel.authPhone==0 && self->deviceModel.phoneAuthStatus == 0){
//                        return;/*自己的云手机且未授权直接返回*/
//                    }
//                    
//                    if (![useName isEqualToString:selfUseName]){
//                        /*根据实际情况进行相关回复*/
//                        [self.commandChannelManager rc_sendData:[RCCommandHelp faceBackControllcommandWithUseName:selfUseName haveControl:self->canControl]];
//                    }
//                }else if ([code isEqualToString:@"4000"]){/*有在控制*/
//                    if (self->deviceModel.authPhone==0 && self->deviceModel.phoneAuthStatus == 0){
//                        return;/*自己的云手机且未授权直接返回*/
//                    }
//                    
//                    if (self->deviceModel.authPhone==0) {/*是自己的设备时候要询问是否夺回控制权*/
//                        if (![useName isEqualToString:selfUseName]) {
//                            /*弹窗询问是否夺回控制权*/
//                            [self tipsGetBackDeviceContrWithPhoneIndex:self->deviceModel];
//                        }
//                    }else if (![useName isEqualToString:selfUseName]) {
//                        if (self->canControl == YES) {
//                            [self tipsNoDeviceContrWithPhoneIndex:self->deviceModel];
//                        }
//                        self->canControl = NO;
//                        if (!self->canControl&&self->controlView){
//                            [self->controlView diasbleControltPhoneView];
//                        }else if (self->controlView){
//                            [self->controlView enableControltPhoneView];
//                        }
//                    }
//                }else if ([code isEqualToString:@"4100"]){/*未控制*/
//                    /*不用处理默认可以控制*/
//                }else if ([code isEqualToString:@"5000"]){/*夺回控制权*/
//                    if (self->deviceModel.authPhone==0 && self->deviceModel.phoneAuthStatus == 0){
//                        return;/*自己的云手机且未授权直接返回*/
//                    }
//                    
//                    if ([useName isEqualToString:selfUseName]){
//                        return;
//                    }
//                    
//                    if (self->deviceModel.authPhone!=0) {/*不是自己的设备时候要进行关闭控制权*/
//                        if (self->canControl == YES) {
//                            /*弹窗提示控制权已经被夺回*/
//                            [self tipsMainUserGetDeviceAuthBack];
//                        }
//                        self->canControl = NO;
//                        if (!self->canControl&&self->controlView){
//                            [self->controlView diasbleControltPhoneView];
//                        }else if (self->controlView){
//                            [self->controlView enableControltPhoneView];
//                        }
//                    }
//                }else
                    if ([code isEqualToString:@"phoneSizeChange"]){/*分辨率改变*/
                    if ([[dataDict allKeys] containsObject:@"data"]) {
                        NSDictionary *data = dataDict[@"data"];
                        if ([[data allKeys] containsObject:@"width"]) {
                            ksharedAppDelegate.couldPhone_W_PHONE = [[data objectForKey:@"width"] integerValue];
                        }
                        if ([[data allKeys] containsObject:@"height"]) {
                            ksharedAppDelegate.couldPhone_H_PHONE = [[data objectForKey:@"height"] integerValue];
                        }
                        
                        if (ksharedAppDelegate.couldPhone_W_PHONE > ksharedAppDelegate.couldPhone_H_PHONE) {
                            CGFloat temp = ksharedAppDelegate.couldPhone_W_PHONE;
                            ksharedAppDelegate.couldPhone_W_PHONE = ksharedAppDelegate.couldPhone_H_PHONE;
                            ksharedAppDelegate.couldPhone_H_PHONE = temp;
                        }
                    }
                }
            }
            else if ([messageType isEqualToString:@"getPhoneSize"] || [messageType isEqualToString:@"setPhoneSize"]){
                NSString *sn = nil;
                if ([[dataDict allKeys] containsObject:@"data"]) {
                    NSDictionary *data = dataDict[@"data"];
                    
                    if ([[data allKeys] containsObject:@"status"]) {
                        NSInteger  status = [[data objectForKey:@"status"] integerValue];
                        
                        if (status == 0) {/*不是当前设备直接返回*/
                            if ([[data allKeys] containsObject:@"width"]) {
                                ksharedAppDelegate.couldPhone_W_PHONE = [[data objectForKey:@"width"] integerValue];
                            }
                            if ([[data allKeys] containsObject:@"height"]) {
                                ksharedAppDelegate.couldPhone_H_PHONE = [[data objectForKey:@"height"] integerValue];
                            }
                            
                            if (ksharedAppDelegate.couldPhone_W_PHONE > ksharedAppDelegate.couldPhone_H_PHONE) {
                                CGFloat temp = ksharedAppDelegate.couldPhone_W_PHONE;
                                ksharedAppDelegate.couldPhone_W_PHONE = ksharedAppDelegate.couldPhone_H_PHONE;
                                ksharedAppDelegate.couldPhone_H_PHONE = temp;
                            }
                        }
                    }
                }
                

                
//                {
//                  "type":"getPhoneSize",    --接口类型
//                  "data":{
//                      "sn":"RK_XXX",       --安卓卡SN
//                      "status":"0",        --状态：0：成功 1：失败
//                      "msg":"success",     --请求状态：success 成功 failed 失败
//                      "width":xxx,
//                      "height":xxx,
//                      "dpi":yyy  --屏幕密度
//                  }
//                }
            }
            else if ([messageType isEqualToString:@"sync_wifi"]){
                [self.commandChannelManager rc_sendData:[RCCommandHelp noSyncWifiBack]];
                //[[iToast makeText:@"本机参数已同步完成，IOS无法同步wifi"] show];
            }
            else if ([messageType isEqualToString:@"reProduceText"]){
                NSString *sn = nil;
                if ([[dataDict allKeys] containsObject:@"data"]) {
                    NSDictionary *data = dataDict[@"data"];

                    if ([[data allKeys] containsObject:@"text"]) {
                        NSString  *pasteboardStr = [data objectForKey:@"text"];
                        UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
                        pasteboard.string = pasteboardStr;
                    }
                }
            }
            else if ([messageType isEqualToString:@"downAdnInstallRep"]){
                if ([[dataDict allKeys] containsObject:@"data"]) {
                    NSDictionary *data = dataDict[@"data"];

                    if ([[data allKeys] containsObject:@"status"]) {
                        NSString  *status = [data objectForKey:@"status"];
                        if ([status isEqualToString:@"1"]) {
                            mainBlock(^{
                               // [[iToast makeText:@"App下载完成"] show];
                            });
                        }else if ([status isEqualToString:@"0"]){
                            mainBlock(^{
                                //[[iToast makeText:@"App下载中"] show];
                            });
                        }
                    }
                }
            }
            else if ([messageType isEqualToString:@"shakeit"]){
                HLog(@"\n-----摇一摇成功------");
            }else if ([messageType isEqualToString:@"keyboardFeedbackBean"]){/*调起键盘*/
                [self->hidenTextField becomeFirstResponder];
//                [self->hidenTextField setText:@"1234"];
                [self->hidenTextField setEnabled:YES];
            }else if ([messageType isEqualToString:@"FileRandomReady"]){/*申请文件上传得到答复*/
                [weakSelf applyUploadFileServiceResponseFun:dataDict];
            }
            else if ([messageType isEqualToString:@"uploadFileRandomRet"]){/*文件上传得到答复*/
                [weakSelf upLoadFileFunServiceResponseFun:dataDict];
            }
            else if ([messageType isEqualToString:@"getBaseInfo"]){/*获取云机的基本信息*/
                [weakSelf getCouldPhoneBaseInfoResponseFun:dataDict];
            }
            else if ([messageType isEqualToString:@"getSysInfo"]){/*获取云机的系统信息*/
                [weakSelf getCouldPhoneSysInfoResponseFun:dataDict];
            }
            else if ([messageType isEqualToString:@"TvStatus"]){/*获取TV投屏信息*/
                [weakSelf getCouldPhoneTvStatusResponseFun:dataDict];
            }
            else if ([messageType isEqualToString:@"reboot"]){/*重启*/
                [weakSelf stopForceStartTimerFun];
            }
        } failure:^(NSError *error) {
            [self showNetErrorAlertFun:2];
        }];
    }
}



- (void)textDidChange:(UITextField *)textField{
    if (textField.markedTextRange == nil) {
        /*新内容 完全包含前面的内容 就是删除*/
        NSRange newInOld = [hidenTextFieldOldStr rangeOfString:textField.text];
        if (newInOld.location == 0 && newInOld.length == textField.text.length){/*删除*/
            NSString *dataStr = [RCCommandHelp commandKeyboadInputStr:nil];
            [self.businessCommandChannelManager rc_sendData:dataStr];
            /*删除以后在输入框前面新增一个字符*/
            NSString *tempStr = textField.text;
            if (tempStr.length > 0){
            }else{
                tempStr = @" ";
            }
            textField.text = tempStr;
        }else{
            /*新增*/
            NSRange oldInNew = [textField.text rangeOfString:hidenTextFieldOldStr];
            if (oldInNew.location == 0 && oldInNew.length == hidenTextFieldOldStr.length){/*新增*/
                NSString *addStr = [textField.text substringWithRange:(NSMakeRange(hidenTextFieldOldStr.length, textField.text.length - hidenTextFieldOldStr.length))];
                NSLog(@"键盘透传--@@@@新增内容:%@",addStr);
                NSString *dataStr = [RCCommandHelp commandKeyboadInputStr:addStr];
                [self.businessCommandChannelManager rc_sendData:dataStr];
            }else{/*部分覆盖*/
                /*覆盖分为两部分 1、覆盖的内容更长 2、覆盖的内容更短*/
                /*删除不同的部分  加上变化的部分*/
                /*后面不同内容的长度*/
                NSInteger sameLength = 0;
                if (hidenTextFieldOldStr.length < textField.text.length){
                    sameLength = [self sameStrLengthSmallStr:hidenTextFieldOldStr longStr:textField.text];
                }else{
                    sameLength = [self sameStrLengthSmallStr:textField.text longStr:hidenTextFieldOldStr];
                }
                /*需要删除的长度*/
                NSInteger needDeleteLength = hidenTextFieldOldStr.length - sameLength;
                for (NSInteger nFori = 0; nFori < needDeleteLength; nFori++) {
                    NSString *dataStr = [RCCommandHelp commandKeyboadInputStr:nil];
                    [self.businessCommandChannelManager rc_sendData:dataStr];
                }
                
                /*需要增加的内容*/
                NSInteger needLength = textField.text.length - sameLength;
                NSString *addStr = [textField.text substringWithRange:(NSMakeRange(sameLength, needLength))];
                NSString *dataStr = [RCCommandHelp commandKeyboadInputStr:addStr];
                [self.businessCommandChannelManager rc_sendData:dataStr];
            }
        }
        hidenTextFieldOldStr = textField.text;
    }
}

- (NSInteger)sameStrLengthSmallStr:(NSString *)litStr longStr:(NSString *)longStr{
    NSInteger samenumber = 0;
    for (NSInteger nFori = 1; nFori < litStr.length+1; nFori++) {
        NSString *temp0 = [litStr substringToIndex:nFori];
        NSString *temp1 = [longStr substringToIndex:nFori];
        if (![temp0 isEqualToString:temp1]){
            break;
        }
        samenumber++;
    }
    
    return samenumber;
}

#pragma mark - UI相关
- (void)drawView
{
    hidenTextField = [[UITextField alloc] initWithFrame:(CGRectMake(0, 0, 0, 0))];
    hidenTextField.delegate = self;
    [hidenTextField addTarget:self action:@selector(textDidChange:) forControlEvents:UIControlEventEditingChanged];
    
    [self.view addSubview:hidenTextField];
    
    [self.view setBackgroundColor:[UIColor whiteColor]];

    mPlayerView = [[PlayerView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, SCREEN_H)];
    //mPlayerView.buyVipType = self.buyVipType;
    [mPlayerView initPoMas_makeWithImageRate:YES isUsageMode:NO];
    [mPlayerView setBackgroundColor:[UIColor blackColor]];
    mPlayerView.delegate = self;

    
    deviceShareStates = 2;
    
    [self.view addSubview:mPlayerView];
    
    [mPlayerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(0);
        make.right.mas_equalTo(0);
        make.top.mas_equalTo(0);
        make.bottom.mas_equalTo(0);
    }];
    
    [self reSetPlayerViewFloatBtnFrame];
    
    if (isLan)/*直接g或者变为横屏*/
    {
        [mPlayerView setLanMas_makeWithImageRate:ksharedAppDelegate.couldPhone_W_PHONE/ksharedAppDelegate.couldPhone_H_PHONE isOpenVirtual:YES isUsageMode:NO];
    }
    else
    {
        [mPlayerView setPoMas_makeWithImageRate:ksharedAppDelegate.couldPhone_W_PHONE/ksharedAppDelegate.couldPhone_H_PHONE isOpenVirtual:YES isUsageMode:NO];
    }
}

/**
 * @brief 漂浮按钮位置初始化
 *
 *
 */
- (void)reSetPlayerViewFloatBtnFrame
{
//    [[[UIApplication sharedApplication] keyWindow] addSubview:mPlayerView.controlBtn];
    [self.navigationController.view addSubview:mPlayerView.controlBtn];
    [self.navigationController.view bringSubviewToFront:mPlayerView.controlBtn];
    
    NSDictionary *dict = nil;
    
    CGFloat h_w_controlBtn = 60.f;
    if (dict)
    {
        CGFloat pointx = [[dict objectForKey:@"pointx"] floatValue];
        CGFloat pointy = [[dict objectForKey:@"pointy"] floatValue];
        
        if (mPlayerView.width > mPlayerView.height){
            if (pointx < 30)
            {
                pointx = 30;
            }
            else if (pointx > mPlayerView.width - h_w_controlBtn - 10.f)
            {
                pointx = mPlayerView.width - h_w_controlBtn - 10.f;
            }
            
            if (pointy < 10)
            {
                pointy = 10;
            }
            else if (pointy > mPlayerView.height - h_w_controlBtn - 10.f)
            {
                pointy = mPlayerView.height - h_w_controlBtn - 10.f;
            }
        }else{
            if (pointx < 10)
            {
                pointx = 10;
            }
            else if (pointx > mPlayerView.width - h_w_controlBtn - 10.f)
            {
                pointx = mPlayerView.width - h_w_controlBtn - 10.f;
            }
            
            if (pointy < 10)
            {
                pointy = 10;
            }
            else if (pointy > mPlayerView.height - h_w_controlBtn - 10.f)
            {
                pointy = mPlayerView.height - h_w_controlBtn - 10.f;
            }
        }
        
//        BOOL hidden = [[dict objectForKey:@"hidden"] boolValue];
        
        [mPlayerView.controlBtn setFrame:CGRectMake(pointx, pointy, h_w_controlBtn, h_w_controlBtn)];
    }
    else
    {
        /*区分横竖屏*/
        if (mPlayerView.width > mPlayerView.height){
            [mPlayerView.controlBtn setFrame:CGRectMake((mPlayerView.width - h_w_controlBtn)/2.f, mPlayerView.height - h_w_controlBtn - 20.f, h_w_controlBtn, h_w_controlBtn)];
        }else{
            //默认居右
            //[mPlayerView.controlBtn setFrame:CGRectMake(mPlayerView.width - h_w_controlBtn - 20.f, (SCREEN_H - h_w_controlBtn)/2.f, h_w_controlBtn, h_w_controlBtn)];
            
            //默认居左
            [mPlayerView.controlBtn setFrame:CGRectMake( h_w_controlBtn + 10.f, (SCREEN_H - h_w_controlBtn)/2.f, h_w_controlBtn, h_w_controlBtn)];
        }
        
        [mPlayerView.controlBtn setHidden:NO];
    }
    
    HLog(@"云手机推流界面 控制按钮中点%@",NSStringFromCGPoint(mPlayerView.controlBtn.center));
    
}

#pragma mark - 手势权限控制处理
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer
                   *)gestureRecognizer{
  return NO; //YES：允许右滑返回 NO：禁止右滑返回
}

- (void)enablePanRightBack
{
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    }
    
    if ([self.tabBarController.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.tabBarController.navigationController.interactivePopGestureRecognizer.enabled = YES;
    }
}

- (void)noEnablePanRightBack
{
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
    
    if ([self.tabBarController.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.tabBarController.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
}

#pragma mark  - RCLiveSteamManagerDelegate

- (void)liveStreamManagerOutPut:(RCLiveSteamManager *)manager didOutPutVideoPixelBuffer:(CVPixelBufferRef)pixelBuffer {
    
    if(!_canShowImgAndVoiceType){
        return;
    }
    
    if (!mySelf || mySelf->haveBack) {
        return;
    }
    if (!pixelBuffer) {
        return;
    }
    [mySelf updateAutoRateAndNetWorkStates];//更新网络标识  以及自动码率
    
    if (mySelf&&!(mySelf->haveBack))
    {
        mySelf->reConnectAccount = 0;
        
        @autoreleasepool {
            if (!mySelf)
            {
                return ;
            }
            
            CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
            if (mySelf->saveCIImage) {
                mySelf->saveCIImage = nil;
            }
            mySelf->saveCIImage = ciImage;
            
            if (!mySelf->videoContext) mySelf->videoContext = [CIContext contextWithOptions:nil];
                            
            if (USEOPENGL)
            {
                if (ciImage)
                {
                    [mySelf showImageOpenglWithCIImage:ciImage];/*使用Opengl渲染*/
                    
                    mySelf.concentTime = [iTools getNowTimeStamp];
                    mySelf.isConnectSuccess = YES;
                }
            }
            else
            {
                if (ciImage)
                {
                    [mySelf showImageUIImageViewWithCIImage:ciImage pixelBufferRef:pixelBuffer];/*使用UIImageView渲染*/
                    
                    mySelf.concentTime = [iTools getNowTimeStamp];
                    mySelf.isConnectSuccess = YES;
                }
            }
            
            if (mySelf&&!mySelf->haveBack && mySelf->wattingView)
            {
                mainBlock(^{
                    [mySelf removeNewIndicator];
                });
            }
        }
    }
}

- (void)liveStreamManagerOutPut:(RCLiveSteamManager *)manager didOutPutAudioData:(NSData *)pcmData {
    @autoreleasepool {
        
        if(!_canShowImgAndVoiceType){
            return;
        }
        
        if (mySelf&&!(mySelf->haveBack)){
            [mySelf->connectLock lock];

            if (!mySelf->pcmPlayer){
                mySelf->pcmPlayer = [[RCPCMPlayer alloc] initWithAudioBufferSize:4096 mSampleRate:44100 mChannelsPerFrame:2];
                
                mySelf.isNeedShowVoiceBar = NO;
                
                [mySelf->pcmPlayer start];
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    mySelf.isNeedShowVoiceBar = YES;
                });
            }

            if (pcmData){
                mySelf.isNeedShowVoiceBar = NO;
                
                [mySelf->pcmPlayer play:pcmData];
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    mySelf.isNeedShowVoiceBar = YES;
                });
            }
        
            [mySelf->connectLock unlock];
        }
    }
}

- (void)liveStreamManager:(RCLiveSteamManager *)manager connectState:(ConnectState)state {
    HLog(@"\n------状态回调---state = %d--", state);
    //[[VclCrash sharedInstance] writeContent:[NSString stringWithFormat:@"_connectDisconnect连接返回句柄 = %d--state--=%d-",ihandle,state]];
    
    switch (state){
        case 0:/*连接已释放*/{
        }
            break;
        case 1:/*正在连接*/{
        }
            break;
        case 2:/*连接成功*/{
            HLog(@"\n-----_%s------SSSSSSSSSSS连接成功",__FUNCTION__);
            
            if (self.isFirstEnterPhone) {
                self.isFirstEnterPhone = NO;
            }
            
            //重启后重连 出来的
            if(_isRebootIngType && !forceStartTimer){
                mainBlock(^{
                    [[iToast makeText:NSLocalizedString(@"player_link_reboot_suc_Tips",nil)] show];
                });
                _isRebootIngType = NO;
            }
            
            //重启后重连 出来的
            if(_isResetingType){
                mainBlock(^{
                    [[iToast makeText:NSLocalizedString(@"my_set_no_Restore_Factorying_tips",nil)] show];
                });
                _isResetingType = NO;
            }
            
            
            
            //  报链接失败 后面又连接上了
            if(linkFailAlretVC){
                mainBlock(^{
                    [self->linkFailAlretVC dismissViewControllerAnimated:YES completion:^{
                                        
                    }];
                    self->linkFailAlretVC = nil;
                });
            }
        }
            break;
        case 3:/*正在渲染*/{
        }
            break;
        case 4:/*正在关闭*/{
        }
            break;
        case 5:/*已关闭*/{
        }
            break;
        case 6:{
            mainBlock(^{
                [self showNewIndicator];
                [self tryAgain];
            });
        }
            break;
        case ConnectStateVerifyErr:{
            HLog(@"\n------token异常----重新超分-----");
            /*鉴权失败  进行超分操作*/
            /*先清除当前的token*/
//            NSDictionary *dictLogin = [[UseAccountManage shareInstance] getLoginInfo];
//            if (dictLogin && [[dictLogin allKeys] containsObject:@"userName"])
//            {
//                /*判断数据库中有没有对应phoneid*/
//                NSString* username = [dictLogin objectForKey:@"userName"];
//                NSString * bg_tableName = P2PModelList_bg_tableName(username);
//                //先显示本地缓存数据
//                NSArray* finfAlls = [PhoneP2PListModel bg_findAll:bg_tableName];
//                if (finfAlls && finfAlls.count >0) {
//                    PhoneP2PListModel *listMod = finfAlls[0];
//                    for (PhoneP2PModel *p2pModel in listMod.data) {
//                        if (p2pModel.phoneId == self.deviceModel.phoneId){
//                            [listMod.data removeObject:p2pModel];
//                            [listMod bg_cover];
//                            break;
//                        }
//                    }
//                }
//            }
        }
            break;
        default:
            break;
    }
}

- (void)openVideForLiveStreamManager:(AVCaptureDevicePosition)position needPost:(BOOL)needPost
{
    if (mySelf&&!(mySelf->haveBack))
    {
        if (mySelf->canControl)
        {
            [mySelf toStopRecoder];
            HLog(@"\n-----打开视频透传  后置摄像头-------");
            [mySelf toStartRecoderWithAVCaptureDevicePosition:(position)];
            
//            if (needPost) {
//                // 云机摄像头使用上报
//                [mySelf postCloudCamera];
//            }
        }
    }
}

- (void)liveStreamManager:(RCLiveSteamManager *)manager didReceiveEvent:(EventState)event {
    
    EventState state = event;
    if (0 == state)/*横屏*/
    {
        if (USELOCALKEYBOARD){
            isLan = YES;
            /*横屏处理*/
            [self setDeviceOrientation:(UIDeviceOrientationLandscapeLeft)];
            HLog(@"\n---000000--横屏--000000-----");
        }else{
            /*横屏处理*/
            isLan = NO;
            [self setDeviceOrientation:(UIDeviceOrientationPortrait)];
            HLog(@"\n---000000--横屏--000000-----");
        }
        
        mySelf->mPlayerView.isLan = YES;
        HLog(@"\n---000000--横屏--000000-----");
    }
    else if (1 == state)/*竖屏*/
    {
        isLan = NO;
        mySelf->mPlayerView.isLan = NO;
        /*横屏处理*/
        [self setDeviceOrientation:(UIDeviceOrientationPortrait)];
    }
    else if (2 == state)/*打开音频透传*/
    {
        if (mySelf&&!(mySelf->haveBack))
        {
            if (mySelf->canControl)
            {
                HLog(@"\n-----打开视频透传-------");
                [mySelf toStartAudioRecoder];
            }
        }
    }
    else if (3 == state)/*关闭音频透传*/
    {
        [mySelf toStopAudioRecoder];
    }
    else if (4 == state)/*打开视频透传*/
    {
        [self openVideForLiveStreamManager:AVCaptureDevicePositionBack needPost:YES];
    }
    else if (5 == state)/*关闭视频透传*/
    {
        [mySelf toStopRecoder];
    }
    else if (7 == state)/*打开视频透传--前置摄像头*/
    {
        [self openVideForLiveStreamManager:AVCaptureDevicePositionFront needPost:YES];
    }
    else if (EventStateTurnOnVideoDontNeedToServer == state)/*打开视频透传*/
    {
        [self openVideForLiveStreamManager:AVCaptureDevicePositionBack needPost:NO];
    }
    else if (EventStateTurnOnVideoFrontDontNeedToServer == state)/*打开视频透传--前置摄像头*/
    {
        [self openVideForLiveStreamManager:AVCaptureDevicePositionFront needPost:NO];
    }
    else if (EventStateTurnOnVideoDontNeedToServer == state)/*打开视频透传*/
    {
        [self openVideForLiveStreamManager:AVCaptureDevicePositionBack needPost:NO];
    }
    else if (EventStateTurnOnVideoFrontDontNeedToServer == state)/*打开视频透传--前置摄像头*/
    {
        [self openVideForLiveStreamManager:AVCaptureDevicePositionFront needPost:NO];
    }
}

- (void)liveStreamManager:(RCLiveSteamManager *)manager didReceiveMessage:(NSString *)message {
    
}

- (void)liveStreamManager:(RCLiveSteamManager *)manager didReceiNetEstimator:(NetEstimator)estimator{
    
}

- (void)liveStreamManager:(RCLiveSteamManager *)manager didReceiveJitterDelay:(int)jitterDelayMs{
    HLog(@"延时毫秒：%d",jitterDelayMs)
}


#pragma mark - 视频流回调
void connectStateCallBack (void *client, ConnectState state, void *context)
{
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:1],@"ihandle",[NSNumber numberWithInt:state],@"state" ,nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:NotNameByCONNECT_DISCONNECT object:dict];
}

static int delayVideo = 0;/*当前最高延时*/
static int okdelayVideo  = 0;/*当前连续延时较好帧数*/
static int baddelayVideo = 0;/*当前较坏延时帧数个数*/
static int havedelayVideoCount = 0;/*当前帧数个数*/
NSDate *lastVideoTome;/*上一帧数据时间*/


- (void)toStartRecoderWithAVCaptureDevicePosition:(AVCaptureDevicePosition)position
{
    if (!self.recoderManager)
    {
        self.recoderManager = [[RCVideoRecoderManager alloc] initWithAVCaptureDevicePosition:position];
        self.recoderManager.delegate = self;
    }
    
    if (!self.recoderManager.isRecoding)
    {
        [self.recoderManager startRecording];
    }
}

- (void)toStopRecoder
{
    if (self.recoderManager)
    {
        [self.recoderManager stopRecording];
        self.recoderManager = nil;
    }
}

- (void)toStartAudioRecoder
{
    if (!self.audioRecoderMamager)
    {
        self.audioRecoderMamager = [[RCAudioRecoderMamager alloc] init];
        self.audioRecoderMamager.delegate = self;
    }
    
    if (!self.audioRecoderMamager.isRecoding)
    {
        [self.audioRecoderMamager startRecording];
    }
}

- (void)toStopAudioRecoder
{
    if (self.audioRecoderMamager)
    {
        [self.audioRecoderMamager stopRecording];
        self.audioRecoderMamager = nil;
    }
}

/**
 * @brief 请求I帧数据
 */
- (void)requestIFrame
{
    [self.liveStreamManager rc_requestIDFrame];
}

#pragma mark - 流媒体服务器
// 初始化
- (BOOL)initVideoServer {
    return YES;
}

// 连接
- (void)connectVideoServer {
    if (!mySelf || haveBack || !ip || !internetVideoPort){
        return;
    }
    
    if (!connectLock)
    {
        connectLock = [[NSLock alloc] init];
    }
    [connectLock lock];

    delayVideo = 0;
    okdelayVideo = 0;
    havedelayVideoCount = 0;
    RCStateInt result = -1;
    
    NSString *tempIP = ip;
    
    HLog(@"__连接ip__%@,端口__%@",ip,internetVideoPort);
    
    //
    RCCloudPhoneConnectType ConnectType = RCCloudPhoneConnectType_websocket;
    RCCloudPhoneVideoQuality VideoQuality = RCCloudPhoneVideoQuality_Default;//RCCloudPhoneVideoQuality_High;
    if([connectDeviceManager shareInstance].DeviceThirdIdMod.data.isPingOk)
    {
        ConnectType = RCCloudPhoneConnectType_udp;
        VideoQuality = RCCloudPhoneVideoQuality_Default;
    }
    result = [self.liveStreamManager rc_openWithIp:ip
                                                         port:internetVideoPort.intValue
                                                  connectType:ConnectType
                                                 videoQuality:VideoQuality
                                                       verify:@"123456"
                                                 streamAESKey:nil];
    
    if ([tempIP isEqualToString:ip])
    {
        if (result < 0)
        {
            [self tryAgain];
        }
        else if (result == 12)
        {
            //[[iToast makeText:@"画面异常,请重新进入"] show];
            HLog(@"画面异常,请重新进入");
        }
    }
    
    HLog(@"______连接____ip = %@   port = %@",ip,internetVideoPort);
    
    HLog(@"__________连接1111111__________");
        HLog(@"__________连接成功__________");

    lastVideoTome = [NSDate date];

    NSString *dataStr =  [RCCommandHelp commandResolution500WithType:(NSUInteger)BITRATE_WIFI_HD];
    [self.liveStreamManager rc_sendJsonData:[dataStr UTF8String]];

//    // 20210305 因为安卓做了分辨率适应 而iOS不需要 所以现在指定接收码率 这个就不用修改对应触摸点的范围比例了 W_PHONE H_PHONE
//    // 发送数据
//    if ([deviceModel.buyVipType isEqualToString:CloudPhoneTypeWuJiPro]) {
//        NSString *commondStr  = @"{\"data\":{\"height\":1920,\"width\":1080},\"type\":\"setPhoneSize\"}";
//        [self send_data:commondStr];
//    }
//
//    //记录推流开始时间
//    NSString *connectedDataStr = [RCCommandHelp commandConnectedWithDeviceId:deviceId];
//    [self send_data:connectedDataStr];

    [connectLock unlock];
}

// 断开连接
- (void)disconnectVideoServer {
    NSString *commondStr = [RCCommandHelp toStopControllerDevice500];
    [self send_data:commondStr];
    HLog(@"\n-----...commondStr = %@....",commondStr);

    [self.liveStreamManager rc_disconnect];
}


- (void)send_data:(NSString *)dataStr
{
    if (canControl)
    {
        KyoLog(@"\n-commandChannelManager---%ld--%@",self.commandChannelManager.rc_socketStatus,dataStr);
        [self.commandChannelManager rc_sendData:dataStr];
    }
}

#pragma mark - PlayerViewDelegate---下方虚拟按键
- (void)mueBtnBePressed:(id)sender
{
    HLog(@"__________%s__________",__func__);
    NSString *dataStr = [RCCommandHelp commandBackOrHomeVolum500WithKeyCode:187];
    HLog(@"\n-----...dataStr = %@....",dataStr);
    
    [self send_data:dataStr];
}

- (void)homeBtnBePressed:(id)sender
{
    HLog(@"__________%s__________",__func__);
    NSString *dataStr = [RCCommandHelp commandBackOrHomeVolum500WithKeyCode:3];
    HLog(@"\n-----...dataStr = %@....",dataStr);
    
    [self send_data:dataStr];
}

- (void)backBtnBePressed:(id)sender
{
    HLog(@"__________%s__________",__func__);
    NSString *dataStr = [RCCommandHelp commandBackOrHomeVolum500WithKeyCode:4];
    HLog(@"\n-----...dataStr = %@....",dataStr);
    
    [self send_data:dataStr];
}

- (void)useInfoBtnBePressed:(id)sender
{
    HLog(@"云手机推流界面 控制按钮点击手势开始");
    [[NSNotificationCenter defaultCenter] postNotificationName:PlayerViewControlBtnTouchBeganNotification object:nil userInfo:nil];
    HLog(@"云手机推流界面 控制按钮点击手势结束");
    [[NSNotificationCenter defaultCenter] postNotificationName:PlayerViewControlBtnTouchEndNotification object:nil userInfo:nil];
    
    HLog(@"__________%s__________",__func__);
    [[UIApplication sharedApplication] setStatusBarHidden:NO];
    MySetViewController *nextVC = [[MySetViewController alloc] init];
    nextVC.whetherPhoneStatus = phoneTimeInfoDataModel.data.whetherPhoneStatus;
    [self.navigationController pushViewController:nextVC animated:YES];
    self.isNeedRecyclResource = NO;
    
    KWeakSelf
#pragma mark 重启盒子
    //{"type":"reboot"}
    nextVC.needToReboot = ^{
        
        NSString *commondStr  = @"{\"type\":\"reboot\"}";
        [weakSelf send_data:commondStr];
        
        [weakSelf startForceStartTimerFun];
        
        //最后一帧 没显示正在重启问题
        self->_canShowImgAndVoiceType = YES;
        
        self->_isRebootIngType = YES;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf reconnectDevice];
        });
    };
    
#pragma mark TV投屏
    nextVC.needToTVP2P = ^{
        NSString *commondStr  = @"{\"type\":\"wakeupTV\"}";
        [weakSelf send_data:commondStr];
    };
#pragma mark 关闭TV投屏
    nextVC.closeTVP2P = ^{
        NSString *commondStr  = @"{\"type\":\"TvOff\"}";
        [weakSelf send_data:commondStr];
    };
    
#pragma mark 恢复出厂盒子
    nextVC.needToReset = ^{
        
        NSString *commondStr  = @"{\"type\":\"reset\"}";
        [weakSelf send_data:commondStr];
        
        //最后一帧 没显示正在重启问题
        //self->_canShowImgAndVoiceType = YES;
        self->_isResetingType = YES;
        
    };
    
#pragma mark 恢复出厂盒子 ok
        nextVC.needToResetAndOk = ^{
            [weakSelf startCheckThridRuiYunTimerFun];
        };
        
#pragma mark 获取云机剩余空间
    nextVC.getBaseInfo = ^{
        
        NSString *commondStr  = @"{\"type\":\"getBaseInfo\"}";
        [weakSelf send_data:commondStr];
    };
    
    
#pragma mark 获取云机版本信息
    nextVC.getSysInfo = ^{
        
        NSString *commondStr  = @"{\"type\":\"getSysInfo\"}";
        [weakSelf send_data:commondStr];
    };
    
#pragma mark 获取TV投屏状态
    nextVC.getTvStatus = ^{
        
        NSString *commondStr  = @"{\"type\":\"TvStatus\"}";
        [weakSelf send_data:commondStr];
    };
}

#pragma mark 启动timer 秒后检查是否软件重启成功
- (void)startForceStartTimerFun
{
    if(forceStartTimer){
        [forceStartTimer invalidate];
        forceStartTimer = nil;
    }
    
    forceStartTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(gotoUpdateForceStartFun) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:forceStartTimer forMode:NSRunLoopCommonModes];
}

- (void)gotoUpdateForceStartFun
{
    [self updateForceStartFun];
    
    KWeakSelf
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf reconnectDevice];
    });
}

- (void)stopForceStartTimerFun
{
    if(forceStartTimer){
        [forceStartTimer invalidate];
        forceStartTimer = nil;
    }
}

#pragma mark 盒子链接成功后需要处理的各种各样事情
- (void)handlAllMsgAfterDidLinkFun
{
    //获取云机尺寸 兼容 720*1080 &1080*1920 不同分辨率的展示和触控
    NSString *getPhoneSizeStr = [RCCommandHelp getPhoneSizecommand];
    [self send_data:getPhoneSizeStr];
    
    //判断是否为需要改机
    BOOL isNeedRandomChangeParams = [HWDataManager getBoolWithKey:Const_need_random_Change_Params];
    if(isNeedRandomChangeParams)
    {
        NSString *commondStr  = @"{\"type\":\"randomChangeParams\"}";
        [self send_data:commondStr];
        
        [HWDataManager setBoolWithKey:Const_need_random_Change_Params value:NO];
    }
    
    [self fristConnectNeedGiveAMsgFun];
    
    
}

#pragma mark 盒子第一次连接成功  给ws发送信息 单点登录 把其他账号挤下去
- (void)fristConnectNeedGiveAMsgFun{
    
    if([self isPlayerViewIsTopVCFun]){
        //等下再发
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self fristConnectNeedGiveAMsgFun];
        });
        return;
    }
    
    if(!_didSendfristMsg || _isLoginAgainType){
        NSString *commondStr  = @"{\"type\":\"forwardMsg\",\"data\":\"offline_notification\"}";
        [self send_data:commondStr];
        _didSendfristMsg = true;
        
        _isLoginAgainType = false;
        
        [self getPreferredLanguage];
        //test code
        //[self LogoutByOtherFun];
    }
}

#pragma mark 语言和市区 同步云机
-(void)getPreferredLanguage
{//{"data":{"language":"zh-CN","timeZone":"Etc/GMT+8"},"type":"setLanguages"}
    // iOS 获取设备当前语言的代码
    NSString *preferredLanguage = [[[NSBundle mainBundle] preferredLocalizations] firstObject];
    HLog(@"当前语言:%@", preferredLanguage);

    //en-US 英文 ja-JP 日文
    
    NSArray *arLanguages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
    NSLog(@"arLanguages:%@",arLanguages);
    ///获取设备当前地区的代码和APP语言环境
    NSString *languageCode = [NSLocale preferredLanguages][0];
  
   
    //目前支持 中文（简体 繁体） 英文 日语
    if([languageCode  rangeOfString:preferredLanguage].location != NSNotFound){
        preferredLanguage = languageCode;
    }
    else{
        preferredLanguage = @"en-US";
    }
    
    NSString*gmtStr = [self UTCOffset];
    HLog(@"%@",gmtStr);
//    //获取名字，如“GMT+08:00
    
    NSString *commondStr = [NSString stringWithFormat:@"{\"type\":\"setLanguages\",\"data\":{\"language\":\"%@\",\"timeZone\":\"%@\"}}",preferredLanguage,gmtStr];
    
    [self send_data:commondStr];
    
}

-(NSString *)UTCOffset {
    NSTimeZone *localTZ = [NSTimeZone localTimeZone];
    float offset = localTZ.secondsFromGMT/3600.0;
    if(offset > 0){
        return [NSString stringWithFormat:@"Etc/GMT+%g",offset];
    }
    return [NSString stringWithFormat:@"Etc/GMT%g",offset];
}


#pragma mark 单点登录被挤下线弹框
- (void)LogoutByOtherFun
{
    //
    [self disconnectVideoServer];
    
    _canShowImgAndVoiceType = NO;
    
    //yyyy-MM-dd HH:mm:ss
    NSString*dateStr = [iTools getNowTimeString2];
    if(dateStr && dateStr.length == 19){
        dateStr = [dateStr substringWithRange:NSMakeRange(11, 5)];
    }
    
    if(!_needShowLogoutDelayType){
        _LogoutTimerStr = [[NSString alloc] initWithFormat:@"%@%@%@",NSLocalizedString(@"single_sign_on_Tips_one",nil),dateStr,NSLocalizedString(@"single_sign_on_Tips_two",nil)];
    }
    
    
    if(_isPwdVCShow){
        _needShowLogoutDelayType = YES;
        return;
    }
    
    _needShowLogoutDelayType = NO;
    
    NSString * loginAgainStr = NSLocalizedString(@"single_sign_on_login_again",nil);
    BOOL isOkBtnHighlight = YES;
    if(![connectDeviceManager shareInstance].DeviceThirdIdMod.data.isPrivacyMode){
        loginAgainStr = @"";
        isOkBtnHighlight = NO;
    }
    
    /*弹窗提示重启*/
    logoutAlertVC = [[ComontAlretViewController alloc] initWithTiTle:NSLocalizedString(@"single_sign_on_Tips_logout",nil)
                                                                                     msg:_LogoutTimerStr
                                                                                imageStr:nil
                                                                             cancelTitle:NSLocalizedString(@"single_sign_on_exit",nil)
                                                                                 okTitle:loginAgainStr isOkBtnHighlight:isOkBtnHighlight
                                                                              didClickOk:^{
        
    } didClickCancel:^{
        
    }];
    logoutAlertVC.modalPresentationStyle = UIModalPresentationCustom;
    logoutAlertVC.delegate = self;
    [self presentViewController:logoutAlertVC animated:YES completion:^{
        self->logoutAlertVC.view.superview.backgroundColor = [UIColor clearColor];
    }];
    
    _isLoginAgainType = YES;
}

#pragma mark 设置是否可以播放音频和视频
-(void)setShowPwdVCTypeFun
{
    _isPwdVCShow = YES;
}

-(void)setShowImgAndVoiceTypeFun
{
    _isPwdVCShow = NO;
    
    if(logoutAlertVC){
        [logoutAlertVC dismissViewControllerAnimated:NO completion:^{
            self->logoutAlertVC = nil;
        }];
    }
    
    [self setShowImgAndVoiceTypeFun:YES];
    
    if(_needShowLogoutDelayType){
        [self LogoutByOtherFun];
    }
}

#pragma mark 判断是否为密码界面登   函数意思写反了 ~~~~
- (BOOL)isPlayerViewIsTopVCFun
{
    UIViewController*topVc = self.navigationController.viewControllers.lastObject;
    if(_isPwdVCShow || ![topVc isKindOfClass:[PlayerViewController class]]){
        return YES;
    }
    
    return NO;
}

-(void)setShowImgAndVoiceTypeFun:(bool)isCan
{
    if(isCan){//判断当前是否为最前面 才能播放
        
        if([self isPlayerViewIsTopVCFun]){
            return;
        }
        
        _canShowImgAndVoiceType = isCan;
        
        if(_isLoginAgainType ){
            [self tryAgain];
            [self fristConnectNeedGiveAMsgFun];
        }
    }
    else{
        _canShowImgAndVoiceType = isCan;
    }
    
}

#pragma mark - 显示秘钥 后续忘记密码要
-(void)showSecretkeyFun
{
    mPlayerView.controlBtn.hidden = YES;
    playerShowSecretkeyView *view = [[playerShowSecretkeyView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, SCREEN_H)];
    [self.view addSubview:view];
    [self.view bringSubviewToFront:view];
    
    KWeakSelf
    view.didCloseSecretKeyViewTip = ^{
        self->mPlayerView.controlBtn.hidden = NO;
        [weakSelf showControlBtnTipFun];
    };
}

#pragma mark 显示首次浮标引导操作提示
- (void)showControlBtnTipFun{
    
    BOOL didShowControlBtnTip = [HWDataManager getBoolWithKey:Const_did_Show_playView_controlBtn_Tip];

    if(!didShowControlBtnTip && !_PlayerControlButTipV){
        mPlayerView.controlBtn.hidden = YES;
        
        _PlayerControlButTipV = [[PlayerControlButTipView alloc] init];
        _PlayerControlButTipV.backgroundColor = [UIColor hwColor:@"000000" alpha:0.6];
        [self.view addSubview:_PlayerControlButTipV];
        [self.view bringSubviewToFront:_PlayerControlButTipV];
        
        [_PlayerControlButTipV mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.mas_equalTo(0);
            make.top.mas_equalTo(0.f);
            make.left.mas_equalTo(0.f);
            make.bottom.mas_equalTo(0.f);
        }];
        
        
        _PlayerControlButTipV.didKnowPlayerControlButTip = ^{
            self->mPlayerView.controlBtn.hidden = NO;
        };
    }
}
#pragma mark - PlayerControlViewDelegate---控制器按键
//- (void)stopShareBtnBePressed:(id)sender
//{
//    HLog(@"__________%s__________",__func__);
//    /*关闭分享成功后调用*/
//    CloudPhoneModel *deviceDcit = [[UseAccountManage shareInstance].cloudPhoneListModel.diskInfo objectAtIndex:phoneIndex];
//    NSString *userCardId = @"";
//    userCardId = [NSString stringWithFormat:@"%ld",deviceDcit.phoneId];
//
//    NSString *username = deviceDcit.username;
//
//    if (0 == deviceShareStates || deviceShareStates == 3)/*分享中*/
//    {
//        /*暂停分享*/
//        NSString *reqsturl = [NSString stringWithFormat:SuspendScreenShareAPI,userCardId,username];
//        [[UseAccountManage shareInstance] CommonGetWithCallBackCode:reqsturl Parameters:nil  success:^(id  _Nonnull responseObject) {
//            SuperModel *mod = [[SuperModel alloc] initWithDictionary:responseObject error:nil];
//            [self removeNewIndicator];
//            NSString *showStr = nil;
//            showStr = mod.msg;
//            if (mod.status && mod.status.integerValue == 0)
//            {
//                deviceDcit.screenShareStatus = 1;
//                self->deviceShareStates = 1;
//                [self->controlView pauseShareView];
//                /*刷新视图 更新设备列表*/
//                deviceDcit.screenShareStatus = self->deviceShareStates;
//            }
//            else
//            {
//                if (mod.msg == nil || [mod.msg isEqualToString:@""])
//                {
//                    showStr = @"暂停分享失败";
//                }
//                [[iToast makeText:showStr] show];
//            }
//        }
//                                                            failure:^(NSError * _Nonnull error) {
//            [[iToast makeText:@"暂停分享失败"] show];
//            [self removeNewIndicator];
//        }];
//    }
//    else if (1 == deviceShareStates)/*暂停分享*/
//    {
//        /*开启分享*/
//        NSString *reqsturl = [NSString stringWithFormat:StartAgainScreenShareAPI,userCardId,username];
//        [[UseAccountManage shareInstance] CommonGetWithCallBackCode:reqsturl Parameters:nil  success:^(id  _Nonnull responseObject) {
//            SuperModel *mod = [[SuperModel alloc] initWithDictionary:responseObject error:nil];
//            [self removeNewIndicator];
//            NSString *showStr = nil;
//            showStr = mod.msg;
//            if (mod.status && mod.status.integerValue == 0)
//            {
//                self->deviceShareStates = 3;
//                deviceDcit.screenShareStatus = self->deviceShareStates;
//                [self->controlView shareingShareView];
//            }
//            else
//            {
//                if (mod.msg == nil || [mod.msg isEqualToString:@""])
//                {
//                    showStr = @"开启分享失败";
//                }
//                [[iToast makeText:showStr] show];
//            }
//        }
//                                                            failure:^(NSError * _Nonnull error) {
//            [[iToast makeText:@"开启分享失败"] show];
//            [self removeNewIndicator];
//        }];
//    }
//}


- (void)showAlertToWaitForTrial:(NSInteger)mins {

    NSString *tipsStr = [NSString stringWithFormat:@"由于系统资源繁忙\n请在%ld分钟后再次进入云手机", mins];
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:tipsStr attributes: @{NSFontAttributeName: [UIFont systemFontOfSize:16],NSForegroundColorAttributeName: HWCFD1D4Color}];
    
    UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

    }];
    [sureAction setValue:HW3B7FFFColor forKey:@"titleTextColor"];//iOS8.3
    
    [self showAlertWithTitle:nil message:string tilteAlignment:NSTextAlignmentCenter messageAlignment:NSTextAlignmentCenter sureAction:sureAction cancelAction:nil];
}

#pragma mark - 新的手势回调委托
- (void)playerShowImageViewtouchesStr:(NSString *)commondStr
{
    if (canControl)
    {
        [self send_data:commondStr];
    }
}


-(void)initAlertWithTitle:(NSString *_Nullable)title message:(NSString *)message sureActionBlock:(sureActionBlock)sureActionBlock {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        
        sureActionBlock(alertController);
    }];
    [alertController addAction:cancelAction];
    
    // 弹窗边框
    UIView *subview = alertController.view.subviews.firstObject;
    UIView *alertContentView = subview.subviews.firstObject;
    alertContentView.layer.cornerRadius = 10;
//                alertContentView.layer.masksToBounds = YES;
    alertContentView.layer.shadowColor = [UIColor colorWithRed:30/255.0 green:32/255.0 blue:34/255.0 alpha:1.0].CGColor;
    alertContentView.layer.shadowOffset = CGSizeMake(0,0);
    alertContentView.layer.shadowOpacity = 1;
    alertContentView.layer.shadowRadius = 7;
    // 弹窗背景颜色
    if (@available(iOS 13.0, *)) {
        alertController.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
    }
    
    UIViewController *currentVC = [[ShortcutManager shareInstance] findCurrentShowingViewController];
    [currentVC presentViewController:alertController animated:YES completion:nil];
//    [self presentViewController:alertController animated:YES completion:nil];
}


#pragma - mark - 监听网络变化
- (void)networkStateChange:(NSNotification *)notification
{
    /*处理*/
    switch ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus)
    {
        case AFNetworkReachabilityStatusUnknown:/*网络状态未知*/
        {
            ;
        }
            break;
        case AFNetworkReachabilityStatusNotReachable:/*网络不可用*/
        {
            //[[iToast makeText:@"网络异常，请稍后重试！"] show];
            
//                if (_ihandle > 0)
//                {
                [self disconnectVideoServer];
//                }
            
            [self showNetErrorAlertFun:12];
        }
            break;
        case AFNetworkReachabilityStatusReachableViaWWAN:/*流量*/
        {
            mainBlock(^{
                [self showNewIndicator];
            });
            [self tryAgain];
        }
            break;
        case AFNetworkReachabilityStatusReachableViaWiFi:/*WiFi*/
        {
            mainBlock(^{
                [self showNewIndicator];
            });
            [self tryAgain];
        }
            break;
            
        default:
            break;
    }

}

#pragma mark 网络异常弹框
-(void)showNetErrorAlertFun:(NSInteger)type
{
    if(linkFailAlretVC){
        return;
    }
    
    //重启后重连 出来的
    if(_isRebootIngType){
        if(![self isPlayerViewIsTopVCFun]){
            [[iToast makeText:NSLocalizedString(@"player_link_rebooting_Tips",nil)] show];
        }
        return;
    }
    
    if(_isResetingType){
        if(![self isPlayerViewIsTopVCFun]){
            [[iToast makeText:NSLocalizedString(@"my_set_no_Restore_Factorying_tips",nil)] show];
        }
        return;
    }
    
    if([self isPlayerViewIsTopVCFun]){
        
        //等下再发
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self showNetErrorAlertFun:type];
        });
        return;
    }
    
    //未连接成功过
    if(_isFirstEnterPhone && type == 5){
        type = 1;
    }
    
    NSString *linkErrTip = NSLocalizedString(@"player_link_fail_couldPhone_Tips",nil);
    if([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable){
        linkErrTip = NSLocalizedString(@"player_link_fail_phone_Tips",nil);
    }
    
    linkErrTip = [[NSString alloc] initWithFormat:@"[%ld]%@",type,linkErrTip];
    
    linkFailAlretVC= [[ComontAlretViewController alloc] initWithTiTle:NSLocalizedString(@"player_link_fail_title",nil)
                                                                                      msg:linkErrTip
                                                                                 imageStr:nil
                                                                              cancelTitle:NSLocalizedString(@"single_sign_on_exit",nil)
                                                                                  okTitle:NSLocalizedString(@"player_link_fail_tryAgain",nil) isOkBtnHighlight:YES
                                                                               didClickOk:^{
        [self showNewIndicator];
        self->reConnectAccount = 0;
        [self tryAgain];
        
        self->linkFailAlretVC = nil;
         
     } didClickCancel:^{
         exit(0);
     }];
    
     linkFailAlretVC.modalPresentationStyle = UIModalPresentationCustom;
     
     [self presentViewController:linkFailAlretVC animated:YES completion:^{
         self->linkFailAlretVC.view.superview.backgroundColor = [UIColor clearColor];
     }];
}

BOOL inReconnect = NO;
- (void)tryAgain
{
    reConnectAccount++;
    
    
    HLog(@"yyyyyyyyyyyyy 重连次数 %ld ",reConnectAccount);
    
    //20231017 修改后台3分钟再次进入 不断转圈圈问题
    if (reConnectAccount >0 && reConnectAccount == 50 )
    {
        mainBlock(^{
            
            if (self.isFirstEnterPhone) {

                self.isFirstEnterPhone = NO;
            }
            
            //重启后重连 出来的 不显示
            if(!self->_isRebootIngType && !self->_isResetingType && ![self isPlayerViewIsTopVCFun]){
                /*链接失败*/
                //[[iToast makeText:NSLocalizedString(@"player_link_fail_tip",nil)] show];
                [self showNetErrorAlertFun:5];
            }
            
        });
        
        return;
    }

    [self reconnectDevice];
}

- (void)reconnectDevice{
    globalBlock(^{
        @synchronized (self) {
            inReconnect = YES;
            [self disconnectVideoServer];
            if ([self initVideoServer])
            {
                [self connectVideoServer];
            }
        }
    });
}

#pragma mark -- /*视频码率按钮文字、索引、指令 之间相互转换*/
- (NSUInteger)resolutionBtnIndexToTypeWithIndex:(NSInteger)index
{
    NSInteger type = BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/;
    
    AFNetworkReachabilityStatus netStatus = [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;
    if (netWorkStates == AFNetworkReachabilityStatusReachableViaWiFi) {
        type = BITRATE_WIFI_STANDARD_CLEARING;
    }
    
    switch (index)
    {
        case 2:/*极速*/
            type = BITRATE_EXTREME_SPEED;
            break;
//        case 1:/*高速*/
//            type = BITRATE_HIGH_SPEED;
//            break;
        case 0:/*高清*/
            if (netStatus == AFNetworkReachabilityStatusReachableViaWiFi) {
                type = BITRATE_WIFI_HD;
            } else {
                type = BITRATE_WIFI_STANDARD_CLEARING/*BITRATE_HD*/;
            }
            break;
        case 1:/*标清*/
            if (netStatus == AFNetworkReachabilityStatusReachableViaWiFi) {
                type = BITRATE_WIFI_STANDARD_CLEARING;
            } else {
                type = BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/;
            }
            break;
        case 3:/*自动*/
            type = BITRATE_AUTO;
            break;
            
        default:
            break;
    }
    
    return type;
}

- (NSInteger)resolutionBtnTypeToIndexWithType:(NSInteger)type
{
    NSInteger index = 2;
    switch (type)
    {
        case BITRATE_EXTREME_SPEED:
            index = 2;
            break;
//        case BITRATE_HIGH_SPEED:
//            index = 1;
//            break;
        case BITRATE_WIFI_STANDARD_CLEARING/*BITRATE_HD*/:
            index = 0;
            break;
//        case BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/:
//            index = 1;
//            break;
        case BITRATE_AUTO:
            index = 3;
            break;
            
        default:
            index = 2;
            break;
    }
    
    return index;
}



- (NSString *)resolutionBtnIndexToStringWithType:(NSInteger)index
{
    NSString *qualitySelectBtnString = @"标清";
    switch (index)
    {
        case 2:
            qualitySelectBtnString = @"极速";
            break;
//        case 1:
//            qualitySelectBtnString = @"高速";
//            break;
        case 0:
            qualitySelectBtnString = @"高清";
            break;
        case 1:
            qualitySelectBtnString = @"标清";
            break;
        case 4:
            qualitySelectBtnString = @"自动";
            break;
            
        default:
            break;
    }
    
    return qualitySelectBtnString;
}

#pragma mark -- /*通知添加与移除*/
- (void)addNSNotification
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkStateChange:)  name:NetWorkChangeNotification        object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectDisconnect:)   name:NotNameByCONNECT_DISCONNECT    object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:)          name:UIDeviceOrientationDidChangeNotification  object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:)    name:UIApplicationWillTerminateNotification    object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:)  name:UIApplicationDidBecomeActiveNotification  object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:)               name:AVSystemController_SystemVolumeDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(extensionRBDGetRbdDeviceNotification:)  name:GetRbdDeviceNotification  object:nil];
    
    outputVolumeKVO = YES;
    [[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:(void *)[AVAudioSession sharedInstance]];
    
    // 控制按钮收拾开始、结束
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerViewControlBtnTouchBegan) name:PlayerViewControlBtnTouchBeganNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerViewControlBtnTouchEnd) name:PlayerViewControlBtnTouchEndNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setShowImgAndVoiceTypeFun) name:ShowImgAndVoiceNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setShowPwdVCTypeFun) name:ShowPwdVCNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginGotoUploadFileFun:) name:uploadFileBeginNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(suspendUploadFileFun:) name:uploadFileSuspendNotification object:nil];
    
}

- (void)removeNSNotification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NetWorkChangeNotification         object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NotNameByCONNECT_DISCONNECT     object:nil];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification    object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:uploadFileBeginNotification     object:nil];
    
    if (outputVolumeKVO)
    {
        [[AVAudioSession sharedInstance] removeObserver:self forKeyPath:@"outputVolume" context:(void *)[AVAudioSession sharedInstance]];
        outputVolumeKVO = NO;
    }
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark -- 音视频数据透传回调
static double firstTime;
static double lastTime;
static int  couneeee = 0;
- (void)videoOutPutH264Data:(void *)h264Data dataLenth:(NSInteger)lenth
{
    if (couneeee == 0)
    {
        firstTime = [[NSDate date] timeIntervalSince1970];
    }
    couneeee++;
    [self.liveStreamManager rc_sendTransportData:(const char *)h264Data length:(int)lenth dataType:VirtualDataTypeVideo];
    if (couneeee == 100)
    {
        lastTime = [[NSDate date] timeIntervalSince1970];
        HLog(@"\nvideoOutPutH264DataTime --%f",lastTime - firstTime);
    }
}

- (void)audioOutPutData:(void *)audioData dataLenth:(NSInteger)lenth
{
    [self.liveStreamManager rc_sendTransportData:(const char *)audioData length:(int)lenth dataType:VirtualDataTypeAudio];
}

-(NSString *)hexStringWithData:(NSData *)data
{
    const unsigned char* dataBuffer = (const unsigned char*)[data bytes];
    if(!dataBuffer){
        return nil;
    }
    NSUInteger dataLength = [data length];
    NSMutableString* hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
    for(int i = 0; i < dataLength; i++){
        [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
    }
    NSString* result = [NSString stringWithString:hexString];
    return result;
}


- (NSArray *)getAllIvar:(id)object
{
    NSMutableArray *array = [NSMutableArray array];

    unsigned int count;
    Ivar *ivars = class_copyIvarList([object class], &count);
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivars[i];
        const char *keyChar = ivar_getName(ivar);
        NSString *keyStr = [NSString stringWithCString:keyChar encoding:NSUTF8StringEncoding];
        @try {
            id valueStr = [object valueForKey:keyStr];
            NSDictionary *dic = nil;
            if (valueStr) {
                dic = @{keyStr : valueStr};
            } else {
                dic = @{keyStr : @"值为nil"};
            }
            [array addObject:dic];
        }
        @catch (NSException *exception) {}
    }
    return [array copy];
}

//系统声音改变
#pragma -mark 系统声音改变
-(void)volumeChanged:(NSNotification *)notification
{
    if (!self.isNeedShowVoiceBar) { // 不需要展示音量工具条
        return;
    }
    
//    /*音量开关打开时 允许发送指令  否则直接返回*/
//    NSDictionary *loginDict = [[UseAccountManage shareInstance] getLoginInfo];
//    NSString *account = [loginDict objectForKey:@"account"];
//    NSString *key = [account stringByAppendingString:Const_Volume_Info_Dict];
//
//    NSDictionary *volumeDict = [[NSUserDefaults standardUserDefaults] objectForKey:key];
//
//    NSString *volumeStr = [volumeDict safeStringForKey:deviceId];
//
//    if (!volumeStr || ![volumeStr isEqualToString:@"1"]){
//        return;
//    }
//
//    float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
//    HLog(@"FlyElephant-系统音量:%f", volume);
//
//    if (volume == 0)
//    {
//        NSString *dataStr = [RCCommandHelp commandBackOrHomeVolum500WithKeyCode:25];
//
//        [self send_data:dataStr];
//    }
//    else if (volume == 1)
//    {
//        NSString *dataStr = [RCCommandHelp commandBackOrHomeVolum500WithKeyCode:24];
//
//        [self send_data:dataStr];
//    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    if(context == (__bridge void *)[AVAudioSession sharedInstance])
    {
//        /*音量开关打开时 允许发送指令  否则直接返回*/
//        NSDictionary *loginDict = [[UseAccountManage shareInstance] getLoginInfo];
//        NSString *account = [loginDict objectForKey:@"account"];
//        NSString *key = [account stringByAppendingString:Const_Volume_Info_Dict];
//
//        NSDictionary *volumeDict = [[NSUserDefaults standardUserDefaults] objectForKey:key];
//
//        NSString *volumeStr = [volumeDict safeStringForKey:deviceId];
//
//        if (!volumeStr || ![volumeStr isEqualToString:@"1"]){
//            return;
//        }
//
//        float newValue = [[change objectForKey:@"new"] floatValue];
//        float oldValue = [[change objectForKey:@"old"] floatValue];
//
//        if (newValue > oldValue)
//        {
//            HLog(@"\n-----音量增加");
//            NSString *dataStr = [RCCommandHelp commandBackOrHomeVolum500WithKeyCode:24];
//
//            [self send_data:dataStr];
//        }
//        else
//        {
//            HLog(@"\n-----音量降低");
//            NSString *dataStr = [RCCommandHelp commandBackOrHomeVolum500WithKeyCode:25];
//
//            [self send_data:dataStr];
//        }
    }
}

#pragma mark-----------------------------------------------------------------------------------------------
#pragma mark - 画面渲染、画面调整相关
#pragma mark - 更新网络标识  以及自动码率
- (void)updateAutoRateAndNetWorkStates
{
    int audio_time = 0;
    NSDate *nowTime = [NSDate date];
    NSString *nowTimeStr  = [NSString stringWithFormat:@"%f", (double)[nowTime timeIntervalSince1970]];
    NSString *lastTimeStr = [NSString stringWithFormat:@"%f", (double)[lastVideoTome timeIntervalSince1970]];
    audio_time = ([nowTimeStr doubleValue] - [lastTimeStr doubleValue]) * 1000;
    lastVideoTome = nowTime;
    
    static int frameCount = 200;
    
    if (0 == frameCount)
    {
        frameCount = 200;
        
        if (audio_time > 500 && !haveBack && self->netWorkStates != 0)
        {
            self->netWorkStates = 0;
            mainBlock(^{
                [self->mPlayerView.controlBtn setBackgroundImage:[UIImage imageNamed:@"you_icon"] forState:(UIControlStateNormal)];
            });
        }
        else if (audio_time > 100 && !haveBack && self->netWorkStates != 1)
        {
            self->netWorkStates = 1;
            mainBlock(^{
                [self->mPlayerView.controlBtn setBackgroundImage:[UIImage imageNamed:@"you_icon"] forState:(UIControlStateNormal)];
            });
        }
        else if (!haveBack && self->netWorkStates != 2)
        {
            self->netWorkStates = 2;
            mainBlock(^{
                [self->mPlayerView.controlBtn setBackgroundImage:[UIImage imageNamed:@"you_icon"] forState:(UIControlStateNormal)];
            });
        }
    }
    else
    {
        frameCount--;
    }
        
    if (delayVideo <  audio_time)
    {
        delayVideo = audio_time;
    }
    
    if (delayVideo < 80)
    {
        okdelayVideo++;
    }
    else
    {
        okdelayVideo = 0;
    }
    
    if (delayVideo > 120)
    {
        baddelayVideo++;
    }
    
    havedelayVideoCount++;
    
    if (havedelayVideoCount % 1000 == 0)
    {
        baddelayVideo = 0;
    }
    
    if (!haveBack && self->rate == 3) {

        if (baddelayVideo > 10)
        {
            /*降低码率*/
            if (self->rateForAuto == BITRATE_WIFI_STANDARD_CLEARING/*BITRATE_HD*/ || self->rateForAuto == BITRATE_WIFI_HD)
            {
                if (self->rateForAuto == BITRATE_WIFI_STANDARD_CLEARING/*BITRATE_HD*/) {
                    self->rateForAuto = BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/;
                } else {
                    self->rateForAuto = BITRATE_WIFI_STANDARD_CLEARING;
                }
            }
            else if (self->rateForAuto == BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/ || self->rateForAuto == BITRATE_WIFI_STANDARD_CLEARING)
            {
                self->rateForAuto = BITRATE_EXTREME_SPEED;
            }
//            else if (mySelf->rateForAuto == BITRATE_HIGH_SPEED)
//            {
//                mySelf->rateForAuto = BITRATE_EXTREME_SPEED;
//                NSString *dataStr =  [RCCommandHelp commondResolution500WithType:mySelf->rateForAuto];
//                int result = send_data(mySelf->_ihandle, [dataStr UTF8String], (int)dataStr.length, 10.f);
//            }
            NSString *dataStr =  [RCCommandHelp commandResolution500WithType:self->rateForAuto];
//            send_data(mySelf->_ihandle, [dataStr UTF8String], (int)dataStr.length, 10.f);
            [self.liveStreamManager rc_sendJsonData:[dataStr UTF8String]];
            baddelayVideo = 0;
        }
        
        if (okdelayVideo > 1000)
        {
            /*上升码率*/
            if (self->rateForAuto == BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/ || self->rateForAuto == BITRATE_WIFI_STANDARD_CLEARING)
            {
                if (self->rateForAuto == BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/) {
                    self->rateForAuto = BITRATE_WIFI_STANDARD_CLEARING/*BITRATE_HD*/;
                } else {
                    self->rateForAuto = BITRATE_WIFI_HD;
                }
            }
//            else if (mySelf->rateForAuto == BITRATE_HIGH_SPEED)
//            {
//                mySelf->rateForAuto = BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/;
//                NSString *dataStr =  [RCCommandHelp commondResolution500WithType:mySelf->rateForAuto];
//                int result = send_data(mySelf->_ihandle, [dataStr UTF8String], (int)dataStr.length, 10.f);
//            }
            else if (self->rateForAuto == BITRATE_EXTREME_SPEED)
            {
                if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi) {
                    self->rateForAuto = BITRATE_WIFI_STANDARD_CLEARING;
                } else {
                    self->rateForAuto = BITRATE_EXTREME_SPEED/*BITRATE_STANDARD_CLEARING*/;
                }
            }
            NSString *dataStr =  [RCCommandHelp commandResolution500WithType:self->rateForAuto];
//            send_data(mySelf->_ihandle, [dataStr UTF8String], (int)dataStr.length, 10.f);
            [self.liveStreamManager rc_sendJsonData:[dataStr UTF8String]];
            okdelayVideo = 0;
        }
    }
}

#pragma mark - opengl渲染
- (void)showImageOpenglWithCIImage:(CIImage *)ciImage
{
    if (USELOCALKEYBOARD){
        ;
    }else{
        CGFloat    tempRate   = ciImage.extent.size.width/ciImage.extent.size.height;
        if (w_h_rate != tempRate)
        {
    //        ksharedAppDelegate.couldPhone_W_PHONE = ciImage.extent.size.width;
    //        ksharedAppDelegate.couldPhone_H_PHONE = ciImage.extent.size.height;
    
            w_h_rate = tempRate;
            mainBlock(^{
                [self updatePlayViewRate:tempRate];
            });
        }
    }

    [mPlayerView glkShowImage:ciImage];
}

#pragma mark - UIImageView渲染
- (void)showImageUIImageViewWithCIImage:(CIImage *)ciImage pixelBufferRef:(CVPixelBufferRef)pixelBuff1
{
    CGImageRef videoImage = [videoContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBuff1), CVPixelBufferGetHeight(pixelBuff1))];
    UIImage    *image     = [UIImage imageWithCGImage:videoImage];
    CGFloat    tempRate   = image.size.width/image.size.height;
      
    mainBlock(^{
        if (image)
        {
            if (USELOCALKEYBOARD){
                ;
            }else{
                if (w_h_rate != tempRate)
                {
    //                ksharedAppDelegate.couldPhone_W_PHONE = ciImage.extent.size.width;
    //                ksharedAppDelegate.couldPhone_H_PHONE = ciImage.extent.size.height;

                    [self updatePlayViewRate:tempRate];
                }
            }

            self->mPlayerView.showImageView.image = image;
        }
    });
    CGImageRelease(videoImage);
}

#pragma mark -- /*画面布局调整*/
- (void)updatePlayViewRate:(CGFloat)tempRate
{
    /*设置横竖屏*/
    if (tempRate > 1) {/*横屏*/
        [self setDeviceOrientation:(UIDeviceOrientationLandscapeRight)];
        [mPlayerView setLanMas_makeWithImageRate:tempRate isOpenVirtual:YES isUsageMode:NO];
    }else{/*竖屏*/
        [self setDeviceOrientation:(UIDeviceOrientationPortrait)];
        [mPlayerView setPoMas_makeWithImageRate:tempRate isOpenVirtual:YES isUsageMode:NO];
    }
}
#pragma mark------------------------------------------------------------------------------------------------------------------
#pragma mark-提示 loading 相关
#pragma mark-添加带有文字loading
- (void)addLoadingWithTipsView:(NSString *)tipsStr
{
    if (loadingWithTipsView)
    {
        [loadingWithTipsView removeFromSuperview];
        loadingWithTipsView = nil;
    }
    loadingWithTipsView = [self loadingViewWithTipsStr:tipsStr];
    
    [self.view addSubview:loadingWithTipsView];
}

- (void)removeLoadingWithTipsView
{
    if (loadingWithTipsView)
    {
        [loadingWithTipsView removeFromSuperview];
        loadingWithTipsView = nil;
    }
}

- (UIView *)loadingViewWithTipsStr:(NSString*)tipsStr
{
    UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, SCREEN_H)];
    [bgView setBackgroundColor:RGBACOLOR(0, 0, 0, 0.5)];
    
    FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"loadingWhiteGif" withExtension:@"gif"]]];
    
    FLAnimatedImageView  *upView =  [[FLAnimatedImageView alloc] init];
    [upView setFrame:CGRectMake((SCREEN_W - 65.f)/2.f, (SCREEN_H - 65.f)/2.f, 65.f, 65.f)];
    [upView setContentMode:UIViewContentModeScaleAspectFill];
    [upView setBackgroundColor:[ UIColor clearColor]];
    upView.animatedImage = image;
    [bgView addSubview:upView];
    
    /*标签文字*/
    UILabel *tipsLabel = [[UILabel alloc] initWithFrame:CGRectMake((SCREEN_W - 100.f)/2.f, (SCREEN_H - 65.f)/2.f + 65.f + 10.f, 100.f*AUTOSCALE, 20.f)];
    [tipsLabel setText:tipsStr];
    [tipsLabel setBackgroundColor:[UIColor clearColor]];
    [tipsLabel setTextColor:[UIColor whiteColor]];
    [tipsLabel setFont:[UIFont systemFontOfSize:14.f]];
    [tipsLabel setTextAlignment:(NSTextAlignmentCenter)];
    
    [bgView addSubview:tipsLabel];
    
    return bgView;
}

#pragma mark-添加loading
-(void)showNewIndicator
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (self->wattingView == nil)
        {
            HLog(@"Tan +++++开");
            self->wattingView =  [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
            [self->wattingView setBackgroundColor:RGBACOLOR(0.f, 0.f, 0.f, 0.7)];
            [self->wattingView.layer setCornerRadius:10.f];
            self->wattingView.center = [[UIApplication sharedApplication] keyWindow].center;// 将wattingVideoImageindicator放于播放画面的中央位置
            self->wattingView.hidden = NO;
            
            FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"loadingWhiteGif" withExtension:@"gif"]]];
            
              FLAnimatedImageView  *upView =  [[FLAnimatedImageView alloc] init];
              [upView setFrame:CGRectMake((100 - 65.f)/2.f, (100 - 65.f)/2.f, 65.f, 65.f)];
              [upView setContentMode:UIViewContentModeScaleAspectFill];
              [upView setBackgroundColor:[ UIColor clearColor]];
              upView.animatedImage = image;
              [self->wattingView addSubview:upView];

            [self->mPlayerView addSubview:self->wattingView];
        }
    });
}

-(void)removeNewIndicator
{
    if (self->wattingView != nil)
    {
        [[self->wattingView viewWithTag:1111].layer removeAllAnimations];
        
        self->wattingView.hidden = YES;
        [self->wattingView removeFromSuperview];
        self->wattingView = nil;
    }
}

#pragma mark 定时器
- (void)setTimerCountDown {
    HLog(@"开启一个");
    
    if (_timer) {
        // 取消定时器
        [self cancelTimer];
    }
    
    // 初始化值计时数据
    self.adjustTime = 3;
    self.concentTime = [iTools getNowTimeStamp];
    self.currentTime = 0;
    
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerChange) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}

- (void)cancelTimer {
    // 取消定时器
    [_timer invalidate];
    _timer = nil;
}

- (void)timerChange {
    
    self.currentTime++;// 0、定时器计数
    
    [self extensionAdjustBtnFrameCheckAdjustTime];// 1、悬浮球3s后 自动靠边隐藏
    
    
    [self checkConcentTime];// 3、30s之后 没有收到拉流数据 自动断开链接
}

// 3、30s之后 没有收到拉流数据 自动断开链接
- (void)checkConcentTime {
    
    NSInteger now      = [iTools getNowTimeStamp];
    NSInteger timeDiff = now - self.concentTime; // 渲染时间与当前时间 时间差

    if (self.concentTime == 0) { //云手机未连接成功
        HLog(@"云手机未连接成功");
    }else if (timeDiff >= 30) { // 30s 无渲染数据
        
        if(!_needToDissconnectType && !_isLoginAgainType && [self isPlayerViewIsTopVCFun]){
             HLog(@"云手机30s 无渲染数据 自动断开连接");
             self.concentTime = [iTools getNowTimeStamp];
             
             [self showNewIndicator];
             [self tryAgain];
        }
       
        
        /*弹窗提示*/
    }else {
//        HLog(@"云手机渲染数据时间差：%zd", timeDiff);
    }
}



#pragma mark - 提示框
- (void)showAlertWithTitle:(NSAttributedString*_Nullable)atbTitle
                   message:(NSAttributedString*_Nullable)atbmessage
            tilteAlignment:(NSTextAlignment)tilteAlignment
          messageAlignment:(NSTextAlignment)messageAlignment
                sureAction:(UIAlertAction*_Nullable)sureAction
              cancelAction:(UIAlertAction*_Nullable)cancelAction
{
    // 当前控制器是UIAlertController 退出
    UIViewController *currentVC = [[ShortcutManager shareInstance] findCurrentShowingViewController];
    if ([currentVC isKindOfClass:[UIAlertController class]]) {
        
        //获得极致体验服务 请购买云手机（不退出 优先级最高）
        UIAlertController *alertVC = (UIAlertController *)currentVC;
        NSMutableAttributedString *attriMsg = [alertVC valueForKey:@"_attributedMessage"];
        if ([attriMsg.string containsString:@"获得极致体验服务"]) {
            return;
        }
        HLog(@"%@",attriMsg.string);
        [currentVC dismissViewControllerAnimated:NO completion:nil];
    }
    
    self.alertController = [UIAlertController alertControllerWithTitle:@"" message:@"" preferredStyle:UIAlertControllerStyleAlert];

    if (atbTitle)
    {
        [self.alertController setValue:atbTitle forKey:@"_attributedTitle"];
    }
    
    if (atbmessage)
    {
        [self.alertController setValue:atbmessage forKey:@"_attributedMessage"];
    }
    
    UIView *subView1 = self.alertController.view.subviews[0];
    if (subView1 && [subView1 subviews])
    {
        UIView *subView2 = subView1.subviews[0];
        if (subView2 && [subView2 subviews])
        {
            UIView *subView3 = subView2.subviews[0];
            if (subView3 && [subView3 subviews])
            {
                UIView *subView4 = subView3.subviews[0];
                if (subView4 && [subView4 subviews])
                {
                    UIView *subView5 = subView4.subviews[0];
                    if (subView5 && [[subView5 subviews] count] > 1)
                    {
                        for (UIView *msg in subView5.subviews)
                        {
                            if ([msg isKindOfClass:[UILabel class]])
                            {
                                NSArray *trmp = [self getAllIvar:msg];
                                
                                for (NSDictionary *dict in trmp)
                                {
                                    if ([[dict allKeys] containsObject:@"_content"])
                                    {
                                        NSAttributedString *dsfds = [dict objectForKey:@"_content"];
                                        if ([atbTitle.string isEqualToString:dsfds.string])
                                        {
                                            [(UILabel*)msg setTextAlignment:(tilteAlignment)];
                                        }
                                        else if ([atbmessage.string isEqualToString:dsfds.string])
                                        {
                                            if (((UILabel*)msg).numberOfLines == 0)
                                            {
                                                [(UILabel*)msg setTextAlignment:(messageAlignment)];
                                            }
                                            else if (((UILabel*)msg).numberOfLines == 1)
                                            {
                                                [(UILabel*)msg setTextAlignment:NSTextAlignmentCenter];
                                            }
                                            else
                                            {
                                                [(UILabel*)msg setTextAlignment:(NSTextAlignmentCenter)];
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    if (sureAction)
    {
        [self.alertController addAction:sureAction];
    }
    
    if (cancelAction)
    {
        [self.alertController addAction:cancelAction];
    }
    
    // 弹窗边框
    UIView *subview = self.alertController.view.subviews.firstObject;
    UIView *alertContentView = subview.subviews.firstObject;
    alertContentView.layer.cornerRadius = 10;
//                alertContentView.layer.masksToBounds = YES;
    alertContentView.layer.shadowColor = [UIColor colorWithRed:30/255.0 green:32/255.0 blue:34/255.0 alpha:1.0].CGColor;
    alertContentView.layer.shadowOffset = CGSizeMake(0,0);
    alertContentView.layer.shadowOpacity = 1;
    alertContentView.layer.shadowRadius = 7;
    // 弹窗背景颜色
    if (@available(iOS 13.0, *)) {
        self.alertController.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
    }
    
    [self presentViewController:self.alertController animated:YES completion:nil];

}


#pragma  mark - 屏幕旋转相关
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

- (BOOL)shouldAutorotate {
    if (canRate)/*画面发现变化 状态变为YES*/
    {
        canRate = NO;/*关键点 只能旋转一次*/
        
        return YES;
    }
    
    //是否允许转屏
    return NO;/*平时禁止*/
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return
    UIInterfaceOrientationMaskPortrait |
    UIInterfaceOrientationMaskLandscapeLeft |
    UIInterfaceOrientationMaskLandscapeRight;
}


#pragma mark -- /*  屏幕旋转通知接收函数*/
- (void)orientationChanged:(NSNotification *)notification
{
    KyoLog(@"rotated");
}

- (void)setDeviceOrientation:(UIDeviceOrientation)orientationPortrait
{
    mainBlock(^{
        UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
        //isPortraitMode
        BOOL ScreenMode = ((UIDeviceOrientation)orientation == orientationPortrait);
        
        NSNumber *value = nil;
        if (ScreenMode)
        {
        }
        else
        {
            self.adjustTime = 3;
            if (orientationPortrait == UIDeviceOrientationLandscapeLeft){
                [self->mPlayerView setLanMas_makeWithImageRate:16.0/9.0 isOpenVirtual:YES isUsageMode:NO];
//                [self.basebgView mas_remakeConstraints:^(MASConstraintMaker *make) {
//                    make.left.mas_equalTo(0);
//                    make.right.mas_equalTo(0);
//                    make.top.mas_equalTo(0);
//                    make.bottom.mas_equalTo(0);
//                }];
                /*悬浮按钮旋转*/
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [self reSetPlayerViewFloatBtnFrame];
                });
                
                [self->mPlayerView.controlBtn setHidden:NO];
                
            }else{
                    [self->mPlayerView setPoMas_makeWithImageRate:9.0/16.0 isOpenVirtual:YES isUsageMode:NO];
//                    [self.basebgView mas_remakeConstraints:^(MASConstraintMaker *make) {
//                        make.left.mas_equalTo(0);
//                        make.right.mas_equalTo(0);
//                        make.top.mas_equalTo(0);
//                        make.bottom.mas_equalTo(0);
//                    }];
            }

            self->canRate = YES;/*关键点  设置临时允许*/
            value = [NSNumber numberWithInteger:orientationPortrait];//横竖屏值设置
            [[UIDevice currentDevice] setValue:value forKey:@"orientation"];/*先将状态栏旋转(影响系统通知弹框方向)*/
            [[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceOrientationDidChangeNotification object:nil];/*发送通知*/
        }
    });
}


/*切换连接方式*/
- (void)connectTypeChange{
    [self reconnectDevice];
}

#pragma mark - UITextFieldDelegate 透传输入法委托
//- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
//
//    /*长度为0时表示删除内容*/
//    if (string.length > 0){
//        NSString *replaceStr = [textField.text substringWithRange:range];
//        HLog(@"\n000000要增加的文字:--%@-------",replaceStr);
//        replaceStr = [replaceStr stringByReplacingOccurrencesOfString:@" " withString:@""];
//        HLog(@"\n111111要增加的文字:--%@-------",replaceStr);
//        for (NSInteger nFori = 0; nFori < replaceStr.length; nFori++) {
//            NSString *dataStr = [RCCommandHelp commandKeyboadInputStr:nil];
//            [self.businessCommandChannelManager rc_sendData:dataStr];
//        }
//        HLog(@"\n-----输入内容:--%@-------",string);
//        NSString *dataStr = [RCCommandHelp commandKeyboadInputStr:string];
//        [self.businessCommandChannelManager rc_sendData:dataStr];
//    }
//    else{
//        HLog(@"\n-----删除:--%ld-------",range.length);
//        NSInteger needDeleteLength = range.length;
//        for (NSInteger nFori = 0; nFori < needDeleteLength; nFori++) {
//            NSString *dataStr = [RCCommandHelp commandKeyboadInputStr:nil];
//            [self.businessCommandChannelManager rc_sendData:dataStr];
//
//            /*初始内容无法删除问题处理*/
//            hidenTextField.text  = @"1234";
//            hidenTextFieldOldStr = @"1234";
//
//            /*如果两者内容差距较大 是否会有删除后出现两者内容不一样的情况*/
//            if (![hidenTextField.text isEqualToString:hidenTextFieldOldStr]){
//                /*两者不相等时需要做等值处理*/
//                hidenTextFieldOldStr = hidenTextField.text;
//            }
//        }
//    }
//
//    return YES;
//}

- (void)textFieldDidEndEditing:(UITextField *)textField{
    HLog(@"\n-----输入法透传 1111111 关闭键盘-------");
    NSString *dataStr = [RCCommandHelp commandClosePhoneKeyboad];
    [self.businessCommandChannelManager rc_sendData:dataStr];
}

-(BOOL)prefersHomeIndicatorAutoHidden {
    return YES;
}


@end
