截至版本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. 关于WIN7 内存占用很大的 问题svchost.exe

    svchost.exe 是用来启动系统服务的,所以某个 svchost.exe 占用内存过大,可能就是它启动的那个服务占用内存过大,所以只要停止并禁用那个服务就行了. 一般来说占用内存最大的服务是 S ...

  2. git分支的使用

    本文章假定你已经接触了一些git的基本概念和基本的操作知识 这里先贴出关于分支的一些常用命令 git branch /*查看所有分支*/git branch <branch-name> / ...

  3. Python的元类

    1.用元类验证子类 每当我们定义新类的时候,元类就会运行雅正代码,以确保这个新类符合规定的规范. Python系统把子类的class语句处理完毕,就会调用元类的 __new__ 方法.元类可以通过 _ ...

  4. SQL Server Alwayson配置两个节点加共享文件夹仲裁见证

    标签:MSSQL/节点和共享文件夹多数 概述 之前讲过多数节点的仲裁配置,多数节点一般3个节点以上的奇数个节点:常见的是使用3个节点节点多了也是浪费因为Alwayson的只读路由只能利用到一个只读副本 ...

  5. log 的 debug()、 error()、 info()方法的区别

    软件中总免不了要使用诸如 Log4net, Log4j, Tracer 等东东来写日志,不管用什么,这些东东大多是大同小异的,一般都提供了这样5个日志级别:    × Debug    × Info  ...

  6. JavaScript+canvas 绘制多边形

    效果图: <body> <canvas id="square" width="500"></canvas> <canv ...

  7. 面向对象15.3String类-常见功能-获取-1

    API使用: 查API文档的时候,有很多方法,首先先看返回的类型 下面的方法函数有的是有覆写Object类的如1.1图,如果没有复写的话是写在1.2图片那里的,如果找到了相对于的方法,可以点击进去可以 ...

  8. iOS开发中frame与bounds的区别

    闲话不多说,先上两张图,大伙们就已经明白了: 显示出来的效果是这样子滴:  总结: 要理清这两者的区别,最主要的要理解一下几个概念:frame可以理解为可视的范围,而bounds可以理解为可视范围内的 ...

  9. 【JAVASCRIPT】React + Redux

    摘要 Redux 数据流图 View 层由React 控制, 根据state 变化 刷新渲染组件,作用是根据更新的数据重新渲染组件 Stroe 层其实就是state存储器,作用是更新数据 Dispat ...

  10. call和apply和bind区别

    call和apply特征一样 都是用来调用函数 立即调用 但是可以在调用函数的同时 通过第一个参数指定函数内部this的指向 call 调用的时候 参数必须以参数列表的形式进行传递 也就是以逗号分隔的 ...