--------------------更新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代码注释

 #include <iostream>
#include "rtspClient.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h> using std::cout;
using std::endl; int main(int argc, char *argv[])
{
string RtspUri("rtsp://127.0.0.1/ansersion");
// string RtspUri("rtsp://192.168.81.145/ansersion");
RtspClient Client; /* Set up rtsp server resource URI */
Client.SetURI(RtspUri); /* Send DESCRIBE command to server */
Client.DoDESCRIBE(); /* Parse SDP message after sending DESCRIBE command */
Client.ParseSDP(); // 解析RTSP服务端受理DESCRIBE命令后返回的SDP信息 /* Send SETUP command to set up all 'audio' and 'video'
* sessions which SDP refers. */
Client.DoSETUP(); printf("start PLAY\n");
printf("SDP: %s\n", Client.GetSDP().c_str()); /* Send PLAY command to play only the
* 'video' sessions.*/
Client.DoPLAY("video"); /* Receive 1000 RTP 'video' packets
* note(FIXME):
* if there are several 'video' session
* refered in SDP, only receive packets of the first
* 'video' session, the same as 'audio'.*/
int packet_num = 0;
uint8_t buf[65534];
size_t size = 0; /* Write h264 video data to file "test_packet_recv.h264"
* Then it could be played by ffplay */
int fd = open("test_packet_recv.h264", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR);
if(Client.GetSPSNalu(buf, &size)) { // 解码SDP中关于H264的SPS的数据
if(write(fd, buf, size) < 0) { // 将SPS写入文件
perror("write");
}
} else {
printf("SPS error\n");
} if(Client.GetPPSNalu(buf, &size)) { // 解码SDP中关于H264的PPS的数据
if(write(fd, buf, size) < 0) { // 将PPS写入文件
perror("write");
}
} else {
printf("PPS error\n");
} while(++packet_num < 1000) { // 接收1000个H264的数据包(确切的说是1000个NALU)
if(!Client.GetMediaData("video", buf, &size)) continue;
if(write(fd, buf, size) < 0) {
perror("write");
}
printf("recv %lu\n", size);
} printf("start TEARDOWN\n");
/* Send TEARDOWN command to teardown all of the sessions */
Client.DoTEARDOWN(); return 0;
}

三、common_example.cpp和complete_example.cpp

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

 int main(int argc, char *argv[])
{
if(argc != ) {
cout << "Usage: " << argv[] << " <URL>" << endl;
cout << "For example: " << endl;
cout << argv[] << " rtsp://127.0.0.1/ansersion" << endl;
return ;
}
cout << "Start play " << argv[] << endl;
cout << "Then put video data into test_packet_recv.h264" << endl;
string RtspUri(argv[]);
// string RtspUri("rtsp://192.168.81.145/ansersion");
RtspClient Client; /* Set up rtsp server resource URI */
Client.SetURI(RtspUri);
......
return ;
}

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

 int main(int argc, char * argv[])
{
......
/* Send DESCRIBE command to server */
if(Client.DoDESCRIBE() != RTSP_NO_ERROR) {
printf("DoDESCRIBE error\n");
return ;
}
printf("%s\n", Client.GetResponse().c_str());
/* Check whether server return '200'(OK) */
if(!Client.IsResponse_200_OK()) {
printf("DoDESCRIBE error\n");
return ;
}
......
return ;
}

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

