一个基于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 ...
随机推荐
- java 文件的编码 问题
package com.io; public class Encodedemo { public static void main(String[] args)throws Exception{ // ...
- Wiser的Junit测试用法
package org.jbpm.process.workitem.email; import static org.junit.Assert.assertEquals; import static ...
- docker~Dockerfile优化程序的部署
回到目录 一些理论 我们都知道docker这个容器工具可以帮助我们快速进行环境的部署,这对于运营人员来说,无疑是个福音,而这个工作大叔认为不应该是运营人员干的,而是由开发人员来做,因为只有你知道你干的 ...
- HDOJ-2009 求数列的和
Problem Description 数列的定义如下:数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和. Input 输入数据有多组,每组占一行,由两个整数n(n<10000 ...
- android-iconify 使用详解
android-iconify 使用详解 有图有真相 1.android-iconify简介 iconify的github地址:https://github.com/JoanZapata/androi ...
- drbd.9.0版本部署
DRBD9.0部署 1) drbd软件安装 软件:drbd-9.0.0.tar.gz . drbd-utils-8.9.5.tar.gz(从8.4.5开始,drbd软件分成了两部分:核心模块和管理工具 ...
- 39. leetcode 326. Power of Three
326. Power of Three Given an integer, write a function to determine if it is a power of three. Follo ...
- 13. leetcode 453. Minimum Moves to Equal Array Elements
Given a non-empty integer array of size n, find the minimum number of moves required to make all arr ...
- java 各种去空格的方法
String str =" dgd fdgd "; 方法一:str = str.trim();//去前后空格 返回:dgd fdgd 方法二:str = str.repla ...
- Python Socket 简单聊天室2
上篇文章写了一个简单的单线程的一问一答的简单聊天室.这次我们使用SocketServer模块搭建一个多线程异步的聊天室. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...