美文网首页iOS Developer
谈谈iOS 手机操控电视盒子

谈谈iOS 手机操控电视盒子

作者: 爆裂少女小鸭子 | 来源:发表于2016-10-22 15:02 被阅读0次

    项目要求:手机的遥控器界面,通过UDP/TCP协议制定的指令,连接电视盒子,操控电视进行换台,播放,暂停,调整声音的操作,同时实现小屏投大屏,即手机播放的视频可以投到电视上播放。

    做项目之前,我们需要知道

    1、如何在oc中使用UDP/TCP协议,他们是什么

    2、UDP/TCP指令是什么

    3、我们要如何使手机和电视盒子连接

    解决问题一:Socket 

    网络七层由下往上分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。http协议对应于应用层,tcp协议对应于传输层,ip协议对应于网络层,三者本质上没有可比性。  何况HTTP协议是基于TCP连接的。TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。

    我们在传输数据时,可以只使用传输层(TCP/IP),但是那样的话,由于没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用应用层 协议,应用层协议很多,有HTTP、FTP、TELNET等等,也可以自己定义应用层协议。WEB使用HTTP作传输层协议,以封装HTTP文本信息,然 后使用TCP/IP做传输层协议将它发送到网络上。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过套接字Socket我们才能使用TCP/IP协议。(当然关于UDP/TCP区别什么的大家应该也都了解了 这里就不赘述了么么哒)

    解决问题二 指令?

    所谓的指令这里也就是电视盒子端的开发人员,制定好的一种规则,例如按住遥控器的“上箭头”,可能会规定指令是“1”,只要接收到我们客户端发送“1”(当然要编码的,稍后会说哦),盒子就会执行“向上”的行为(可能是换台)。

    命令

    0x11111111 (app傳送操作命令)

    格式: 0x11111111 + {int cmd} (操作命令)

    操作命令 1:POW OFF 2:HOME 3:MUTE 4:MENU 5:RETURN 6:VOL_UP 7:VOL_DOWN 8:ARR_UP 9:ARR_DOWN 10:ARR_RIGHT 11:ARR_LEFT 12:BUT_OK

    解决问题3  建立socket连接

    建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。

    套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

    服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

    客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

    连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户 端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

    上面的可能太官方了,说白了,你需要有以下的步骤来使客户端和盒子(服务器)建立连接。

    1、首先你需要发送广播,来找谁是盒子

    2、找到以后,服务器会返回给你,它自己的ip和端口号

    3、以后你发的指令,就往这个ip和端口号发送就好啦

    那么废话不多说上代码,因为我做的项目是遵循UDP协议的,所以代码是基于UDP写的,关于Sorket这里有一个封装好的类库GCDAsyncUdpSocket,下载地址如下http://download.csdn.net/download/xiaoamani/7455735(如果你不能下载也可百度搜索,GitHub上也有但是是demo,不是只是类库,当然你也可以和我要哈)

    代码代码代码

    -(void)createClientUdpSocket

    {

    dispatch_queue_tdQueue =dispatch_get_global_queue(0,0);

    //1.创建一个udp socket用来和服务器端进行通讯

    sendUdpSocket= [[GCDAsyncUdpSocketalloc]initWithDelegate:selfdelegateQueue:dQueuesocketQueue:nil];

    //2.banding一个端口(可选),如果不绑定端口,那么就会随机产生一个随机的电脑唯一的端口

    //端口数字范围(1024,2^16-1)

    [sendUdpSocketbindToPort:8085error:nil];

    [sendUdpSocketenableBroadcast:YESerror:nil];

    //3.等待接收对方的消息

    [sendUdpSocketreceiveOnce:nil];

    }

    - (void) sendMsg {

    intcommNum =0x55f03651;

    NSMutableData*myData = [[NSMutableDataalloc]init];

    [myDataappendBytes:&commNumlength:sizeof(commNum)];

    NSString*host =@"255.255.255.255"; //发送广播

    uint16_tport =49555;//规定的端口号

    //开始发送

    //改函数只是启动一次发送它本身不进行数据的发送,而是让后台的线程慢慢的发送也就是说这个函数调用完成后,数据并没有立刻发送,异步发送

    [sendUdpSocketsendData:myData toHost:hostport:port withTimeout:1tag:100];

    }

    #pragma mark -GCDAsyncUdpSocketDelegate

    -(void)udpSocket:(GCDAsyncUdpSocket*)sock didSendDataWithTag:(long)tag{

    if(tag ==100) {

    NSLog(@"表示标记为100的数据发送完成了");

    }

    }

    -(void)udpSocket:(GCDAsyncUdpSocket*)sock didNotSendDataWithTag:(long)tag dueToError:(NSError*)error{

    NSLog(@"标记为tag %ld的发送失败失败原因%@",tag, error);

    }

    //接受盒子服务器的返回端口号和ip以及一些数据

    -(void)udpSocket:(GCDAsyncUdpSocket*)sock didReceiveData:(NSData*)data fromAddress:(NSData*)address withFilterContext:(id)filterContext{

    NSString*ip = [GCDAsyncUdpSockethostFromAddress:address];

    uint16_tport = [GCDAsyncUdpSocketportFromAddress:address];

    //继续来等待接收下一次消息

    _ipNum= ip;

    _myPort= port;

    [sockreceiveOnce:nil];

    //dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    //[self sendBackToHost:ip port:port withMessage:s];

    //});

    }

    //开始向接收到的ip和端口号发送指令myIpum

    - (void) sendMsgTime :(NSString*)myIpum andPort:(uint16_t)myPort andUid:(NSString*)myUid{

    intcommNumber =0x11111111;

    NSMutableData*myDa = [[NSMutableDataalloc]init];

    [myDaappendBytes:&commNumberlength:sizeof(commNumber)];

    NSString*host = myIpum;

    uint16_tport = myPort;

    _romeId= myUid;

    //开始发送

    //改函数只是启动一次发送它本身不进行数据的发送,而是让后台的线程慢慢的发送也就是说这个函数调用完成后,数据并没有立刻发送,异步发送

    [sendUdpSocketsendData:myDatoHost:hostport:portwithTimeout:1tag:100];

    }

    ok截至到这里  大家就应该明白了如何接受服务器的数据,和发送指令。那么投屏的,道理一样,只是需要发送指令的时候,把点播视频url编码后也发送过去,直播的videoId也发送过去(至于编码我会在研究,写一篇文章,欢迎大家到时候看看指点)当然每个项目的规定不一样,我这不是一定的,只是思路大家明白就好。这是我的第一篇文章,可能会有许多的不足,希望大家指正,哈哈哈,我今年刚毕业,10月份之前公司有点变故辞职了,现在找工作几乎没面试,很多人劝我转行,说我没经验,iOS已经发展不好了,可是我觉得,如果有技术能钻研,就算不发展的那一天,我也觉得我没白学iOS,因为我得到了那份满足感,开发的满足感,我享受打码。

    相关文章

      网友评论

        本文标题:谈谈iOS 手机操控电视盒子

        本文链接:https://www.haomeiwen.com/subject/hagcuttx.html