截至版本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)

  1. ErrorType RtspClient::DoOPTIONS(string uri)
  2. {
  3. string RtspUri("");
  4. int Sockfd = -;
  5.  
  6. if(uri.length() != ) {
  7. RtspUri.assign(uri);
  8. RtspURI.assign(uri);
  9. }
  10. else if(RtspURI.length() != ) RtspUri.assign(RtspURI);
  11. else return RTSP_INVALID_URI;
  12.  
  13. Sockfd = CreateTcpSockfd(RtspUri);
  14. if(Sockfd < ) return RTSP_INVALID_URI;
  15.  
  16. string Cmd("OPTIONS");
  17. stringstream Msg("");
  18. Msg << Cmd << " " << RtspUri << " " << "RTSP/" << VERSION_RTSP << "\r\n";
  19. Msg << "CSeq: " << ++RtspCSeq << "\r\n";
  20. Msg << "\r\n";
  21.  
  22. if(!SendRTSP(Sockfd, Msg.str())) {
  23. Close(Sockfd);
  24. return RTSP_SEND_ERROR;
  25. }
  26. if(!RecvRTSP(Sockfd, &RtspResponse)) {
  27. Close(Sockfd);
  28. return RTSP_RECV_ERROR;
  29. }
  30. return RTSP_NO_ERROR;
  31. }

第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)

  1. ErrorType RtspClient::DoPLAY(MediaSession * media_session)
  2. {
  3. if(!media_session) {
  4. return RTSP_INVALID_MEDIA_SESSION;
  5. }
  6.  
  7. ErrorType Err = RTSP_NO_ERROR;
  8. int Sockfd = -;
  9. Sockfd = CreateTcpSockfd();
  10. if(Sockfd < ) return RTSP_INVALID_URI;
  11.  
  12. string Cmd("PLAY");
  13. stringstream Msg("");
  14. Msg << Cmd << " " << RtspURI << " " << "RTSP/" << VERSION_RTSP << "\r\n";
  15. Msg << "CSeq: " << ++RtspCSeq << "\r\n";
  16. Msg << "Session: " << media_session->SessionID << "\r\n";
  17. if(Realm.length() > && Nonce.length() > ) {
  18. string RealmTmp = Realm;
  19. string NonceTmp = Nonce;
  20. string Md5Response = MakeMd5DigestResp(RealmTmp, Cmd, RtspURI, NonceTmp);
  21. if(Md5Response.length() != MD5_SIZE) {
  22. cout << "Make MD5 digest response error" << endl;
  23. return RTSP_RESPONSE_401;
  24. }
  25. Msg << "Authorization: Digest username=\"" << Username << "\", realm=\""
  26. << RealmTmp << "\", nonce=\"" << NonceTmp << "\", uri=\"" << RtspURI
  27. << "\", response=\"" << Md5Response << "\"\r\n";
  28. }
  29. Msg << "\r\n";
  30.  
  31. if(RTSP_NO_ERROR == Err && !SendRTSP(Sockfd, Msg.str())) {
  32. Close(Sockfd);
  33. Sockfd = -;
  34. Err = RTSP_SEND_ERROR;
  35. }
  36. if(RTSP_NO_ERROR == Err && !RecvRTSP(Sockfd, &RtspResponse)) {
  37. Close(Sockfd);
  38. Sockfd = -;
  39. Err = RTSP_RECV_ERROR;
  40. }
  41. return RTSP_NO_ERROR;
  42. }

第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. java 文件的编码 问题

    package com.io; public class Encodedemo { public static void main(String[] args)throws Exception{ // ...

  2. Wiser的Junit测试用法

    package org.jbpm.process.workitem.email; import static org.junit.Assert.assertEquals; import static ...

  3. docker~Dockerfile优化程序的部署

    回到目录 一些理论 我们都知道docker这个容器工具可以帮助我们快速进行环境的部署,这对于运营人员来说,无疑是个福音,而这个工作大叔认为不应该是运营人员干的,而是由开发人员来做,因为只有你知道你干的 ...

  4. HDOJ-2009 求数列的和

    Problem Description 数列的定义如下:数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和.   Input 输入数据有多组,每组占一行,由两个整数n(n<10000 ...

  5. android-iconify 使用详解

    android-iconify 使用详解 有图有真相 1.android-iconify简介 iconify的github地址:https://github.com/JoanZapata/androi ...

  6. drbd.9.0版本部署

    DRBD9.0部署 1) drbd软件安装 软件:drbd-9.0.0.tar.gz . drbd-utils-8.9.5.tar.gz(从8.4.5开始,drbd软件分成了两部分:核心模块和管理工具 ...

  7. 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 ...

  8. 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 ...

  9. java 各种去空格的方法

    String str =" dgd fdgd ";   方法一:str = str.trim();//去前后空格 返回:dgd fdgd   方法二:str = str.repla ...

  10. Python Socket 简单聊天室2

    上篇文章写了一个简单的单线程的一问一答的简单聊天室.这次我们使用SocketServer模块搭建一个多线程异步的聊天室. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...