一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(三)用户接口层之RTSP命令
截至版本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命令的更多相关文章
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(一)简介
关于实时流媒体传输的开源库,目前流行的主要有两个:live555和jrtplib. 其中live555将rtp.rtcp和rtsp的传输协议实现集于一身,功能齐全,是个超强的集合体.但是对于嵌入式系统 ...
- 一个基于JRTPLIB的轻量级RTSP客户端——myRTSPClient详解
myRTSPClient是一个轻量级的RTSP客户端C++函数库. 支持多平台,支持H264,H265,MPA等音视频传输. 免费开源,接口易用,配套教程与代码解析(本博客). 适合RTSP入门学习. ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(一)概览
myRTSPClient主要可以分成3个部分: 1. RTSPClient用户接口层: 2. RTP 音视频传输解析层: 3. RTP传输层. "RTSPClient用户接口层": ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(六)RTP音视频传输解析层之音视频数据传输格式
一.差异 本地音视频数据格式和用来传输的音视频数据格式存在些许差异,由于音视频数据流到达客户端时,需要考虑数据流的数据边界.分包.组包顺序等问题,所以传输中的音视频数据往往会多一些字节. 举个例子,有 ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(四)用户接口层之处理SDP报文
当RTSP客户端向RTSP服务端发送DESCRIBE命令时,服务端理应当回复一条SDP报文. 该SDP报文中包含RTSP服务端的基本信息.所能提供的音视频媒体类型以及相应的负载能力,以下是一段SDP示 ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(二)示例
一.搭建RTSP服务器 要想测试RTSP客户端,没有服务端怎么行呢?然而,有时候条件有限,手头并没有独立的RTSP服务器拿来用,那么我们不妨自己撘一个. 以下有2种方便的做法可供选择: 第一种:使用v ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(三)RTSP命令解析
一.RTSP命令简述 RTSP是用来控制实时流媒体“播放”.“暂停”.“停止”.“录像”等行为的传输协议.该协议规定了一系列命令以及这些命令的发送格式,RTSP客户端可以通过发送这些指定的命令,从而控 ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(五)用户接口层之提取媒体流数据
当RTSP客户端向RTSP服务端发送完PLAY命令后,RTSP服务端就会另外开启UDP端口(SDP协商定义的端口)发送RTP媒体流数据包.这些数据包之间会间隔一段时间(毫秒级)陆续被发送到RTSP客户 ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(二)用户接口层之RtspClient类及其构造函数
RtspClient类是myRTSPClient函数库所有特性集中实现的地方. 主要为用户提供: 1. RTSP协议通信接口函数,如DoOPTIONS(): 2. RTSP账号.密码设置函数,如Set ...
随机推荐
- 如何用快速傅里叶变换实现DFT
[目标] 如何以 \(O(N \log N)\) 的效率将系数多项式转换为点值多项式. [前置技能] 众所周知,\(x^n=1\)的根有n个,而且它们分别是\(e^{\frac{2*π*i}{ ...
- MessageBoxButtons.OKCancel的选择事件
private void 退出ToolStripMenuItem1_Click(object sender, EventArgs e) { DialogResult resault = Message ...
- A start job is running for xxx to stop
CentOS7开机时,遇到这样的问题已经好多回了,查阅了许多这样的问题,总是没能找到自己想要的答案. 今天本来启动顺利,但是设置mysql.httpd服务开机启动之后,再次开机时又遇到这样的问题. 这 ...
- Opencv探索之路(十九):读写xml和yml文件
有时候我们处理完图像后需要保存一下数据到文件上,以供下一步的处理.一个比较广泛的需求场景就是:我们对一幅图像进行特征提取之后,需要把特征点信息保存到文件上,以供后面的机器学习分类操作.那么如果遇到这样 ...
- 华为CloudIDE免费公测,带你出坑带你飞
你的代码仓库上线了吗?是不是有时候遇到这样的问题? 只想浏览一下代码,却发现线上浏览效果不佳,高亮显示什么的都没有.而在桌面端浏览要需要先同步代码,再用桌面端的IDE打开.尤其是使用git的时候,先要 ...
- 【期望DP】
[总览] [期望dp] 求解达到某一目标的期望花费:因为最终的花费无从知晓(不可能从$\infty$推起),所以期望dp需要倒序求解. 设$f[i][j]$表示在$(i, j)$这个状态实现目标的期望 ...
- Scikit-Learn与决策树
Scikit-Learn(决策树)可以用于方法分类和回归. 一.分类 sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='b ...
- Linux文件系统,ntfs分区显示只读文件系统,提示超级快损坏
背景:某天当我打开自己的设备,突然发现ntfs分区无法写入任何文件,提示为只读文件系统,具体现象如下: 修复过程:排除权限问题,使用fsck进行修复无果后,使用e2fsck进行修复 显示超级快损坏,这 ...
- 30. leetcode 121. Best Time to Buy and Sell Stock
121. Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of ...
- 从equals和==的区别开始
今天我要谈的,不是具体的一个小程序的设计,也不是什么高大上的遗传算法群体智能什么什么的理念.今天我想就非常简单的一个问题,深入地解释一些东西,把自己的一些看法传达给大家.我相信,认真看下去,大家会有所 ...