上一篇              回目录

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

  1. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(一)简介

    关于实时流媒体传输的开源库,目前流行的主要有两个:live555和jrtplib. 其中live555将rtp.rtcp和rtsp的传输协议实现集于一身,功能齐全,是个超强的集合体.但是对于嵌入式系统 ...

  2. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(二)示例

    一.搭建RTSP服务器 要想测试RTSP客户端,没有服务端怎么行呢?然而,有时候条件有限,手头并没有独立的RTSP服务器拿来用,那么我们不妨自己撘一个. 以下有2种方便的做法可供选择: 第一种:使用v ...

  3. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(三)RTSP命令解析

    一.RTSP命令简述 RTSP是用来控制实时流媒体“播放”.“暂停”.“停止”.“录像”等行为的传输协议.该协议规定了一系列命令以及这些命令的发送格式,RTSP客户端可以通过发送这些指定的命令,从而控 ...

  4. 一个基于JRTPLIB的轻量级RTSP客户端——myRTSPClient详解

    myRTSPClient是一个轻量级的RTSP客户端C++函数库. 支持多平台,支持H264,H265,MPA等音视频传输. 免费开源,接口易用,配套教程与代码解析(本博客). 适合RTSP入门学习. ...

  5. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——解码篇:(一)用ffmpeg解码视频

    一.概述 myRTSPClient(RTSPClient)获取音视频数据之后,接下来的工作便是将音视频数据交给解码器去解码(ffmpeg),ffmpeg解码之后于是便有了呈现在终端用户(USER)面前 ...

  6. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(四)用户接口层之处理SDP报文

    当RTSP客户端向RTSP服务端发送DESCRIBE命令时,服务端理应当回复一条SDP报文. 该SDP报文中包含RTSP服务端的基本信息.所能提供的音视频媒体类型以及相应的负载能力,以下是一段SDP示 ...

  7. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(五)用户接口层之提取媒体流数据

    当RTSP客户端向RTSP服务端发送完PLAY命令后,RTSP服务端就会另外开启UDP端口(SDP协商定义的端口)发送RTP媒体流数据包.这些数据包之间会间隔一段时间(毫秒级)陆续被发送到RTSP客户 ...

  8. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(十)使用JRTPLIB传输RTP数据

    myRtspClient通过简单修改JRTPLIB的官方例程作为其RTP传输层实现.因为JRTPLIB使用的是CMAKE编译工具,这就是为什么编译myRtspClient时需要预装CMAKE. 该部分 ...

  9. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(二)用户接口层之RtspClient类及其构造函数

    RtspClient类是myRTSPClient函数库所有特性集中实现的地方. 主要为用户提供: 1. RTSP协议通信接口函数,如DoOPTIONS(): 2. RTSP账号.密码设置函数,如Set ...

随机推荐

  1. Unity-奥义技能背景变黑效果

    [旧博客转移 - 2016年8月29日 12:51 ] 前段时间做了一个放技能的时候,背景缓慢变黑,放完后再变回来的效果,可以很好的突出技能特效的感觉. 算是一种屏幕后期特效,这个特效说难不难,说简单 ...

  2. Java系列 - 用Java8新特性进行Java开发太爽了

    本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome/ 前言 从开始写博客到现在已经过去3个 ...

  3. HttpClient以json形式的参数调用http接口并对返回的json数据进行处理(可以带文件)

    1.参数的url就是被调用的地址,map是你要传的参数.参数转成json我使用的是gson方式转换的. 主要使用的jar包有httpclient-4.5.3.jar.httpcore-4.4.6.ja ...

  4. Angular表单控件需要类型和实际值类型不一致时实现双向绑定

    适用Angular版本为:>=2.本文同样适用于Ionic这类的基于Angular实现的框架. 本文的思路也适用于控件显示的值和实际的值不一样时实现双向绑定. 1. 问题描述 在使用md2的da ...

  5. 由max_allowed_packet引发的mysql攻防大战

    1.原因 程序的sql语句比较长.max_allowed_packet默认是1024.于是就报错了.一开始手动改 global max_allowed_packet ,改完后.莫名奇妙被还原.后来改配 ...

  6. 使用jersey 注解包扫描类PackageNamesScanner

    Jersey 中自带一个包扫描,可以是包,或者具体类名 ,扫描的类型是自己定注解类型,实现功能更加大,可以是jar 包 可以是虚拟地址下的 Jersey 主要用来扫描Path Provider 类中同 ...

  7. css3 变换 transform(2D)

    一.transform变换 可做拉伸.压缩.旋转.偏移的效果.需加各个浏览器前缀. 二.transform-origin 为transform属性值的基点,默认值为元素的中心位置,即以元素左上角为坐标 ...

  8. Ansible 运维自动化 ( 配置管理工具 )

    背景 出差背景,要搞项目的自动化部署.因为只直接对接生产分发,机器又非常多,这样以往使用的bat只能作为应急方案了,还是得考虑使用专业化的工具来做这个事情! 当下有许多的运维自动化工具( 配置管理 ) ...

  9. java 常见数据结构

    1)tree 2) queue 3) list 4) stack 5) heap 6) map

  10. IEnumerable & IEnumerator

    IEnumerable 只有一个方法:IEnumerator GetEnumerator(). INumerable 是集合应该实现的一个接口,这样,就能用 foreach 来遍历这个集合. IEnu ...