代码改变世界

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(四)example代码解析

2015-12-28 10:53  Ansersion  阅读(4598)  评论(0编辑  收藏  举报

--------------------更新2018.08.20-------------------

添加http_tunnel_example.cpp作为RtspOverHttp示例程序。

--------------------更新2018.08.20结束-------------------

 

一、example逻辑伪码

myRTSPClient附带3个example程序:simple_example、complete_example、common_example。后两个example都是从simple_example中衍生出来的,以下将以simple_example为主进行解析,并且会在最后说明一下另两个example与simple_example的差别。

以下是simple_example简化后的伪代码,以便理解:

1. main():

2.   myRtspClient Client;

3.   Client.SetURI("rtsp://127.0.0.1/ansersion");

4.   Client.SendDESCRIBE();

5.   Client.SendSETUP();

6.   Client.SendPLAY();

7.   Write 1000 RTP Data to file "test_packet_recv.h264";

8.   Client.SendTEARDOWN();

9.   return;

 

二、simple_example.cpp代码注释

 1 #include <iostream>
 2 #include "rtspClient.h"
 3 #include <stdio.h>
 4 #include <sys/types.h>
 5 #include <sys/stat.h>
 6 #include <unistd.h>
 7 #include <fcntl.h>
 8 
 9 using std::cout;
10 using std::endl;
11 
12 int main(int argc, char *argv[])
13 {
14         string RtspUri("rtsp://127.0.0.1/ansersion");
15         // string RtspUri("rtsp://192.168.81.145/ansersion");
16         RtspClient Client;
17 
18         /* Set up rtsp server resource URI */
19         Client.SetURI(RtspUri);
20 
21         /* Send DESCRIBE command to server */
22         Client.DoDESCRIBE();
23 
24         /* Parse SDP message after sending DESCRIBE command */
25         Client.ParseSDP(); // 解析RTSP服务端受理DESCRIBE命令后返回的SDP信息
26 
27         /* Send SETUP command to set up all 'audio' and 'video' 
28          * sessions which SDP refers. */
29         Client.DoSETUP();
30         
31         printf("start PLAY\n");
32         printf("SDP: %s\n", Client.GetSDP().c_str());
33 
34         /* Send PLAY command to play only the 
35          * 'video' sessions.*/
36         Client.DoPLAY("video");
37 
38         /* Receive 1000 RTP 'video' packets
39          * note(FIXME): 
40          * if there are several 'video' session 
41          * refered in SDP, only receive packets of the first 
42          * 'video' session, the same as 'audio'.*/
43         int packet_num = 0;
44         uint8_t buf[65534];
45         size_t size = 0;
46 
47         /* Write h264 video data to file "test_packet_recv.h264" 
48          * Then it could be played by ffplay */
49         int fd = open("test_packet_recv.h264", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR);
50         if(Client.GetSPSNalu(buf, &size)) { // 解码SDP中关于H264的SPS的数据
51                 if(write(fd, buf, size) < 0) { // 将SPS写入文件
52                         perror("write");
53                 }
54         } else {
55                 printf("SPS error\n");
56         }
57 
58         if(Client.GetPPSNalu(buf, &size)) { // 解码SDP中关于H264的PPS的数据
59                 if(write(fd, buf, size) < 0) { // 将PPS写入文件
60                         perror("write");
61                 }
62         } else {
63                 printf("PPS error\n");
64         }
65 
66         while(++packet_num < 1000) { // 接收1000个H264的数据包(确切的说是1000个NALU)
67                 if(!Client.GetMediaData("video", buf, &size)) continue;
68                 if(write(fd, buf, size) < 0) {
69                         perror("write");
70                 }
71                 printf("recv %lu\n", size);
72         }
73 
74         printf("start TEARDOWN\n");
75         /* Send TEARDOWN command to teardown all of the sessions */
76         Client.DoTEARDOWN();
77 
78         return 0;
79 }
80                               

 

三、common_example.cpp和complete_example.cpp

common_example.cpp不同于simple_example.cpp的地方只有开头几行,这些代码是为了可以用参数指定RTSP URI。

 1 int main(int argc, char *argv[])
 2 {
 3         if(argc != 2) {
 4                 cout << "Usage: " << argv[0] << " <URL>" << endl;
 5                 cout << "For example: " << endl;
 6                 cout << argv[0] << " rtsp://127.0.0.1/ansersion" << endl;
 7                 return 1;
 8         }
 9         cout << "Start play " << argv[1] << endl;
10         cout << "Then put video data into test_packet_recv.h264" << endl;
11         string RtspUri(argv[1]);
12         // string RtspUri("rtsp://192.168.81.145/ansersion");
13         RtspClient Client;
14 
15         /* Set up rtsp server resource URI */
16         Client.SetURI(RtspUri);
17         ......
18         return 0;
19 }

 

complete_example.cpp不同于simple_example.cpp的地方,就在于每次发送RTSP命令时, 它都会检查命令发送是否成功,并且检验返回信息是否是“200 OK”。

 1 int main(int argc, char * argv[])
 2 {
 3         ......      
 4          /* Send DESCRIBE command to server */
 5         if(Client.DoDESCRIBE() != RTSP_NO_ERROR) {
 6                 printf("DoDESCRIBE error\n");
 7                 return 0;
 8         }
 9         printf("%s\n", Client.GetResponse().c_str());
10         /* Check whether server return '200'(OK) */
11         if(!Client.IsResponse_200_OK()) {
12                 printf("DoDESCRIBE error\n");
13                 return 0;
14         }
15         ......
16         return 0;
17 }

 

OK!以上便是myRTSP的基础内容。

 

上一篇              回目录