iOS 使用socket 实现rtsp +rtp 协议

http://bbs.rosoo.net/blog-24408-8658.html



大家好:这是我写的流媒体客户端的实现,rtsp 是用tcp 实现的,rtp接收数据流 是用udp 实现的,rstp 部分沟通是ok 的,rtp 接收数据流也可以接收,但是每次接收数据流只能接收到2_4个包。我仔细研究过这几个包,刚好是一个完整一张图片。
请各位大侠帮忙看看,多多指导。

- (void)viewDidLoad

{

    [super viewDidLoad];

    

    Info = [[NSString allocinit];

    getport = 0;

    

    socket = [[AsyncSocket allocinitWithDelegate:self];

    NSError *error = nil;

    if(!([socket connectToHost:SERVERADDR onPort:SERVERPORT error:&error]))

    {

        NSLog(@"error:%@",error);

    }

    else 

    {

        isRtp = 0;

    }

    

    socketudp = [[AsyncUdpSocket allocinitWithDelegate:self];

}


/*

*建立连接,返回服务器对OPTIONS请求的响应

*/

-(NSMutableString*)getOptions

 {

    NSMutableString* options = [[[NSMutableString allocinitautorelease];

    

    [options appendFormat:@"OPTIONS rtsp://%@/v1 RTSP/1.0%@",SERVERADDR,KENTER];

    [options appendFormat:@"CSeq: 2%@",KENTER];

    [options appendFormat:@"User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)%@%@",KENTER,KENTER];

     NSLog(@"options = %@",options);

    [socket writeData:[options dataUsingEncoding:NSUTF8StringEncodingwithTimeout:3 tag:1];

    NSMutableString* readString = [[[NSMutableString allocinitautorelease];

    [socket readDataWithTimeout:3 tag:1];

     

    return readString;

}


/*

*建立连接,返回服务器对DESCRIBE请求的响应

*/

-(NSMutableString*)getDescribe

{

    NSMutableString* describe = [[[NSMutableString allocinitautorelease];


    [describe appendFormat:@"DESCRIBE rtsp://%@/v1 RTSP/1.0%@",SERVERADDR,KENTER];

    [describe appendFormat:@"CSeq: 3%@",KENTER];

    [describe appendFormat:@"User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)%@",KENTER];

    [describe appendFormat:@"Accept: application/sdp%@%@",KENTER,KENTER];

   // [describe appendFormat:@"Authorization: Basic YWRtaW4=%@",KENTER];

     NSLog(@"describe = %@",describe);

    [socket writeData:[describe dataUsingEncoding:NSUTF8StringEncodingwithTimeout:3 tag:1];

    NSMutableString* readString = [[[NSMutableString allocinitautorelease];

    [socket readDataWithTimeout:3 tag:2];

    return readString;

}

/*

*建立连接,返回通过udp连接服务器对SETUP请求的响应

*/

-(NSMutableString*)getUdpSetup

 {

   NSMutableString* udpsetup = [[[NSMutableString allocinitautorelease];

     

   [udpsetup appendFormat:@"SETUP rtsp://%@/v1/track0 RTSP/1.0%@",SERVERADDR,KENTER];

   [udpsetup appendFormat:@"CSeq: 4%@",KENTER];

   [udpsetup appendFormat:@"User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)%@",KENTER];

   [udpsetup appendFormat:@"Transport: RTP/AVP;unicast;client_port=49664-49665%@%@",KENTER,KENTER];

     

    NSLog(@"udpsetup = %@",udpsetup);

   [socket writeData:[udpsetup dataUsingEncoding:NSUTF8StringEncodingwithTimeout:3 tag:1];

   NSMutableString* readString = [[[NSMutableString allocinitautorelease];

   [socket readDataWithTimeout:3 tag:3]; 

    return readString;

}

/*

*建立连接,返回向服务器对PLAY请求的响应

*/

-(NSMutableString*)getPlay:(NSString*)session

{

     NSMutableString* play = [[[NSMutableString allocinitautorelease];

   

    [play appendFormat:@"PLAY rtsp://%@/v1 RTSP/1.0%@",SERVERADDR,KENTER];

    [play appendFormat:@"CSeq: 6%@",KENTER];

    [play appendFormat:@"User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)%@",KENTER];

    [play appendFormat:@"Session:%@%@",session,KENTER];

    [play appendFormat:@"Range: npt=0.000-%@%@",KENTER,KENTER];

    // [Info  release];

     NSLog(@"play = %@",play);

    [socket writeData:[play dataUsingEncoding:NSUTF8StringEncodingwithTimeout:3 tag:1];

    NSMutableString* readString = [[[NSMutableString allocinitautorelease];

   [socket readDataWithTimeout:3 tag:4]; 

    

    return readString;

}

-(void)RecvUDPData

{

  //  severs_port = [self getPort:Info];

  //  NSLog(@"severs_port = %d",severs_port);

    NSError * error1 = nil;

    [socketudp bindToPort:49664 error:nil];

    if(error1)

    {

        NSLog(@"error1:%@",error1);  

    }

    NSLog(@"start udp server");

    

 //   if ([socketudp connectToHost:SERVERADDR onPort:severs_port error:nil]) 

    {

        [socketudp receiveWithTimeout:-1 tag:0];//将不断接受摄像头发送的数据

    }

}

/*

*过主机名和端口号连接服务器

*/

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port

{

   NSLog(@"onSocket:%p didConnectToHost:%@ port:%hu", sock, host, port);

    if(isRtp == 0)

    {

       [self getOptions]; 

    }

    else 

    {

         NSLog(@"start tcp server");

       [rtpTcp readDataWithTimeout:-1 tag:5]; 

    }

}

/*

*向内存中写入数据

*/

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

{

     NSString *message;

     switch (tag)

    {

             

        case 1:

        {

            NSLog(@"getOptions:did read data");

            message = [[NSString allocinitWithData:data encoding:NSUTF8StringEncoding];

            if([[message substringToIndex:15isEqualToString:@"RTSP/1.0 200 OK"])

            {

              //  NSLog(@"message is: \n%@",message);

                [message release];

                [self getDescribe];

            }

            else 

            {

             //  NSLog(@"message is: \n%@",message);

                [message release];

                return;

            }

            

        }

            break;

            

        case 2:

        {

            NSLog(@"getDescribe:did read data");

            message = [[NSString allocinitWithData:data encoding:NSUTF8StringEncoding];

            if([[message substringToIndex:15isEqualToString:@"RTSP/1.0 200 OK"])

            {

               // NSLog(@"message is: \n%@",message);

                [message release];

                [self getUdpSetup];

            }

            else 

            {

               // NSLog(@"message is: \n%@",message);

                [message release];

                return;

            }

            

        }

            break

             

        case 3:

        {

            NSLog(@"getUdpSetup:did read data");

            message = [[NSString allocinitWithData:data encoding:NSUTF8StringEncoding];

            if([[message substringToIndex:15isEqualToString:@"RTSP/1.0 200 OK"])

            {

               // NSLog(@"message is: \n%@",message);

                Info = message;

             //   NSLog(@"Info = %@",Info);

                NSString* session = [self getSession:Info];

                [self getPlay:session];

                

            }

            else 

            {

              //  NSLog(@"message is: \n%@",message);

                [message release];

                return;

            }

            

        }

            break

            

        case 4:

        {

            NSLog(@"getPlay:did read data");

            message = [[NSString allocinitWithData:data encoding:NSUTF8StringEncoding];

            if([[message substringToIndex:15isEqualToString:@"RTSP/1.0 200 OK"])

            {

                NSLog(@"message is: \n%@",message);

                [message release];

                [self RecvUDPData];

            }

            else 

            {

               //  NSLog(@"message is: \n%@",message);

                [message release];

                return;

            }

            

        }

            break

       

        /*    

        case 5:

         {

            NSLog(@"getTeardown:did read data");

            message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

            NSLog(@"message is: \n%@",message);

         }

            break; 

         */

            

        default:

            break;

        }


- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port

{

    NSLog(@"start rece rtp by udp");

    NSLog(@"length = %d ",[data length]);

      Byte *testByte = (Byte *)[data bytes];

    for(char i=12;i<[data length];i++)

    {

         printf("%02x",testByte[i]);

    }

    [socketudp receiveWithTimeout:-1 tag:0]; 

    

    return YES

- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotReceiveDataWithTag:(long)tag dueToError:(NSError *)error

{

    NSLog(@"UDP is missing");

    [socketudp release];

    

    socketudp = [[AsyncUdpSocket allocinitWithDelegate:self];

    [socketudp bindToPort:49664 error:nil];

    [socketudp enableBroadcast:YES error:nil];//设置为广播

    [socketudp receiveWithTimeout:-1 tag:0];//将不断接受摄像头发送的数据

}


@end


下面附上我的调试信息:

2012-08-22 19:28:04.619 TcpWebcanShow[6909:f803] 

onSocket:0x6c23e30 didConnectToHost:192.168.8.37 port:554

2012-08-22 19:28:04.620 TcpWebcanShow[6909:f803] options = 



OPTIONS rtsp://192.168.8.37/v1 RTSP/1.0

CSeq: 2

User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)


2012-08-22 19:28:04.628 TcpWebcanShow[6909:f803] getOptions:did read data

2012-08-22 19:28:04.629 TcpWebcanShow[6909:f803] message is: 



RTSP/1.0 200 OK

CSeq: 2

Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, CMD


2012-08-22 19:28:04.629 TcpWebcanShow[6909:f803] describe = 



DESCRIBE rtsp://192.168.8.37/v1 RTSP/1.0

CSeq: 3

User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)

Accept: application/sdp


2012-08-22 19:28:04.632 TcpWebcanShow[6909:f803] getDescribe:did read data

2012-08-22 19:28:04.633 TcpWebcanShow[6909:f803] message is: 



RTSP/1.0 200 OK

CSeq: 3

Date: Date: Tue, Aug 21 2012 19:22:20 GMT+0800

Content-Base: rtsp://192.168.8.37/v1/

Content-Type: application/sdp

Content-Length: 465


v=0

o=- 1 1 IN IP4 127.0.0.1

s=v1

i=Live

t=0 0

a=tool:Sunamper Live Media Streamer

a=type:broadcast

a=control:*

a=range:npt=0-

a=x-qt-text-nam:v1

a=x-qt-text-inf:Live

c=IN IP4 0.0.0.0

a=x-xframerate:20

m=video 0 RTP/AVP 96

a=rtpmap:96 H264/90000

a=fmtp:96 packetization-mode=1;profile-level-id=000001;sprop-parameter-sets=Z0IAKOkBaHsg,aM4xUg==

a=control:track0

m=audio 0 RTP/AVP 97

a=rtpmap:97 AMR/8000

a=fmtp:97 octet-align=1

a=control:track1

2012-08-22 19:28:04.633 TcpWebcanShow[6909:f803] udpsetup = 


SETUP rtsp://192.168.8.37/v1/track0 RTSP/1.0

CSeq: 4

User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)

Transport: RTP/AVP;unicast;client_port=49664-49665


2012-08-22 19:28:04.639 TcpWebcanShow[6909:f803] getUdpSetup:did read data

2012-08-22 19:28:04.640 TcpWebcanShow[6909:f803] message is: 



RTSP/1.0 200 OK

CSeq: 4

Date: Date: Tue, Aug 21 2012 19:22:20 GMT+0800

Transport: RTP/AVP;unicast;distination=192.168.8.204;source=192.168.8.37;client_port=49664-49665;server_port=57208-57209

Session: 4CD08825B705749A93351455111778


2012-08-22 19:28:04.641 TcpWebcanShow[6909:f803] play = 



PLAY rtsp://192.168.8.37/v1 RTSP/1.0

CSeq: 6

User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)

Session:4CD08825B705749A93351455111778

Range: npt=0.000-


2012-08-22 19:28:04.644 TcpWebcanShow[6909:f803] getPlay:did read data

2012-08-22 19:28:04.644 TcpWebcanShow[6909:f803] message is: 



RTSP/1.0 200 OK

CSeq: 6

Date: Date: Tue, Aug 21 2012 19:22:20 GMT+0800

Session: 4CD08825B705749A93351455111778

Range: npt=0.000-

RTP-Info: url=rtsp://192.168.8.37/v1/track0;seq=53324;rtptime=629723212


2012-08-22 19:28:04.645 TcpWebcanShow[6909:f803] start udp server

2012-08-22 19:28:04.666 TcpWebcanShow[6909:f803] start rece rtp by udp

2012-08-22 19:28:04.667 TcpWebcanShow[6909:f803] length = 1028 

419a660a6301bf824e047bc7f9eff572f8032b6bbbdbe239700afec0dd37cdcbc3bfbf2f848d8ef049e1338bd3a8679b802bbfe5efbe978279019848e5eb9d1430780f57c47e4108f34660c0f1df93848c319ae7aa6d7fe4f006de5b3e762ebd7c54059acd92fbac3f07e0cbfc9d873c2734aef2


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值