截至版本1.2.3,myRtspClient函数库共支持以下6个RTSP命令(RFC 2326):

(1)OPTIONS

(2)DESCRIBE

(3)SETUP

(4)PLAY

(5)PAUSE

(6)TEARDOWN

对应的接口函数都以“Do”开头,如“DoOPTIONS”。各个接口函数写法相似,大同小异,差异部分会在后续章节做说明,现以DoOPTIONS()和DoPLAY()举例。

一、ErrorType RtspClient::DoOPTIONS(string uri)

 ErrorType RtspClient::DoOPTIONS(string uri)
{
string RtspUri("");
int Sockfd = -; if(uri.length() != ) {
RtspUri.assign(uri);
RtspURI.assign(uri);
}
else if(RtspURI.length() != ) RtspUri.assign(RtspURI);
else return RTSP_INVALID_URI; Sockfd = CreateTcpSockfd(RtspUri);
if(Sockfd < ) return RTSP_INVALID_URI; string Cmd("OPTIONS");
stringstream Msg("");
Msg << Cmd << " " << RtspUri << " " << "RTSP/" << VERSION_RTSP << "\r\n";
Msg << "CSeq: " << ++RtspCSeq << "\r\n";
Msg << "\r\n"; if(!SendRTSP(Sockfd, Msg.str())) {
Close(Sockfd);
return RTSP_SEND_ERROR;
}
if(!RecvRTSP(Sockfd, &RtspResponse)) {
Close(Sockfd);
return RTSP_RECV_ERROR;
}
return RTSP_NO_ERROR;
}

