rtsp_rtsp 交互 - CSDN
rtsp 订阅
RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP请求由客户机发出,服务器作出响应;使用RTSP时,客户机和服务器都可以发出请求,即RTSP可以是双向的。RTSP是用来控制声音或影像的多媒体串流协议,并允许同时多个串流需求控制,传输时所用的网络通讯协定并不在其定义的范围内,服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而前面提到的允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量,更进而支持多方视讯会议(Video Conference)。因为与HTTP1.1的运作方式相似,所以代理服务器〈Proxy〉的快取功能〈Cache〉也同样适用于RTSP,并因RTSP具有重新导向功能,可视实际负载情况来转换提供服务的服务器,以避免过大的负载集中于同一服务器而造成延迟。 [1] 展开全文
RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP请求由客户机发出,服务器作出响应;使用RTSP时,客户机和服务器都可以发出请求,即RTSP可以是双向的。RTSP是用来控制声音或影像的多媒体串流协议,并允许同时多个串流需求控制,传输时所用的网络通讯协定并不在其定义的范围内,服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而前面提到的允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量,更进而支持多方视讯会议(Video Conference)。因为与HTTP1.1的运作方式相似,所以代理服务器〈Proxy〉的快取功能〈Cache〉也同样适用于RTSP,并因RTSP具有重新导向功能,可视实际负载情况来转换提供服务的服务器,以避免过大的负载集中于同一服务器而造成延迟。 [1]
信息
外文名
Real Time Streaming Protocol
简    称
RTSP
中文名
实时流传输协议
属    性
应用层协议
RTSP协议简介
其是 TCP/IP 协议体系中的一个应用层协议,该协议定义了一对多应 用程序如何有效地通过 IP 网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTSP传送的是多媒体数据。RTSP是基于文本的协议,采用ISO10646字符集,使用UTF-8编码方案。行以CRLF中断,包括消息类型、消息头、消息体和消息长。但接收者本身可将CR和LF解释成行终止符。基于文本的协议使其以自描述方式增加可选参数更容易,接口中采用SDP作为描述语言。 [2]  RTSP是应用级协议,控制实时数据的发送。RTSP提供了一个可扩展框架,使实时数据,如音频与视频的受控点播成为可能。数据源包括现场数据与存储在剪辑中数据。该协议目的在于控制多个数据发送连接,为选择发送通道,如UDP、组播UDP与TCP,提供途径,并为选择基于RTP上发送机制提供方法。RTSP建立并控制一个或几个时间同步的连续流媒体。尽管连续媒体流与控制流交换是可能的,通常它本身并不发送连续流。换言之,RTSP充当多媒体服务器的网络远程控制。RTSP连接没有绑定到传输层连接,如TCP。在RTSP连接期间,RTSP用户可打开或关闭多个对服务器的可传输连接以发出RTSP请求。此外,可使用无连接传输协议,如UDP。RTSP流控制的流可能用到RTP,但RTSP操作并不依赖用于携带连续媒体的传输机制。 [3]  协议支持的操作如下:(1)从媒体服务器上检索媒体:用户可通过HTTP或其它方法提交一个演 示描述。如演示是组播,演示式就包含用于连续媒体的组播地址和端口。如演示仅通过单播发送给用户,用户为了安全应提供目的地址。(2)媒体服务器邀请进入会议:媒体服务器可被邀请参加正进行的会议,或回放媒体,或记录其中一部分,或全部。这种模式在分布式教育应用上很有用,会议中几方可轮流按远程控制按钮。(3)将媒体加到现成讲座中:如服务器告诉用户可获得附加媒体内容,对现场讲座显得尤其有用。如HTTP/1.1中类似,RTSP请求可由代理、通道与缓存处理。
收起全文
精华内容
参与话题
  • 0.所有相关的资料、代码、工具都放在百度云盘中 1.java语言实现 2.rtsp_rtp_h264&Mjpeg协议最简单全实现,无控件 3.可以和ffplay,vlc进行rtsp协议互联 4.效果如图:
  • rtsp 简介

    千次阅读 2018-06-23 20:26:08
    一、RTSP协议介绍什么是rtsp?RTSP协议以客户服务器方式工作,,如:暂停/继续、后退、前进等。它是一个多媒体播放控制协议,用来使用户在播放从因特网下载的实时数据时能够进行控制, 因此 RTSP 又称为“因特网录像机...

    一、RTSP协议介绍

    什么是rtsp?

    RTSP协议以客户服务器方式工作,,如:暂停/继续、后退、前进等。它是一个多媒体播放控制协议,用来使用户在播放从因特网下载的实时数据时能够进行控制, 因此 RTSP 又称为“因特网录像机遥控协议”。

            RTSP(Real-Time Stream Protocol)是一种基于文本的应用层协议,在语法及一些消息参数等方面,RTSP协议与HTTP协议类似。 是TCP/IP协议体系中的一个应用层协议, 由哥伦比亚大学, 网景和RealNetworks公司提交的IETF RFC标准. 对应的RFC编号是2326,可以在这里搜索 RFC Editor

            该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据. RTSP在体系结构上位于RTP和RTCP之上, 它使用TCP或RTP完成数据传输. RTSP被用于建立的控制媒体流的传输,它为多媒体服务扮演“网络远程控制”的角色。尽管有时可以把RTSP控制信息和媒体数据流交织在一起传送,但一般情况RTSP本身并不用于转送媒体流数据。媒体数据的传送可通过RTP/RTCP等协议来完成。

    该协议用于C/S模型, 是一个基于文本的协议, 用于在客户端和服务器端建立和协商实时流会话.

    网络体系

    RTSP是类似http的应用层协议,一个典型的流媒体框架网络体系可参考下图
    

    image

    一次基本的RTSP操作过程:

    • 首先,客户端连接到流服务器并发送一个RTSP描述命令(DESCRIBE)。
    • 流服务器通过一个SDP描述来进行反馈,反馈信息包括流数量、媒体类型等信息。
    • 客户端再分析该SDP描述,并为会话中的每一个流发送一个RTSP建立命令(SETUP),RTSP建立命令告诉服务器客户端用于接收媒体数据的端口。流媒体连接建立完成后,
    • 客户端发送一个播放命令(PLAY),服务器就开始在UDP上传送媒体流(RTP包)到客户端。 在播放过程中客户端还可以向服务器发送命令来控制快进、快退和暂停等。
    • 最后,客户端可发送一个终止命令(TERADOWN)来结束流媒体会话
    sequenceDiagram
    客户端->>服务器:DESCRIBE
    服务器->>客户端: 200 OK (SDP)
    客户端->>服务器:SETUP
    服务器->>客户端: 200 OK
    客户端->>服务器:PLAY
    服务器->>客户端: (RTP包)
    

    协议特点

    • 可扩展性: 新方法和参数很容易加入RTSP.
    • 易解析: RTSP可由标准HTTP或MIME解析器解析.
    • 安全: RTSP使用网页安全机制.
    • 独立于传输: RTSP可使用不可靠数据报协议(EDP), 可靠数据报协议(RDP); 如要实现应用级可靠, 可使用可靠流协议.
    • 多服务器支持: 每个流可放在不同服务器上, 用户端自动与不同服务器建立几个并发控制连接, 媒体同步在传输层执行.
    • 记录设备控制: 协议可控制记录和回放设备.
    • 流控与会议开始分离: 仅要求会议初始化协议提供, 或可用来创建惟一会议标识号. 特殊情况下, 可用SIP或H.323来邀请服务器入会.
    • 适合专业应用: 通过SMPTE时标, RTSP支持帧级精度, 允许远程数字编辑.
    • 演示描述中立: 协议没强加特殊演示或元文件, 可传送所用格式类型; 然而, 演示描述至少必须包括一个RTSP URL.
    • 代理与防火墙友好: 协议可由应用和传输层防火墙处理. 防火墙需要理解SETUP方法, 为UDP媒体流打开一个“缺口”.
    • HTTP友好: 此处, RTSP明智地采用HTTP观念, 使现在结构都可重用. 结构包括Internet内容选择平台(PICS). 由于在大多数情况下控制连续媒体需要服务器状态, RTSP不仅仅向HTFP添加方法.
    • 适当的服务器控制: 如用户启动一个流, 必须也可以停止一个流.
    • 传输协调: 实际处理连续媒体流前, 用户可协调传输方法.
    • 性能协调: 如基本特征无效, 必须有一些清理机制让用户决定哪种方法没生效. 这允许用户提出适合的用户界面.

    RTSP协议与HTTP协议区别

    1. RTSP引入了几种新的方法,比如DESCRIBE、PLAY、SETUP 等,并且有不同的协议标识符,RTSP为rtsp 1.0,HTTP为http 1.1;
    2. HTTP是无状态的协议,而RTSP为每个会话保持状态;
    3. RTSP协议的客户端和服务器端都可以发送Request请求,而在HTTPF 协议中,只有客户端能发送Request请求。
    4. 在RTSP协议中,载荷数据一般是通过带外方式来传送的(除了交织的情况),及通过RTP协议在不同的通道中来传送载荷数据。而HTTP协议的载荷数据都是通过带内方式传送的,比如请求的网页数据是在回应的消息体中携带的。
    5. 使用ISO 10646(UTF-8) 而不是ISO 8859-1,以配合当前HTML的国际化;
    6. RTSP使用URI请求时包含绝对URI。而由于历史原因造成的向后兼容性问题,HTTP/1.1只在请求中包含绝对路径,把主机名放入单独的标题域中;

    二、RTSP 的报文结构

    RTSP URL的语法结构

    一个终端用户是通过在播放器中输入URL地址开始进行观看流媒体业务的第一步,而对于使用RTSP协议的移动流媒体点播而言,URL的一般写法如下:

    一个以“rtsp”或是“rtspu”开始的URL链接用于指定当前使用的是RTSP 协议。RTSP URL的语法结构如下:

    rtsp_url = (“rtsp:”| “rtspu:”) “//” host [“:”port”] /[abs_path]/content_name

    host:可以是一个有效的域名或是IP地址。

    port:端口号,对于RTSP协议来说,缺省的端口号为554。当我们在确认流媒体服务器提供的端口号为554时,此项可以省略 说明:当HMS服务器使用的端口号为554时,我们在写点播链接时,可以不用写明端口号,但当使用非554端口时,在RTSP URL中一定要指定相应的端口。

    abs_path: 为RTSPServer中的媒体流资源标识,见下章节的录像资源命名。

    RTSPURL用来标识RTSPServer的媒体流资源,可以标识单一的媒体流资源,也可以标 识多个媒体流资源的集合。

    RTSP的报文结构

        RTSP是一种基于文本的协议,用CRLF作为一行的结束符。使用基于文本协议的好处在于我们可以随时在使用过程中的增加自定义的参数,也可以随便将协议包抓住很直观的进行分析。

        RTSP有两类报文:请求报文和响应报文。请求报文是指从客户向服务器发送请求报文,响应报文是指从服务器到客户的回答。 由于 RTSP 是面向正文的(text-oriented),因此在报文中的每一个字段都是一些 ASCII 码串,因而每个字段的长度都是不确定的。 RTSP报文由三部分组成,即开始行、首部行和实体主体。在请求报文中,开始行就是请求行.

    RTSP请求报文的结构如下图所示

    image

                            图2 RTSP请求报文的结构

    RTSP请求报文的方法包括:OPTIONS、DESCRIBE、SETUP、TEARDOWN、PLAY、PAUSE、GET_PARAMETER和SET_PARAMETER。

    一个请求消息(a request message)即可以由客户端向服务端发起也可以由服务端向客户端发起。请求消息的语法结构如下:

    Request = Request-Line

      *(	general-header	 | request-header | entity-header)
    
      	CRLF
    
      	[message-body]
    
    1. Request Line

    请求消息的第一行的语法结构如下:

    Request-Line	=	Method 空格 Request-URI 空格 RTSP-Version CRLF
    

    其中在消息行中出现的第一个单词即是所使用的信令标志。目前已经有的信息标志如下:

      Method 		=	“DESCRIBE” 
      		|	“ANNOUNCE”
      		|	“GET_PARAMETER”
      		|	“OPTIONS”
      		|	“PAUSE”
      		|	“PLAY”
      		|	“RECORD”
      		|	“REDIRECT”
      		|	“SETUP”
      		|	“SET_PARAMETER”
      		|	“TEARDOWN”
    

    例子:

    DESCRIBE rtsp://211.94.164.227/3.3gp RTSP/1.0

    2. Request Header Fields

    在消息头中除了第一行的内容外,还有一些需求提供附加信息。其中有些是一定要的,后续我们会详细介绍经常用到的几个域的含义。

      Request-header		=	Accept
       			|	Accept-Encoding
      			|	Accept-Language
      			|	Authorization
      			|	From
      			|	If-Modified-Since
      			|	Range
      			|	Referer
      			|	User-Agent
    

    响应消息

    响应报文的开始行是状态行,RTSP响应报文的结构如下图所示 image

                            图3 RTSP响应报文的结构

    响应消息的语法结构如下:

    Response = Status-Line *( general-header | response-header | entity-header) CRLF [message-body]

    1. Status-Line

    响应消息的第一行是状态行(status-line),每个元素之间用空格分开。除了最后的CRLF之外,在此行的中间不得有CR或是LF的出现。它的语法格式如下,

    Status-Line = RTSP-Version 空格 Status-Code 空格 Reason-Phrase CRLF

    状态码(Status-Code) 是一个三位数的整数,用于描述接收方对所收到请求消息的执行结果

    Status-Code的第一位数字指定了这个回复消息的种类,一共有5类:

    •  1XX: Informational – 请求被接收到,继续处理
    •  2XX: Success – 请求被成功的接收,解析并接受
    •  3XX: Redirection – 为完成请求需要更多的操作
    •  4XX: Client Error – 请求消息中包含语法错误或是不能够被有效执行
    •  5XX: Server Error – 服务器响应失败,无法处理正确的有效的请求消息

    我们在处理问题时经常会遇到的状态码有如下:

    | | |
    ---|---|---|---|--- Status-Code | = |“200”| : OK . || | “400”| : Bad Request . || | “404”| : Not Found . || | “500”| : Internal Server Error

    2. Response Header Fields

    在响应消息的域中存放的是无法放在Status-Line中,而又需要传送给请求者的一些附加信息。

     Response-header 	=	Location
    
      			|	Proxy-Authenticate
      			|	Public
      			|	Retry-After
      			|	Server
      			|	Vary
      			|	WWW-Authenticate
    

    RTSP的主要方法:

    方法方向对象要求含义
    DESCRIBEC->SP,S推荐检查演示或媒体对象的描述,也允许使用接收头指定用户理解的描述格式。DESCRIBE的答复-响应组成媒体RTSP初始阶段
    ANNOUNCEC->S S->CP,S可选当从用户发往服务器时,ANNOUNCE将请求URL识别的演示或媒体对象描述发送给服务器;反之,ANNOUNCE实时更新连接描述。如新媒体流加入演示,整个演示描述再次发送,而不仅仅是附加组件,使组件能被删除
    GET_PARAMETERC->S S->CP,S可选GET_PARAMETER请求检查RUL指定的演示与媒体的参数值。没有实体体时,GET_PARAMETER也许能用来测试用户与服务器的连通情况
    OPTIONSC->S S->CP,S要求可在任意时刻发出OPTIONS请求,如用户打算尝试非标准请求,并不影响服务器状态
    PAUSEC->SP,S推荐PAUSE请求引起流发送临时中断。如请求URL命名一个流,仅回放和记录被停止;如请求URL命名一个演示或流组,演示或组中所有当前活动的流发送都停止。恢复回放或记录后,必须维持同步。在SETUP消息中连接头超时参数所指定时段期间被暂停后,尽管服务器可能关闭连接并释放资源,但服务器资源会被预订
    PLAYC->SP,S要求PLAY告诉服务器以SETUP指定的机制开始发送数据;直到一些SETUP请求被成功响应,客户端才可发布PLAY请求。PLAY请求将正常播放时间设置在所指定范围的起始处,发送流数据直到范围的结束处。PLAY请求可排成队列,服务器将PLAY请求排成队列,顺序执行
    RECORDC->SP,S可选该方法根据演示描述初始化媒体数据记录范围,时标反映开始和结束时间;如没有给出时间范围,使用演示描述提供的开始和结束时间。如连接已经启动,立即开始记录,服务器数据请求URL或其他URL决定是否存储记录的数据;如服务器没有使用URL请求,响应应为201(创建),并包含描述请求状态和参考新资源的实体与位置头。支持现场演示记录的媒体服务器必须支持时钟范围格式,smpte格式没有意义
    REDIRECTS->CP,S可选重定向请求通知客户端连接到另一服务器地址。它包含强制头地址,指示客户端发布URL请求;也可能包括参数范围,以指明重定向何时生效。若客户端要继续发送或接收URL媒体,客户端必须对当前连接发送TEARDOWN请求,而对指定主执新连接发送SETUP请求
    SETUPC->SS要求对URL的SETUP请求指定用于流媒体的传输机制。客户端对正播放的流发布一个SETUP请求,以改变服务器允许的传输参数。如不允许这样做,响应错误为"455 Method Not Valid In This State”。为了透过防火墙,客户端必须指明传输参数,即使对这些参数没有影响
    SET_PARAMETERC->S S->CP,S可选请求设置演示或URL指定流的参数值。请求仅应包含单个参数,允许客户端决定某个特殊请求为何失败。如请求包含多个参数,所有参数可成功设置,服务器必须只对该请求起作用。服务器必须允许参数可重复设置成同一值,但不让改变参数值。注意:媒体流传输参数必须用SETUP命令设置。将设置传输参数限制为SETUP有利于防火墙。将参数划分成规则排列形式,结果有更多有意义的错误指示
    TEARDOWNC->SP,S要求TEARDOWN请求停止给定URL流发送,释放相关资源。如URL是此演示URL,任何RTSP连接标识不再有效。除非全部传输参数是连接描述定义的,SETUP请求必须在连接可再次播放前发布
    注:P---演示,C---客户端,S---服务器, S(对象栏)---流
    
    信令指的是在Request-URI中指定的需要被接收者完成的操作。信令(The method)大小写敏感,不能以字符”$”开始,并且一定要是一个标记符。

    RTSP重要头字段参数

    1. Accept: 用于指定客户端可以接受的媒体描述信息类型。比如: Accept: application/rtsl, application/sdp;level=2

    2. Bandwidth: 用于描述客户端可用的带宽值。

    3. CSeq: 指定了RTSP请求回应对的序列号,在每个请求或回应中都必须包括这个头字段。对每个包含一个给定序列号的请求消息,都会有一个相同序列号的回应消息。

    4. Rang: 用于指定一个时间范围,可以使用SMPTE、NTP或clock时间单元。

    5. Session: Session头字段标识了一个RTSP会话。Session ID 是由服务器在SETUP的回应中选择的,客户端一当得到Session ID后,在以后的对Session 的操作请求消息中都要包含Session ID.

    6. Transport: Transport头字段包含客户端可以接受的转输选项列表,包括传输协议,地址端口,TTL等。服务器端也通过这个头字段返回实际选择的具体选项。如: Transport: RTP/AVP;multicast;ttl=127;mode="PLAY", RTP/AVP;unicast;client_port=3456-3457;mode="PLAY"

    简单的RTSP消息交互过程

    C表示RTSP客户端,S表示RTSP服务端

    第一步:查询服务器端可用方法

    C->S OPTION request //询问S有哪些方法可用

    S->C OPTION response //S回应信息的public头字段中包括提供的所有可用方法

    第二步:得到媒体描述信息

    C->S DESCRIBE request //要求得到S提供的媒体描述信息

    S->C DESCRIBE response //S回应媒体描述信息,一般是sdp信息

    第三步:建立RTSP会话

    C->S SETUP request //通过Transport头字段列出可接受的传输选项,请求S建立会话

    S->C SETUP response //S建立会话,通过Transport头字段返回选择的具体转输选项,并返回建立的Session ID;

    第四步:请求开始传送数据

    C->S PLAY request //C请求S开始发送数据

    S->C PLAY response //S回应该请求的信息

    第五步: 数据传送播放中

    S->C 发送流媒体数据 // 通过RTP协议传送数据

    第六步:关闭会话,退出

    C->S EARDOWN request //C请求关闭会话

    S->C TEARDOWN response //S回应该请求

    上述的过程只是标准的、友好的rtsp流程,但实际的需求中并不一定按此过程。 其中第三和第四步是必需的!第一步,只要服务器和客户端约定好有哪些方法可用,则option请求可以不要。第二步,如果我们有其他途径得到媒体初始化描述信息(比如http请求等等),则我们也不需要通过rtsp中的describe请求来完成。


    RTSP的请求响应示例

     其中C是客户端,S是服务端。
    
    OPTIONS
      C->S:       OPTION request //询问S有哪些方法可用
      S->C:       OPTION response //S回应信息中包括提供的所有可用方法
    

    ** 客户端到服务端 **

    OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
    Cseq: 1

    服务端对OPTIONS的回应:(服务器的回应信息会在Public字段列出提供的方法。)

    RTSP/1.0 200 OK
    Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
    Cseq: 1
    Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD

    DESCRIBE
      C->S:      DESCRIBE request //要求得到S提供的媒体初始化描述信息
      S->C:      DESCRIBE response //S回应媒体初始化描述信息,主要是sdp
    

    客户端到服务端的请求举例:(客户端向服务器端发送DESCRIBE,用于得到URI所指定的媒体描述信息,一般是SDP信息。客户端通过Accept头指定客户端可以接受的媒体述信息类型。)

    DESCRIBE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
    Cseq: 2

    服务端对DESCRIBE的回应:(服务器回应URI指定媒体的描述信息)

    RTSP/1.0 200 OK  
    Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )  
    Cseq: 2  
    Content-length: 421  
    Date: Mon, 03 Aug 2009 08:21:33 GMT  
    Expires: Mon, 03 Aug 2009 08:21:33 GMT  
    Content-Type: application/sdp  
    x-Accept-Retransmit: our-retransmit  
    x-Accept-Dynamic-Rate: 1  
    Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/  
    
    
    v=0  
    o=MediaBox 127992 137813 IN IP4 0.0.0.0  
    s=RTSP Session  
    i=Starv Box Live Cast  
    c=IN IP4 218.207.101.236  
    t=0 0  
    a=range:npt=now-  
    a=control:*  
    m=video 0 RTP/AVP 96  
    b=AS:20  
    a=rtpmap:96 MP4V-ES/1000  
    a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586  
    a=range:npt=now-  
    a=framerate:5  
    a=framesize:96 176-144  
    a=cliprect:0,0,144,176  
    a=control:trackID=1  
    展开全文
  • RTSP分析与实现原理

    千人学习 2019-06-05 08:48:16
    本课程是RTSP/ONVIF/GB28181系列教程之一,通过分析RTSP协议信令交互过程,结合RTSP媒体库(由Inpilen完全自主实现的RTSP/RTP/RTCP媒体库)的接口设计、模块划分、实现思路及RTSP相关重要细节,对RTSP协议作出一个...
  • RTSP协议学习

    万次阅读 2017-03-03 18:45:19
    RTSP简介 RTSP和HTTP RTPRTCP的关系 RTSP和HTTP RTSP和RTPRTCP RTSP消息 简单的rtsp交互过程 RTSP中常用方法 OPTION DESCRIBE SETUP PLAY TEARDOWN SDP协议 RTSP基于libcurl代码实现 参考资料

    RTSP简介

    RTSP(Real Time Streaming Protocol)是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。RTSP对流媒体提供了诸如暂停,快进等控制,而它本身并不传输数据,RTSP的作用相当于流媒体服务器的远程控制。服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。

    RTSP和HTTP RTP(RTCP)的关系

    RTSP和HTTP

    • 联系:两者都用纯文本来发送消息,且rtsp协议的语法也和HTTP类似。Rtsp一开始这样设计,也是为了能够兼容使用以前写的HTTP协议分析代码 。
    • 区别:rtsp是有状态的,不同的是RTSP的命令需要知道现在正处于一个什么状态,也就是说rtsp的命令总是按照顺序来发送,某个命令总在另外一个命令之前要发送。Rtsp不管处于什么状态都不会断掉连接。而http则不保存状态,协议在发送一个命令以后,连接就会断开,且命令之间是没有依赖性。rtsp协议使用554端口,http使用80端口。

    RTSP和RTP(RTCP)

    • RTP:Realtime Transport Potocol 实时传输协议
      RTP提供时间标志,序列号以及其他能够保证在实时数据传输时处理时间的方法。
    • RTCP:Realtime Transport Control Potocol 实时传输控制协议
      RTCP是RTP的控制部分,用来保证服务质量和成员管理。RTP和RTCP是一起使用的。
    • RTSP:RealTime Streaming Potocol 实时流协议
      RTSP具体数据传输交给RTP,提供对流的远程控制

    RTP是基于 UDP协议的, UDP不用建立连接,效率更高;但允许丢包, 这就要求在重新组装媒体的时候多做些工作
    RTP只是包裹内容信息,而RTCP是交换控制信息的,Qos是通过RTCP实现的
    应用程序对应的是play, seek, pause, stop等命令,RTSP则是处理这些命令,在UDP传输时并使用RTP(RTCP)来完成。如果是TCP连接则不会使用RTP(RTCP)。

    protocol structure

    RTSP的client连接server通过SDP(会话描述协议)传递信息,详细请见:RTSP消息

    RTSP消息

    RTSP的消息有两大类,一是请求消息(request),一是回应消息(response),两种消息的格式不同。
    请求消息格式

    方法 URI RTSP版本 CR LF
    消息头 CR LF CR LF
    消息体 CR LF

    方法包括:OPTIONS、SETUP、PLAY、TEARDOWN DESCRIBE
    URI是接收方(服务端)的地址,例如:rtsp://192.168.22.136:5000/v0
    每行后面的CR LF表示回车换行,需要接收端有相应的解析,消息头需要有两个CR LF。

    DESCRIBE rtsp://192.168.1.211 RTSP/1.0
    CSeq: 1
    Accept: application/sdp
    User-Agent: magnus-fc

    回应消息格式

    RTSP版本 状态码 解释 CR LF
    消息头 CR LF CR LF
    消息体 CR LF

    其中RTSP版本一般都是RTSP/1.0,状态码是一个数值,200表示成功,解释是与状态码对应的文本解释,详细请见:SDP协议介绍。

    RTSP/1.0 200 OK
    CSeq: 1
    Server: GrandStream Rtsp Server V100R001
    Content-Type: application/sdp
    Content-length: 256
    Content-Base: rtsp://192.168.1.211/0
    
    v=0
    o=StreamingServer 3331435948 1116907222000 IN IP4 192.168.1.211
    s=h264.mp4
    c=IN IP4 0.0.0.0
    t=0 0
    a=control:*
    m=video 0 RTP/AVP 96
    a=control:trackID=0
    a=rtpmap:96 H264/90000
    m=audio 0 RTP/AVP 97
    a=control:trackID=1
    a=rtpmap:97 G726-16/8000

    简单的rtsp交互过程:

    C表示rtsp客户端, S表示rtsp服务端

    step1:
    C->S:OPTION request //询问S有哪些方法可用
    S->C:OPTION response //S回应信息中包括提供的所有可用方法

    step2:
    C->S:DESCRIBE request //要求得到S提供的媒体初始化描述信息
    S->C:DESCRIBE response //S回应媒体初始化描述信息,主要是sdp

    step3:
    C->S:SETUP request //设置会话的属性,以及传输模式,提醒S建立会话
    S->C:SETUP response //S建立会话,返回会话标识符,以及会话相关信息

    step4:
    C->S:PLAY request //C请求播放
    S->C:PLAY response //S回应该请求的信息

    S->C:发送流媒体数据

    step5:
    C->S:TEARDOWN request //C请求关闭会话
    S->C:TEARDOWN response //S回应该请求

    RTSP中常用方法

    OPTION

    得到服务器提供的可用方法

    OPTIONS rtsp://192.168.20.136:5000/xxx666 RTSP/1.0
    CSeq: 1 //每个消息都有序号来标记,第一个包通常是option请求消息
    User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)

    服务器的回应信息包括提供的一些方法,例如:

    RTSP/1.0 200 OK 
    Server: UServer 0.9.7_rc1
    Cseq: 1 //每个回应消息的cseq数值和请求消息的cseq相对应
    Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, SCALE,GET_PARAMETER //服务器提供的可用的方法

    DESCRIBE

    C向S发起DESCRIBE请求,为了得到会话描述信息(SDP):

    DESCRIBE rtsp://192.168.20.136:5000/xxx666 RTSP/1.0
    CSeq: 2
    token: 
    Accept: application/sdp
    User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) 

    服务器回应一些对此会话的描述信息(sdp):

    RTSP/1.0 200 OK 
    Server: UServer 0.9.7_rc1 
    Cseq: 2 
    x-prev-url: rtsp://192.168.20.136:5000 
    x-next-url: rtsp://192.168.20.136:5000 
    x-Accept-Retransmit: our-retransmit 
    x-Accept-Dynamic-Rate: 1 
    Cache-Control: must-revalidate 
    Last-Modified: Fri, 10 Nov 2006 12:34:38 GMT 
    Date: Fri, 10 Nov 2006 12:34:38 GMT 
    Expires: Fri, 10 Nov 2006 12:34:38 GMT 
    Content-Base: rtsp://192.168.20.136:5000/xxx666/ 
    Content-Length: 344 
    Content-Type: application/sdp 
    
    v=0 //以下都是sdp信息  
    o=OnewaveUServerNG 1451516402 1025358037 IN IP4 192.168.20.136 
    s=/xxx666 
    u=http:/// 
    e=admin@ 
    c=IN IP4 0.0.0.0 
    t=0 0 
    a=isma-compliance:1,1.0,1 
    
    a=range:npt=0- 
    m=video 0 RTP/AVP 96 //m表示媒体描述,下面是对会话中视频通道的媒体描述
    a=rtpmap:96 MP4V-ES/90000 
    a=fmtp:96 profile-level-id=245;config=000001B0F5000001B509000001000000012000C888B0E0E0FA62D089028307 a=control:trackID=0 //trackID=0表示视频流用的是通道0

    SETUP

    客户端提醒服务器建立会话,并确定传输模式:

    SETUP rtsp://192.168.20.136:5000/xxx666/trackID=0 RTSP/1.0 
    CSeq: 3 
    Transport: RTP/AVP/TCP;unicast;interleaved=0-1 
    User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
     //uri中 带有trackID=0,表示对该通道进行设置。Transport参数设置了传输模式,包的结构。接下来的数据包头部第二个字节位置就是 interleaved,它的值是每个通道都不同的,trackID=0的interleaved值有两个0或1,0表示rtp包,1表示rtcp包,接收端根据interleaved的值来区别是哪种数据包。

    服务器回应信息:

    RTSP/1.0 200 OK 
    Server: UServer 0.9.7_rc1 
    Cseq: 3 
    Session: 6310936469860791894 //服务器回应的会话标识符
    Cache-Control: no-cache 
    Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=6B8B4567

    PLAY

    客户端发送播放请求:

    PLAY rtsp://192.168.20.136:5000/xxx666 RTSP/1.0 
    CSeq: 4 
    Session: 6310936469860791894 
    Range: npt=0.000- //设置播放时间的范围
    User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)

    服务器回应信息:

    RTSP/1.0 200 OK 
    Server: UServer 0.9.7_rc1 
    Cseq: 4 
    Session: 6310936469860791894 
    Range: npt=0.000000- 
    RTP-Info: url=trackID=0;seq=17040;rtptime=1467265309 
     //seq和rtptime都是rtp包中的信息

    TEARDOWN

    客户端发起关闭请求:

    TEARDOWN rtsp://192.168.20.136:5000/xxx666 RTSP/1.0 
    CSeq: 5 
    Session: 6310936469860791894 
    User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) 

    服务器回应:

    RTSP/1.0 200 OK 
    Server: UServer 0.9.7_rc1 
    Cseq: 5 
    Session: 6310936469860791894 

    SDP协议

    sdp的格式:

    v=<version>
    o=<username> <session id> <version> <network type> <address type> <address>
    s=<session name>
    i=<session description>
    u=<URI>
    e=<email address>
    p=<phone number>
    c=<network type> <address type> <connection address>
    b=<modifier>:<bandwidth-value>
    t=<start time> <stop time>
    r=<repeat interval> <active duration> <list of offsets from start-time>
    z=<adjustment time> <offset> <adjustment time> <offset> ....
    k=<method>
    k=<method>:<encryption key>
    a=<attribute>
    a=<attribute>:<value>
    m=<media> <port> <transport> <fmt list>

    v = (协议版本)
    o = (所有者/创建者和会话标识符)
    s = (会话名称)
    i = * (会话信息)
    u = * (URI 描述)
    e = * (Email 地址)
    p = * (电话号码)
    c = * (连接信息)
    b = * (带宽信息)
    z = * (时间区域调整)
    k = * (加密密钥)
    a = * (0 个或多个会话属性行)

    • 时间描述:
      t = (会话活动时间)
      r = * (0或多次重复次数)

    • 媒体描述:
      m = (媒体名称和传输地址)
      i = * (媒体标题)
      c = * (连接信息 — 如果包含在会话层则该字段可选)
      b = * (带宽信息)
      k = * (加密密钥)
      a = * (0 个或多个媒体属性行)

    SDP一会话描述协议一描述SAP、SIP和RTSR会话的协议,是一种文件描述协议,是由服务器生成的描述媒体文件编码信息以及所在服务器的链接等的信息。在多媒体会话 中sDP传送有关媒体流的信息,使会话描述的参人方加人会话。SDP主要用于Intemet网中,但也可以在其它网络环境下使用。SDP十分通用,可描述其它网络环境中的会话,但主要用 于Intemet中。在Intemet环境下,SDP有两个主要目的:一是表明会话存在,二是传送足够信息给接收方,以便能加人、参加该会话。SDP所传达的信息包括:会话名称和目的,会话 活动时间,组成会话媒体种类,接收这些媒体的控制信息(如地址、端口、格式、带宽和会议管理人员资料等)。

    总结:在RTSP交互过程中,只要在客户端发出Describe请求的时候,服务端回应的时候会有SDP消息发出,用SDP来描述会话情况和内容,方便客户端能够加入该会话。

    RTSP基于libcurl代码实现

    /*
     * Copyright (c) 2011, Jim Hollinger
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *   * Redistributions of source code must retain the above copyright
     *     notice, this list of conditions and the following disclaimer.
     *   * Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *   * Neither the name of Jim Hollinger nor the names of its contributors
     *     may be used to endorse or promote products derived from this
     *     software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /* <DESC>
     * A basic RTSP transfer
     * </DESC>
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <curl/curl.h>
    
    #if defined (WIN32)
    #include <conio.h>  /* _getch() */
    #else
    #include <termios.h>
    #include <unistd.h>
    
    #define VERSION_STR  "V1.0"
    
    /* error handling macros */
    #define my_curl_easy_setopt(A, B, C)                             \
      res = curl_easy_setopt((A), (B), (C));                         \
      if(!res)                                                       \
        fprintf(stderr, "curl_easy_setopt(%s, %s, %s) failed: %d\n", \
                #A, #B, #C, res);
    
    #define my_curl_easy_perform(A)                                     \
      res = curl_easy_perform(A);                                       \
      if(!res)                                                          \
        fprintf(stderr, "curl_easy_perform(%s) failed: %d\n", #A, res);
    
    static int _getch(void)
    {
      struct termios oldt, newt;
      int ch;
      tcgetattr(STDIN_FILENO, &oldt);
      newt = oldt;
      newt.c_lflag &= ~( ICANON | ECHO);
      tcsetattr(STDIN_FILENO, TCSANOW, &newt);
      ch = getchar();
      tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
      return ch;
    }
    #endif
    
    /* send RTSP OPTIONS request */
    static void rtsp_options(CURL *curl, const char *uri)
    {
      CURLcode res = CURLE_OK;
      printf("\nRTSP: OPTIONS %s\n", uri);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
      my_curl_easy_perform(curl);
    }
    
    /* send RTSP DESCRIBE request and write sdp response to a file */
    static void rtsp_describe(CURL *curl, const char *uri,
                              const char *sdp_filename)
    {
      CURLcode res = CURLE_OK;
      FILE *sdp_fp = fopen(sdp_filename, "wb");
      printf("\nRTSP: DESCRIBE %s\n", uri);
      if(sdp_fp == NULL) {
        fprintf(stderr, "Could not open '%s' for writing\n", sdp_filename);
        sdp_fp = stdout;
      }
      else {
        printf("Writing SDP to '%s'\n", sdp_filename);
      }
      my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, sdp_fp);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE);
      my_curl_easy_perform(curl);
      my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);
      if(sdp_fp != stdout) {
        fclose(sdp_fp);
      }
    }
    
    /* send RTSP SETUP request */
    static void rtsp_setup(CURL *curl, const char *uri, const char *transport)
    {
      CURLcode res = CURLE_OK;
      printf("\nRTSP: SETUP %s\n", uri);
      printf("      TRANSPORT %s\n", transport);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, transport);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP);
      my_curl_easy_perform(curl);
    }
    
    /* send RTSP PLAY request */
    static void rtsp_play(CURL *curl, const char *uri, const char *range)
    {
      CURLcode res = CURLE_OK;
      printf("\nRTSP: PLAY %s\n", uri);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
      my_curl_easy_setopt(curl, CURLOPT_RANGE, range);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
      my_curl_easy_perform(curl);
    }
    
    /* send RTSP TEARDOWN request */
    static void rtsp_teardown(CURL *curl, const char *uri)
    {
      CURLcode res = CURLE_OK;
      printf("\nRTSP: TEARDOWN %s\n", uri);
      my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN);
      my_curl_easy_perform(curl);
    }
    
    /* convert url into an sdp filename */
    static void get_sdp_filename(const char *url, char *sdp_filename,
                                 size_t namelen)
    {
      const char *s = strrchr(url, '/');
      strcpy(sdp_filename, "video.sdp");
      if(s != NULL) {
        s++;
        if(s[0] != '\0') {
          snprintf(sdp_filename, namelen, "%s.sdp", s);
        }
      }
    }
    
    /* scan sdp file for media control attribute */
    static void get_media_control_attribute(const char *sdp_filename,
                                            char *control)
    {
      int max_len = 256;
      char *s = malloc(max_len);
      FILE *sdp_fp = fopen(sdp_filename, "rb");
      control[0] = '\0';
      if(sdp_fp != NULL) {
        while(fgets(s, max_len - 2, sdp_fp) != NULL) {
          sscanf(s, " a = control: %s", control);
        }
        fclose(sdp_fp);
      }
      free(s);
    }
    
    /* main app */
    int main(int argc, char * const argv[])
    {
    #if 1
      const char *transport = "RTP/AVP;unicast;client_port=1234-1235";  /* UDP */
    #else
      /* TCP */
      const char *transport = "RTP/AVP/TCP;unicast;client_port=1234-1235";
    #endif
      const char *range = "0.000-";
      int rc = EXIT_SUCCESS;
      char *base_name = NULL;
    
      printf("\nRTSP request %s\n", VERSION_STR);
      printf("    Project web site: http://code.google.com/p/rtsprequest/\n");
      printf("    Requires curl V7.20 or greater\n\n");
    
      /* check command line */
      if((argc != 2) && (argc != 3)) {
        base_name = strrchr(argv[0], '/');
        if(base_name == NULL) {
          base_name = strrchr(argv[0], '\\');
        }
        if(base_name == NULL) {
          base_name = argv[0];
        }
        else {
          base_name++;
        }
        printf("Usage:   %s url [transport]\n", base_name);
        printf("         url of video server\n");
        printf("         transport (optional) specifier for media stream"
               " protocol\n");
        printf("         default transport: %s\n", transport);
        printf("Example: %s rtsp://192.168.0.2/media/video1\n\n", base_name);
        rc = EXIT_FAILURE;
      }
      else {
        const char *url = argv[1];
        char *uri = malloc(strlen(url) + 32);
        char *sdp_filename = malloc(strlen(url) + 32);
        char *control = malloc(strlen(url) + 32);
        CURLcode res;
        get_sdp_filename(url, sdp_filename, strlen(url) + 32);
        if(argc == 3) {
          transport = argv[2];
        }
    
        /* initialize curl */
        res = curl_global_init(CURL_GLOBAL_ALL);
        if(res == CURLE_OK) {
          curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
          CURL *curl;
          fprintf(stderr, "    curl V%s loaded\n", data->version);
    
          /* initialize this curl session */
          curl = curl_easy_init();
          if(curl != NULL) {
            my_curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
            my_curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
            my_curl_easy_setopt(curl, CURLOPT_HEADERDATA, stdout);
            my_curl_easy_setopt(curl, CURLOPT_URL, url);
    
            /* request server options */
            snprintf(uri, strlen(url) + 32, "%s", url);
            rtsp_options(curl, uri);
    
            /* request session description and write response to sdp file */
            rtsp_describe(curl, uri, sdp_filename);
    
            /* get media control attribute from sdp file */
            get_media_control_attribute(sdp_filename, control);
    
            /* setup media stream */
            snprintf(uri, strlen(url) + 32, "%s/%s", url, control);
            rtsp_setup(curl, uri, transport);
    
            /* start playing media stream */
            snprintf(uri, strlen(url) + 32, "%s/", url);
            rtsp_play(curl, uri, range);
            printf("Playing video, press any key to stop ...");
            _getch();
            printf("\n");
    
            /* teardown session */
            rtsp_teardown(curl, uri);
    
            /* cleanup */
            curl_easy_cleanup(curl);
            curl = NULL;
          }
          else {
            fprintf(stderr, "curl_easy_init() failed\n");
          }
          curl_global_cleanup();
        }
        else {
          fprintf(stderr, "curl_global_init(%s) failed: %d\n",
                  "CURL_GLOBAL_ALL", res);
        }
        free(control);
        free(sdp_filename);
        free(uri);
      }
    
      return rc;
    }

    参考资料

    展开全文
  • 从零开始写一个RTSP服务器(一)RTSP协议讲解

    万次阅读 多人点赞 2019-11-17 09:06:32
    从零开始写一个RTSP服务器系列 从零开始写一个RTSP服务器(一)不一样的RTSP协议讲解 从零开始写一个RTSP服务器(二)RTP传输H.264(待写) 从零开始写一个RTSP服务器(三)一个传输H.264的RTSP服务器(待写) 从零开始...

    从零开始写一个RTSP服务器系列

    ★我的开源项目-RtspServer

    从零开始写一个RTSP服务器(一)RTSP协议讲解

    从零开始写一个RTSP服务器(二)RTSP协议的实现

    从零开始写一个RTSP服务器(三)RTP传输H.264

    从零开始写一个RTSP服务器(四)一个传输H.264的RTSP服务器

    从零开始写一个RTSP服务器(五)RTP传输AAC

    从零开始写一个RTSP服务器(六)一个传输AAC的RTSP服务器

    从零开始写一个RTSP服务器(七)多播传输RTP包

    从零开始写一个RTSP服务器(八)一个多播的RTSP服务器

    从零开始写一个RTSP服务器(九)一个RTP OVER RTSP/TCP的RTSP服务器

    从零开始写一个RTSP服务器(一)不一样的RTSP协议讲解

    前言

    • 为什么要写这个系列?

      因为我自己在学习rtsp协议想自己从零写一个rtsp服务器的时候,由于rtsp比较复杂,所以觉得这个过程非常的困难,网上许多相关文章或模棱两可,或是复制粘贴。所以想写这样一个系列,来帮助想要学习rtsp协议或者想要从零写一个rtsp服务器的初学者

    • 本系列的文章特点

      并系列文章实现追求精简,能够让人明白rtsp协议的实现过程,不追求复杂和完美

      如果想要实现一个比较完善的rtsp服务器,可以参考我的开源项目-RtspServer

    言归正传,下面开始本系列的文章

    一、什么是RTSP协议?

    RTSP是一个实时传输流协议,是一个应用层的协议

    通常说的RTSP包括RTSP协议RTP协议RTCP协议

    对于这些协议的作用简单的理解如下

    RTSP协议:负责服务器与客户端之间的请求与响应

    RTP协议:负责传输媒体数据

    RTCP协议:在RTP传输过程中提供传输信息

    rtsp承载与rtp和rtcp之上,rtsp并不会发送媒体数据,而是使用rtp协议传输

    rtp并没有规定发送方式,可以选择udp发送或者tcp发送

    二、RTSP协议详解

    rtsp的交互过程就是客户端请求,服务器响应,下面看一看请求和响应的数据格式

    2.1 RTSP数据格式

    RTSP协议格式与HTTP协议格式类似

    • RTSP客户端的请求格式

      method url vesion\r\n
      CSeq: x\r\n
      xxx\r\n
      ...
      \r\n
      

      method:方法,表明这次请求的方法,rtsp定义了很多方法,稍后介绍

      url:格式一般为rtsp://ip:port/session,ip表主机ip,port表端口好,如果不写那么就是默认端口,rtsp的默认端口为554,session表明请求哪一个会话

      version:表示rtsp的版本,现在为RTSP/1.0

      CSeq:序列号,每个RTSP请求和响应都对应一个序列号,序列号是递增的

    • RTSP服务端的响应格式

      vesion 200 OK\r\n
      CSeq: x\r\n
      xxx\r\n
      ...
      \r\n
      

      version:表示rtsp的版本,现在为RTSP/1.0

      CSeq:序列号,这个必须与对应请求的序列号相同

    2.2 RTSP请求的常用方法

    方法 描述
    OPTIONS 获取服务端提供的可用方法
    DESCRIBE 向服务端获取对应会话的媒体描述信息
    SETUP 向服务端发起建立请求,建立连接会话
    PLAY 向服务端发起播放请求
    TEARDOWN 向服务端发起关闭连接会话请求

    2.3 RTSP交互过程

    有了上述的知识,我们下面来讲解一个RTSP的交互过程

    OPTIONS

    • C–>S

      OPTIONS rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
      CSeq: 2\r\n
      \r\n
      

      客户端向服务器请求可用方法

    • S–>C

      RTSP/1.0 200 OK\r\n
      CSeq: 2\r\n
      Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY\r\n
      \r\n
      

      服务端回复客户端,当前可用方法OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY

    DESCRIBE

    • C–>S

      DESCRIBE rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
      CSeq: 3\r\n
      Accept: application/sdp\r\n
      \r\n
      

      客户端向服务器请求媒体描述文件,格式为sdp

    • S–>C

      RTSP/1.0 200 OK\r\n
      CSeq: 3\r\n
      Content-length: 146\r\n
      Content-type: application/sdp\r\n
      \r\n
      
      v=0\r\n
      o=- 91565340853 1 in IP4 192.168.31.115\r\n
      t=0 0\r\n
      a=contol:*\r\n
      m=video 0 RTP/AVP 96\r\n
      a=rtpmap:96 H264/90000\r\n
      a=framerate:25\r\n
      a=control:track0\r\n
      

      服务器回复了sdp文件,这个文件告诉客户端当前服务器有哪些音视频流,有什么属性,具体稍后再讲解

      这里只需要直到客户端可以根据这些信息得知有哪些音视频流可以发送

    SETUP

    • C–>S

      SETUP rtsp://192.168.31.115:8554/live/track0 RTSP/1.0\r\n
      CSeq: 4\r\n
      Transport: RTP/AVP;unicast;client_port=54492-54493\r\n
      \r\n
      

      客户端发送建立请求,请求建立连接会话,准备接收音视频数据

      解析一下Transport: RTP/AVP;unicast;client_port=54492-54493\r\n

      RTP/AVP:表示RTP通过UDP发送,如果是RTP/AVP/TCP则表示RTP通过TCP发送

      unicast:表示单播,如果是multicast则表示多播

      client_port=54492-54493:由于这里希望采用的是RTP OVER UDP,所以客户端发送了两个用于传输数据的端口,客户端已经将这两个端口绑定到两个udp套接字上,54492表示是RTP端口,54493表示RTCP端口(RTP端口为某个偶数,RTCP端口为RTP端口+1)

    • S–>C

      RTSP/1.0 200 OK\r\n
      CSeq: 4\r\n
      Transport: RTP/AVP;unicast;client_port=54492-54493;server_port=56400-56401\r\n
      Session: 66334873\r\n
      \r\n
      

      服务端接收到请求之后,得知客户端要求采用RTP OVER UDP发送数据,单播客户端用于传输RTP数据的端口为54492,RTCP的端口为54493

      服务器也有两个udp套接字,绑定好两个端口,一个用于传输RTP,一个用于传输RTCP,这里的端口号为56400-56401

      之后客户端会使用54492-54493这两端口和服务器通过udp传输数据,服务器会使用56400-56401这两端口和这个客户端传输数据

    PLAY

    • C–>S

      PLAY rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
      CSeq: 5\r\n
      Session: 66334873\r\n
      Range: npt=0.000-\r\n
      \r\n
      

      客户端请求播放媒体

    • S–>C

      RTSP/1.0 200 OK\r\n
      CSeq: 5\r\n
      Range: npt=0.000-\r\n
      Session: 66334873; timeout=60\r\n
      \r\n
      

      服务器回复之后,会开始使用RTP通过udp向客户端的54492端口发送数据

    TEARDOWN

    • C–>S

      TEARDOWN rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
      CSeq: 6\r\n
      Session: 66334873\r\n
      \r\n
      
    • S–>C

      RTSP/1.0 200 OK\r\n
      CSeq: 6\r\n
      \r\n
      

    2.4 sdp格式

    我们上面避开没有讲sdp文件,这里来好好补一补

    sdp格式由多行的type=value组成

    sdp会话描述由一个会话级描述和多个媒体级描述组成。会话级描述的作用域是整个会话,媒体级描述描述的是一个视频流或者音频流

    会话级描述v=开始到第一个媒体级描述结束

    媒体级描述m=开始到下一个媒体级描述结束

    下面是上面示例的sdp文件,我们就来好好分析一下这个sdp文件

    v=0\r\n
    o=- 91565340853 1 in IP4 192.168.31.115\r\n
    t=0 0\r\n
    a=contol:*\r\n
    m=video 0 RTP/AVP 96\r\n
    a=rtpmap:96 H264/90000\r\n
    a=framerate:25\r\n
    a=control:track0\r\n
    

    这个示例的sdp文件包含一个会话级描述一个媒体级描述,分别如下

    • 会话级描述

      v=0\r\n
      o=- 91565340853 1 IN IP4 192.168.31.115\r\n
      t=0 0\r\n
      a=contol:*\r\n
      

      v=0

      表示sdp的版本
      o=- 91565340853 1 IN IP4 192.168.31.115
      格式为 o=<用户名> <会话id> <会话版本> <网络类型><地址类型> <地址>
      用户名:-
      会话id:91565340853,表示rtsp://192.168.31.115:8554/live请求中的live这个会话
      会话版本:1
      网络类型:IN,表示internet
      地址类型:IP4,表示ipv4
      地址:192.168.31.115,表示服务器的地址

    • 媒体级描述

      m=video 0 RTP/AVP 96\r\n
      a=rtpmap:96 H264/90000\r\n
      a=framerate:25\r\n
      a=control:track0\r\n
      

      m=video 0 RTP/AVP 96\r\n

      格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
      媒体类型:video

      端口号:0,为什么是0?因为上面在SETUP过程会告知端口号,所以这里就不需要了

      传输协议:RTP/AVP,表示RTP OVER UDP,如果是RTP/AVP/TCP,表示RTP OVER TCP

      媒体格式:表示负载类型(payload type),一般使用96表示H.264

      a=rtpmap:96 H264/90000

      格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率>

      a=framerate:25

      表示帧率

      a=control:track0

      表示这路视频流在这个会话中的编号

    三、RTP协议

    3.1 RTP包格式

    rtp包由rtp头部和rtp荷载构成

    • RTP头部

    在这里插入图片描述

    版本号(V):2Bit,用来标志使用RTP版本

    填充位§:1Bit,如果该位置位,则该RTP包的尾部就包含填充的附加字节

    扩展位(X):1Bit,如果该位置位,则该RTP包的固定头部后面就跟着一个扩展头部

    CSRC技术器(CC):4Bit,含有固定头部后面跟着的CSRC的数据

    标记位(M):1Bit,该位的解释由配置文档来承担

    载荷类型(PT):7Bit,标识了RTP载荷的类型

    序列号(SN):16Bit,发送方在每发送完一个RTP包后就将该域的值增加1,可以由该域检测包的丢失及恢复

    ​ 包的序列。序列号的初始值是随机的

    时间戳:32比特,记录了该包中数据的第一个字节的采样时刻

    同步源标识符(SSRC):32比特,同步源就是RTP包源的来源。在同一个RTP会话中不能有两个相同的SSRC值

    贡献源列表(CSRC List):0-15项,每项32比特,这个不常用

    • rtp荷载

      rtp载荷为音频或者视频数据

    3.2 RTP OVER TCP

    RTP默认是采用UDP发送的,格式为RTP头+RTP载荷,如果是使用TCP,那么需要在RTP头之前再加上四个字节

    第一个字节:$,辨识符

    第二个字节:通道,在SETUP的过程中获取

    第三第四个字节: RTP包的大小,最多只能12位,第三个字节保存高4位,第四个字节保存低8位

    四、RTCP

    RTCP用于在RTP传输过程中提供传输信息,可以报道RTP传输情况,还可以用来音视频同步,这里就不详细讲解了

    展开全文
  • RTSP&RTP

    千次阅读 2011-12-01 15:42:38
    RTSP RTSP信令的交互我们一般用TCP方式,RTP而是用UDP方式 RTSP 有如下信令: 在这之前建立一个TCP socket用来作信令交互,叫做TCPSockfd OPTIONS: 功能:请求用于返回服务端支持的 RTSP 命令列表...

    RTSP

    RTSP信令的交互我们一般用TCP方式,RTP而是用UDP方式


    RTSP 有如下信令:



    在这之前建立一个TCP socket用来作信令交互,叫做TCPSockfd

    OPTIONS:

    功能:请求用于返回服务端支持的 RTSP 命令列表

    信令交互:

    C->S: 

    OPTIONS * RTSP/1.0
    CSeq: 1
    Require: implicit-play
    Proxy-Require: gzipped-messages


    S->C: 

    RTSP/1.0 200 OK
    CSeq: 1
    Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE

    这个信令不常用,一般client端知道对接的服务器有哪些命令

    CSeq:信令序列号,后面的序列号累计增加。


    DESCRIBE:

    功能:用于请求指定的媒体流的 SDP 描述信息

    信令交互:

    C->S:

    DESCRIBE rtsp://10.50.108.17/vod/957509 RTSP/1.0
    CSeq: 2
    Accept: application/sdp

    S->C:

    RTSP/1.0 200 OK
    CSeq: 2
    Content-Type: application/sdp
    Content-Length: 376


    v=0
    o=- 2890844526 2890842807 IN IP4 10.50.108.17
    s=RTSP Session
    t=0 0
    r=15 0 0 0
    i=
    b=AS:1600
    c=IN IP4 0.0.0.0
    m=video 0 RTP/AVP 33
    a=rtpmap:33 MP2T/90000
    a=range:npt=0.000-566.000//媒体流的开始时间和结束时间,以S为单位


    在descripe之后,我们建立一个UDP的socket,用于RTP包的传输,UDPSockfd,bind到一个端口,比如:26958

    SETUP:

    功能: 命令用于配置数据交付的方法

    信令交互:

    C->S:

    SETUP rtsp://10.50.108.17/vod/957509/ RTSP/1.0
    CSeq: 2
    Transport: RTP/AVP;unicast;client_port=26958-26959//通知server 发送RTP包给client这个端口,后面的26959是rtcp端口,一般没有实现
    User-Agent: CTC RTSP 1.0

    S->C:

    RTSP/1.0 200 OK
    CSeq: 2
    Session: 10145778//rtsp的session,之后的信令都要带上这个参数,并保持一致
    Transport: MP2T/RTP/UDP;unicast;destination=172.19.133.128:26958;control_address=10.50.108.17:554;mode=play;QAM_FRQ=131073


    172.19.133.128:26958 client端IP和port

    10.50.108.17:554 server端IP和port


    setup之后有必要做一个natdetect:私有信令,这个信令是是用UDPSockfd发的,收也是UDPSockfd来收,这样就做了一个nat穿越

    NAT_DETECT

    C->S:

    NAT_DETECT rtsp://10.50.108.17/vod/957509 RTSP/1.0
    CSeq: 1

    S->C:



    PLAY:

    功能:请求流

    C->S

    rtsp://10.50.108.17/vod/957509 RTSP/1.0

    CSeq: 3
    Session: 10145778
    User-Agent: CTC RTSP 1.0


    S->C:

    RTSP/1.0 200 OK
    CSeq: 3
    Session: 10145778
    Scale: 1.0
    Range: npt=0.000-0.000


    PAUSE

    功能:暂停

    C->S

    PAUSE rtsp://10.50.108.17/vod/957509 RTSP/1.0
    CSeq: 5
    Session: 10145778
    User-Agent: CTC RTSP 1.0

    S->C

    RTSP/1.0 200 OK
    CSeq: 5
    Session: 10016005


    GET_PARAMETER:心跳作用

    C->S:

    GET_PARAMETER rtsp://10.50.108.17/vod/957509 RTSP/1.0
    CSeq: 4
    Session: 10145778
    User-Agent: CTC RTSP 1.0

    S->C:

    RTSP/1.0 200 OK
    CSeq: 4
    Session: 10145778


    ANNOUNCE:

    也是用UDPSockfd来收的,用来处理边界值







    RTP头:

    前12个字节在每一个RTP packet中都存在,而一系列的CSRC标记只有存在Mixer时才有。

       version (V): 2 bits
          标明RTP版本号。协议初始版本为0,RFC3550中规定的版本号为2。

       padding (P): 1 bit
          如果该位被设置,则在该packet末尾包含了额外的附加信息,附加信息的最后一个字节表示额外附加信息的长度(包含该字节本身)。该字段之所以存在是因为一些加密机制需要固定长度的数据块,或者为了在一个底层协议数据单元中传输多个RTP packets。

       extension (X): 1 bit
          如果该位被设置,则在固定的头部后存在一个扩展头部,格式定义在RFC3550 5.3.1节。

       CSRC count (CC): 4 bits
          在固定头部后存在多少个CSRC标记。

       marker (M): 1 bit
          该位的功能依赖于profile的定义。profile可以改变该位的长度,但是要保持marker和payload type总长度不变(一共是8 bit)。

       payload type (PT): 7 bits
          标记着RTP packet所携带信息的类型,标准类型列出在RFC3551中。如果接收方不能识别该类型,必须忽略该packet。

       sequence number: 16 bits
          序列号,每个RTP packet发送后该序列号加1,接收方可以根据该序列号重新排列数据包顺序。

       timestamp: 32 bits
          时间戳。反映RTP packet所携带信息包中第一个字节的采样时间。

       SSRC: 32 bits
          标识数据源。在一个RTP Session其间每个数据流都应该有一个不同的SSRC。

       CSRC list: 0 to 15 items, 32 bits each
          标识贡献的数据源。只有存在Mixer的时候才有效。如一个将多声道的语音流合并成一个单声道的语音流,在这里就列出原来每个声道的SSRC。








    展开全文
  • RTMP/RTP/RTSP/RTCP的区别

    2018-11-08 02:04:31
    RTMP/RTP/RTSP/RTCP的区别
  • RTSP/RTP 媒体传输和控制协议

    千次阅读 2016-09-21 16:23:17
    本协议主要基于标准的 IETE 的 RTSP/RTP 以及相关协议, 并针对具体应用定义了部分扩展. 本协议只是当前实现的总结和整理, 具体的协议细节以实际实现为准 2 定义 RTSP实现流协议SDP会话
  • 网络摄像头Rtsp直播方案(二)

    万次阅读 2018-12-21 16:30:24
    上一部分说了Socket通讯的一些东西,这部分就结合代码来说说RTSP交互的过程。 在放实现代码之前先说说概念上的东西吧,关于RTSP这个流媒体网络协议。RTSP作为一个应用层协议,提供了一个可供扩展的框架,使得流媒体...
  • 浏览器播放RTSP摄像头视频

    万次阅读 热门讨论 2019-01-30 16:09:30
    一、项目需求,需要在chrome浏览器中播放rtsp协议的摄像头视频流 二、思路: 1、chrome已经不支持插件了,所以排除一切插件的思路; 2、浏览器目前停留在支持rtmp协议,hls协议流视频阶段,还没开始支持rtsp协议,...
  • RTSP传输介绍

    千次阅读 2019-04-26 16:55:17
    RTSP(Real-Time Stream Protocol)协议是一个基于文本的多媒体播放控制协议,属于应用层。RTSP以客户端方式工作,对流媒体提供播放、暂停、后退、前进等操作。该标准由IETF指定,对应的协议是RFC2326。 RTSP作为一个...
  • FFMPEG发布RTSP

    万次阅读 2017-04-07 14:01:23
    视频上传 ffmpeg -i a.mp4 -vcodec libx264 -f rtsp rtsp://127.0.0.1:5050/ok 视频接收 ffmpeg -rtsp_flags listen -f rtsp -i rtsp://127.0.0.1:5050/ok b.mp4
  • RTSP 在线测试地址

    万次阅读 热门讨论 2019-02-12 17:06:50
    亲测可用 rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
  • 各品牌网络监控摄像头RTSP地址查询

    万次阅读 2019-12-09 22:16:53
    各品牌网络监控摄像头RTSP地址查询
  • 关键字:rtsp url 用户名 密码 user password rtsp://[[:]@][:][/]
  • 公司做监控的,H5播放RTSP流,不要用插件(flash,vlc等),现在看到有一个h5stream-master的好像不是我想要的,html5_rtsp_player-master说得很有道理,资料太少,安装都安装不上,而且好像要收费,有没有人做过有更好...
  • RTSP视频测试地址

    万次阅读 热门讨论 2020-09-17 18:06:28
    1、rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov 一段动画片 2、rtsp://218.204.223.237:554/live/1/66251FC11353191F/e7ooqwcfbqjoo80j.sdp 拱北口岸珠海过澳门大厅
  • VLC搭建RTSP直播流,图文介绍

    万次阅读 热门讨论 2020-05-03 17:10:14
    将一个视频转成rtsp流,通过vlc播放器,搭建一个rtsp服务器,让rtsp客户端去访问这个视频的rtsp流 1 需要有vlc播放器,我的版本如下 2 媒体 --> 流 3 添加视频文件 ,点击添加一个mp4 文件 4 选择串流,...
  • 现在在做流媒体项目,要求java搭建RTSP服务器。但是本人新手第一次接触,确切的是听说。所以在此希望各位兄弟介绍下java实现RTSP服务器的思路。。。。 当然,如果有高人共享代码,本人不胜感激。。。。
  • 1.推送rtsp视频流 ffmpeg -i rtsp://admin:admin1234@192.168.1.64:554/h264/ch1/sub/av_stream -codec copy -f rtsp rtsp://192.168.1.223:554/stream/ 2.推送r视频文件到rtsp服务器 ffmpeg -re -i sff.mp4 -...
1 2 3 4 5 ... 20
收藏数 35,797
精华内容 14,318
关键字:

rtsp