第6-11行,获取RTSP的URI(如rtsp://127.0.0.1/ansersion)。先检查DoOPTIONS参数传入的URI,如果不存在就使用类成员变量RtspURI(更多说明见“实现篇(二)二、RtspClient::RtspClient(string uri)”),若RtspURI也不存在则返回失败。如果参数传入URI,该URI同时会保存至类成员变量RtspURI从而记忆住该URI,以便后续调用“DoXXX”RTSP命令函数时,不必再重复传入URI。

第13-14行,根据URI创建socket,用于和RTSP服务端通信(注:CreateTcpSockfd会根据URI中的IP创建socket,如果以前创建过socket且未关闭,则继续沿用旧有socket。截至版本1.2.3,仅支持使用IPv4的URI)。

第16-20行,组建OPTIONS报文(参见RFC2326 10.1)。

第22-25行,向服务端发送OPTIONS报文。

第26-29行,接收服务端返回报文,并将报文赋值给类成员变量RtspResponse(可以通过GetResponse()获取该值)。

第30行,返回成功。

二、ErrorType RtspClient::DoPLAY(MediaSession * media_session)

 ErrorType RtspClient::DoPLAY(MediaSession * media_session)
{
if(!media_session) {
return RTSP_INVALID_MEDIA_SESSION;
} ErrorType Err = RTSP_NO_ERROR;
int Sockfd = -;
Sockfd = CreateTcpSockfd();
if(Sockfd < ) return RTSP_INVALID_URI; string Cmd("PLAY");
stringstream Msg("");
Msg << Cmd << " " << RtspURI << " " << "RTSP/" << VERSION_RTSP << "\r\n";
Msg << "CSeq: " << ++RtspCSeq << "\r\n";
Msg << "Session: " << media_session->SessionID << "\r\n";
if(Realm.length() > && Nonce.length() > ) {
string RealmTmp = Realm;
string NonceTmp = Nonce;
string Md5Response = MakeMd5DigestResp(RealmTmp, Cmd, RtspURI, NonceTmp);
if(Md5Response.length() != MD5_SIZE) {
cout << "Make MD5 digest response error" << endl;
return RTSP_RESPONSE_401;
}
Msg << "Authorization: Digest username=\"" << Username << "\", realm=\""
<< RealmTmp << "\", nonce=\"" << NonceTmp << "\", uri=\"" << RtspURI
<< "\", response=\"" << Md5Response << "\"\r\n";
}
Msg << "\r\n"; if(RTSP_NO_ERROR == Err && !SendRTSP(Sockfd, Msg.str())) {
Close(Sockfd);
Sockfd = -;
Err = RTSP_SEND_ERROR;
}
if(RTSP_NO_ERROR == Err && !RecvRTSP(Sockfd, &RtspResponse)) {
Close(Sockfd);
Sockfd = -;
Err = RTSP_RECV_ERROR;
}
return RTSP_NO_ERROR;
}

第3-5行,判断media_session是否有效(MediaSession类存有音频或视频相关信息,后续章节将做说明)。

第9-10行,创建socket。

第12-29行,组建PLAY报文(参见RFC2326 10.5),其中第17-28行在报文中加入鉴权信息(参见RFC2069),如果不需要鉴权则可略去。

第31-35行,向服务端发送PLAY报文。

第36-40行,接收服务端返回报文。

example代码中使用的是ErrorType RtspClient::DoPLAY(string media_type),是该函数的封装,参数media_type取“video”或“audio”。

上一篇                       回目录                      下一篇

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(三)用户接口层之RTSP命令的更多相关文章

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

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

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

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

  3. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(一)概览

    myRTSPClient主要可以分成3个部分: 1. RTSPClient用户接口层: 2. RTP 音视频传输解析层: 3. RTP传输层. "RTSPClient用户接口层": ...

  4. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(六)RTP音视频传输解析层之音视频数据传输格式

    一.差异 本地音视频数据格式和用来传输的音视频数据格式存在些许差异,由于音视频数据流到达客户端时,需要考虑数据流的数据边界.分包.组包顺序等问题,所以传输中的音视频数据往往会多一些字节. 举个例子,有 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Struts2框架05 result标签的类型

    1 result标签是干什么的 就是结果,服务器处理完返回给浏览器的结果:是一个输出结果数据的组件 2 什么时候需要指定result标签的类型 把要输出的结果数据按照我们指定的数据类型进行处理 3 常 ...

  2. 欢迎大家Follow me!微软MVP罗勇(Dynamics CRM方向)欢迎您!

    我是一名八零后,来自湖南乡村,2002年毕业于大连大学工商管理专业,主要靠自学走上了编程之路.从2012年开始接触Dynamics CRM 2011,一直从事Dynamics CRM方面工作,熟悉Dy ...

  3. 为实施了IFD的Dynamics 365更换自签名的SSL证书以符合Chrome的要求

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复259或者20170704可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...

  4. MyBatis源码解析【6】SqlSession运行

    前言 这个分类比较连续,如果这里看不懂,或者第一次看,请回顾之前的博客 http://www.cnblogs.com/linkstar/category/1027239.html 经过之前的学习我们知 ...

  5. java Static的使用

    static是一个静态修饰符,用于修饰成员(成员变量,成员函数).<thinking in java>对staic的使用场景有下面2种定义:“一种情形是只想用一个存储区域来保存一个特定的数 ...

  6. Async(异步)(一)

    在谈到异步的概念时,先要了解几个概念了. 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源. 而一个进程又是由多个线程所组成的 什么是线程? 线程 ...

  7. C#常用8种排序算法实现以及原理简介

    public static class SortExtention { #region 冒泡排序 /* * 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先比较a[1]与a[2 ...

  8. mysql中csv文件的导入导出

    导出例子: select *from testinto outfile 'D:test.csv'fields terminated by ',' optionally enclosed by '&qu ...

  9. DirectX 11---从空间变换来看3D场景如何转化到2D屏幕

    DirectX 11---从空间变换来看3D场景如何转化到2D屏幕 在看<Introduction to 3D Game Programming with DirectX 11>的时候,发 ...

  10. Python正则表达式指南(转)

    原文地址:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html 1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python ...