转载于:http://itindex.net/detail/51966-%E6%B5%B7%E5%BA%B7-rtsp-%E5%AE%A2%E6%88%B7%E7%AB%AF

海康相机RTSP连接代码分析

最近在做海康相机rtsp连接获取音视频的工作,现在介绍一下分析过程和源码。

【源码在我上传的共享资料中:   http://download.csdn.net/detail/zhouyongku/8203521

一、基本原理

RTSP客户端去连接服务器的最基本步骤如下:

(1)分析url中的端口号,创建一个与服务器[S-PORT]端口号的TCP连接用于RTSP命令交互 (2)执行RTSP命令请求,告诉服务器可以连接到本地的端口[C-PORT]进行数据发送 (3)客户端从本地[C-PORT]读取数据

二、研究步骤

来研究一下海康相机的RTSP数据是怎么交互的

(1)打开Wireshark,选择"抓包"->"网络接口"->选择网卡->“开始”,在"过滤“栏输入"rtsp",屏蔽不相关信息。

(2)打开VLC播放器,输入海康相机RTSP地址

例如:【rtsp://admin:12345@192.168.1.145:554/MPEG-4/ch2/main/av_stream】

(3)播放几秒后再点击停止播放,退出VLC播放器。 (4)分析Wireshark数据

 

三、RTSP协议过程分析

1、RTSP协议梗概

就这几个简单的交互命令就能实现RTSP对接,C代表Client S代表Server

例如:C1-客户端发的第一个命令 S1-服务器响应的第一个回复

【C1】OPTIONS rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream RTSP/1.0RTSP

【S1】Reply: RTSP/1.0 200 OK RTSP 【C2】DESCRIBE rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream RTSP/1.0RTSP 【S2】Reply: RTSP/1.0 401 Unauthorized RTSP 【C3】DESCRIBE rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream RTSP/1.0RTSP 【S3】Reply: RTSP/1.0 200 OK, with session descriptionRTSP/SDP 【C4】SETUP rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=1 RTSP/1.0RTSP 【S4】Reply: RTSP/1.0 200 OK RTSP 【C5】SETUP rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=2 RTSP/1.0RTSP 【S5】Reply: RTSP/1.0 200 OK RTSP 【C6】PLAY rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/ RTSP/1.0RTSP 【S6】Reply: RTSP/1.0 200 OK RTSP 【C7】GET_PARAMETER rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/ RTSP/1.0RTSP 【S7】Reply: RTSP/1.0 200 OK RTSP 【C8】TEARDOWN rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/ RTSP/1.0RTSP 【S8】Reply: RTSP/1.0 200 OK RTSP

2、请求OPTION

【C1-OPTION】

Request: OPTIONS rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream RTSP/1.0\r\n

CSeq: 2\r\n

User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)\r\n

\r\n

询问RTSP服务器有哪些命令可以使用

【S1-REPLY】

Response: RTSP/1.0 200 OK\r\n

CSeq: 2\r\n

Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER\r\n

Date:  Thu, Nov 27 2014 11:59:41 GMT\r\n

服务器回应客户端的请求。这个回应第一行为OK,则表明服务器接受查询命令,并且反馈给客户端信息,可以使用的命令有:OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER,则下一步就可以向服务器发送这些命令,如果没有,则服务器不接收这些命令。

3、无验证请求资源描述DESCRIBE

【C2-DESCRIBE】

Request: DESCRIBE rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream RTSP/1.0\r\n

CSeq: 3\r\n

User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)\r\n

Accept: application/sdp\r\n

\r\n

请求RTSP服务器描述自身有哪些音视频资源

【S2-REPLY】

Response: RTSP/1.0 401 Unauthorized\r\n   CSeq: 3\r\n   WWW-Authenticate: Digest realm="4419b727ab09", nonce="66bb9f0bf5ac93a909ac8e88877ae727", stale="FALSE"\r\n   WWW-Authenticate: Basic realm="4419b727ab09"\r\n

Date:  Thu, Nov 27 2014 11:59:41 GMT\r\n

服务器回应客户端的请求。第一行为Unauthorized,表明认证不成功服务器拒绝给出拥有的资源,因此我们需要再次发送认证的请求到服务器,则服务器才能给出拥有的资源

4、认证请求资源描述DESCRIBE

【C3-DESCRIBE】

Request: DESCRIBE rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream RTSP/1.0\r\n

CSeq: 4\r\n

Authorization: Digest username="admin", realm="4419b727ab09", nonce="66bb9f0bf5ac93a909ac8e88877ae727", uri="rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream", response="108084646408d21aa255664781c886fc"\r\n

User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)\r\n

Accept: application/sdp\r\n

\r\n

发送具有认证标识的信息到服务器,去获取服务器的资源列表。怎样的格式算正确认证的信息?这个关键在于response字段。[S2-REPLY]中反馈了两个信息realm="4419b727ab09", nonce="66bb9f0bf5ac93a909ac8e88877ae727",

**************************************response区域的计算规则如下***********************************

(1)当password为MD5编码,则

response = md5(<password>:<nonce>:md5(<cmd>:<url>));

(2)当password为ANSI字符串,则

response = md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<uri>));

***********************************************************************************************************

其中 password=密码,nonce=服务器返回的nonce,cmd=当前命令(DESCRIBE、SETUP等),realm=服务器返回的reaml,uri=请求的uri地址.当服务器接收到response为108084646408d21aa255664781c886fc的时候,服务器也会用这一套公式去计算,当发现计算出的值与客户端提供的值吻合的时候,则表明用户名和密码校验成功!

  1. /*MD5加密函数*/
  1. int md5_hash(const void *buff, size_t len, char *hexsum);
  1. <span style="white-space:pre"> </span>/*发送具有response认证的describe命令函数*/
  1. void RtspRequest::SendRegisterRequest(string requestType)
  1. {
  1. string requestCmd;
  1. char cseq[256];
  1. char session[256];
  1. char author[500] = { 0 };
  1. char acc[200] = { 0 };
  1. char szInput[200] = { "" };
  1. char szOutput[200] = { 0 };
  1. char szMd5Pwd[200] = { 0 };
  1. char szmd5methorduri[200] = { 0 };
  1. m_CSeq++;
  1.  
  1. if (m_SetupName.length())
  1. {
  1. requestCmd = requestType;
  1. requestCmd += " ";
  1. requestCmd += m_RequestsMrl;
  1. requestCmd += "/";
  1. requestCmd += m_SetupName;
  1. requestCmd += " RTSP/1.0";
  1.  
  1. m_SetupName = "";
  1. }
  1. else
  1. {
  1. requestCmd = requestType;
  1. requestCmd += " ";
  1. requestCmd += m_RequestsMrl;
  1. requestCmd += " RTSP/1.0";
  1. }
  1.  
  1.  
  1. //当password为ANSI字符串 response = md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<uri>));
  1. //md5(<username>:<realm>:<password>)=md5(admin:4419b727ab09:12345)=fa47d934c754db5ebebd9b42a4412073
  1. sprintf_s(szInput, 200, "%s:%s:%s", m_uername.c_str(), m_realm.c_str(), m_password.c_str());
  1. md5_hash(szInput, strlen(szInput), szMd5Pwd);
  1. //md5(<cmd>:<uri>)=md5(DESCRIBE:rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream) =0b0a4e77e852876bdfdf6ecb72ba3900
  1. sprintf_s(szInput, 200, "DESCRIBE:%s", m_RequestsMrl.c_str());
  1. md5_hash(szInput, strlen(szInput), szmd5methorduri);
  1. //md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<uri>));
  1. //=md5(fa47d934c754db5ebebd9b42a4412073:66bb9f0bf5ac93a909ac8e88877ae727:0b0a4e77e852876bdfdf6ecb72ba3900)
  1. <span style="white-space:pre"> </span>//=108084646408d21aa255664781c886fc
  1. //关于这一条,http://www.3464.com/Tools/MD5/index.asp 网站给出的结论则不一致:98f90a583e5c436f83da956c9b00767b 
  1. <span style="white-space:pre"> </span>//我的代码给出的值与VLC和其它工具给出的值完全匹配
  1. sprintf_s(szInput, 200, "%s:%s:%s", szMd5Pwd, m_nonce.c_str(), szmd5methorduri);
  1. md5_hash(szInput, strlen(szInput), szOutput);
  1. m_response = szOutput;
  1.  
  1. _snprintf(cseq, 256, "CSeq: %u", m_CSeq);
  1. _snprintf(author, 500, "Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
  1. m_uername.c_str(), m_realm.c_str(), m_nonce.c_str(), m_RequestsMrl.c_str(), m_response.c_str());
  1. _snprintf(acc, 500, "Accept: application/sdp");
  1.  
  1. if (requestType.compare("TEARDOWN") == 0)
  1. m_Session = 0;
  1. _snprintf(session, 256, "Session: %I64u", m_Session);
  1.  
  1. Write(requestCmd.c_str());
  1. Write(cseq);
  1. Write(author);
  1. Write("User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)");
  1. Write(acc);
  1. if (m_Session > 0)
  1. Write(session);
  1.  
  1. WriteFields();
  1. Write("");
  1. }

【S3-REPLY】

Response: RTSP/1.0 200 OK\r\n

CSeq: 4\r\n

Content-type: application/sdp

Content-Base: rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/\r\n

Content-length: 672

\r\n

Session Description Protocol

Session Description Protocol Version (v): 0

Owner/Creator, Session Id (o): - 1417089581269778 1417089581269778 IN IP4 192.168.1.145

Session Name (s): Media Presentation

E-mail Address (e): NONE

Bandwidth Information (b): AS:5100

Time Description, active time (t): 0 0

Session Attribute (a): control:rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/

Media Description, name and address (m): video 0 RTP/AVP 96

Bandwidth Information (b): AS:5000

Media Attribute (a): control:rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=1

Media Attribute (a): rtpmap:96 H264/90000

Media Attribute (a): fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z0KAH4iLUCgC3QgAADhAAAr8gCA=,aM44gA==

Media Description, name and address (m): audio 0 RTP/AVP 0

Bandwidth Information (b): AS:50

Media Attribute (a): control:rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=2

Media Attribute (a): rtpmap:0 PCMU/8000

Media Attribute (a): Media_header:MEDIAINFO=494D4B48010100000400010010710110401F000000FA000000000000000000000000000000000000;

Media Attribute (a): appversion:1.0

首先第一行给了OK,表明上一个命令成功--DESCRIBE成功得到服务器认证

其次,给出了服务器的媒体信息-具有两路码流--音频(audio)和视频(video) 并给出了请求两路数据的地址

5、请求视频资源

【C4-SETUP】

Request: SETUP rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=1 RTSP/1.0\r\n

CSeq: 5\r\n

Authorization: Digest username="admin", realm="4419b727ab09", nonce="66bb9f0bf5ac93a909ac8e88877ae727", uri="rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/", response="dfd7cfc85819d15d622e4491ad12217d"\r\n

User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)\r\n

Transport: RTP/AVP;unicast;client_port=56732-56733

\r\n

请求获取流媒体服务器上的视频资源 并告知服务器可以往客户端56732端口发送视频数据,56733为RTCP接收端口,发送方式为单播。传输方式为UDP

**********************传输方式与Transport string的对应关系**********************

UDP传输:Transport:RTP/AVP

TCP传输:Transport:RTP/AVP/TCP

RAW UDP传输:Transport:RAW/RAW/UDP

****************************************************************************************

【S4-REPLY】

Response: RTSP/1.0 200 OK\r\n

CSeq: 5\r\n

Session: 1350856257;timeout=60

Transport: RTP/AVP;unicast;client_port=56732-56733;server_port=8208-8209;ssrc=4a3a67d5;mode="play"

Date:  Thu, Nov 27 2014 11:59:41 GMT\r\n

\r\n

服务器同意发送视频数据给客户端 56732为视频接收端,56733为RTCP接收端口,发送方式为单播。传输方式为UDP

6、请求音频资源

【C5-SETUP】

Request: SETUP rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=2 RTSP/1.0\r\n

CSeq: 6\r\n

Authorization: Digest username="admin", realm="4419b727ab09", nonce="66bb9f0bf5ac93a909ac8e88877ae727", uri="rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/", response="dfd7cfc85819d15d622e4491ad12217d"\r\n

User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)\r\n

Transport: RTP/AVP;unicast;client_port=56734-56735

Session: 1350856257

\r\n

请求获取服务器上的音频资源 并告知服务器可以往客户端56734端口发送视频数据,56735为RTCP接收端口,发送方式为单播。传输方式为UDP

【S5-REPLY】

Response: RTSP/1.0 200 OK\r\n

CSeq: 6\r\n

Session: 1350856257;timeout=60

Transport: RTP/AVP;unicast;client_port=56734-56735;server_port=8226-8227;ssrc=232306b5;mode="play"

Date:  Thu, Nov 27 2014 11:59:41 GMT\r\n

\r\n

服务器同意发送音频数据给客户端 56734为视频接收端,56735为RTCP接收端口,发送方式为单播。传输方式为UDP

7、开始数据接收

【C6-PLAY】

Request: PLAY rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/ RTSP/1.0\r\n

CSeq: 7\r\n

Authorization: Digest username="admin", realm="4419b727ab09", nonce="66bb9f0bf5ac93a909ac8e88877ae727", uri="rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/", response="4c4e89a5894d2b208489fde1aeaf9e44"\r\n

User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)\r\n

Session: 1350856257

Range: npt=0.000-\r\n

\r\n

告知服务器一切准备就绪,数据可以发过来了!come on baby!

【S6-REPLY】

Response: RTSP/1.0 200 OK\r\n

CSeq: 7\r\n

Session: 1350856257

RTP-Info: url=rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=1;seq=31283;rtptime=1712470431,url=rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/trackID=2;seq=3370;rtptime=1846536290\r\n

Date:  Thu, Nov 27 2014 11:59:41 GMT\r\n

\r\n

服务器告知客户端,朋友我已经送数据过来了,你可以接收了!

这个时候我们打开Wireshark,在过滤栏输入rtp,可以看到如下数据,表明服务器已经向客户端的56732、56734端口发送数据

RTP拆包到图像显示和音频播放,会在我的下一篇博客中详细解释

8、关闭播放

【C7-TEARDOWN】

Request: TEARDOWN rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/ RTSP/1.0\r\n

Method: TEARDOWN

URL: rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/

CSeq: 9\r\n

Authorization: Digest username="admin", realm="4419b727ab09", nonce="66bb9f0bf5ac93a909ac8e88877ae727", uri="rtsp://192.168.1.145:554/MPEG-4/ch2/main/av_stream/", response="af15346442151a51f1478da1858778d5"\r\n

User-Agent: LibVLC/2.1.3 (LIVE555 Streaming Media v2014.01.21)\r\n

Session: 1350856257

\r\n

关闭数据传输 释放服务器资源 如果需要重新获取码流 则需要从1~6再来一次

【S7-REPLY】

Response: RTSP/1.0 200 OK\r\n

Status: 200

CSeq: 9\r\n

Session: 1350856257

Date:  Thu, Nov 27 2014 11:59:42 GMT\r\n

\r\n

服务器已经成功关闭当前链接

rtsp学习参考资料1的更多相关文章

  1. rtsp 学习

    1.1.   RTSP协议简介 一种应用层协议,可基于tcp或udp协议. Real Time Streaming Protocol或者RTSP(实时流媒体协议),是由Real network 和 N ...

  2. 与NS2一起度过第一个圣诞夜!(NS2入门学习参考资料)

    Merry xmas! 安装好NS2后正式开始学习NS2啦,先转发一哥们的博客内容,慢慢看! 一). NS常用基本网站         1. 寻求问题答案最好的地方.           http:/ ...

  3. HTML5学习参考资料整理

    给大家推荐一下学习研究HTML5必备的一些个网站,更加有利于大家对HTML5的学些和研究.如果各位童鞋还有更多的,欢迎投递资源给我们,也可以支持 我们,让我们利用大家的力量收集更多的HTML5学习资料 ...

  4. Presto 学习参考资料

    Presto 文档资料: 0.1版:Presto 0.100 Documentation 0.213版:Presto 0.213 Documentation 阿里云 presto 学习资料:https ...

  5. Mongoose学习参考资料

    我们学习node操作mongodb数据库时,可能经常要用到MongoDB 数据库的模型工具Mongoose,下面是我整理的一些学习资料: 番外篇之——使用 Mongoose:https://githu ...

  6. Python - 学习参考资料

    官方reference: 1.Numpy的API Reference https://docs.scipy.org/doc/numpy/reference/routines.html 2.SciPy的 ...

  7. rtsp学习----海康RTSP客户端连接深入分析

    转载于:http://blog.csdn.net/zhouyongku/article/details/41546789 海康相机RTSP连接代码分析 最近在做海康相机rtsp连接获取音视频的工作,现 ...

  8. 词向量word2vec(图学习参考资料)

    介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现. 项目链接: https://aistudio.baidu.com/aistudio/projectdetail/500940 ...

  9. spring学习参考资料

    http://www.cnblogs.com/ooooevan/p/5795456.html http://blog.csdn.net/hongjun1847/article/details/2053 ...

随机推荐

  1. SuperSocket实例

    下载地址:https://files.cnblogs.com/files/xixixing/ConsoleApp.zip 创建控制台应用程序:ConsoleApp MySession.cs using ...

  2. MySQL多表查询总结

    MySQL术语: Redundacncy(冗余):存储两次或多次数据,以便实现快速查询. Primary Key(主键):主键是唯一的.表中每条记录的唯一标识. Foreign Key(外键):用于连 ...

  3. Intel Code Challenge Final Round D. Dense Subsequence 二分思想

    D. Dense Subsequence time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  4. CSS简单选择器的学习笔记

    我们知道通过CSS定义页面样式的时候要用到各种各样的选择器,正确的使用选择器是我们能够正确使用CSS做页面样式的基础.下面是我学习选择器的一个简易笔记,举一些简单的例子. 为了方便展示,我选择在内部的 ...

  5. 泛目录/泛目录程序/泛目录解析/莲花泛目录解析/寄生虫程序/黑帽SEO

    莲花泛目录程序强大之处: 蜘蛛抓取繁殖新页面,对搜索引擎更加友好采用PHP7语言开发,代码执行率高.蜘蛛抓取目录页面触发繁殖新页面,诱导搜索引擎爬虫爬行更多目录页面, 并且在本地生成缓存页面,搜索引擎 ...

  6. centos7下面安装tomcat

    前言 对于一个新安装的 centos 系统来说,是没有 tomcat 服务器的.用下面的命令可以查看 tomcat 服务的状态. systemctl status tomcat.service//或者 ...

  7. Lombok Pojo默认初始值问题

    Lombok以注解形式来简化java代码,提高开发效率.比如我们常用的@Builder.@Data.@AllArgsConstructor.@NoArgsConstructor.@ToString等. ...

  8. DOM操作的性能优化

    DOM操作的真正问题在于 每次操作都会出发布局的改变.DOM树的修改和渲染. React解决了大面积的DOM操作的性能问题,实现了一个虚拟DOM,即virtual DOM,这个我们一条条讲. 所以关于 ...

  9. bash脚本获取绝对路径的最后一个目录名称

    比如绝对路径是/root/autoHls/streamID 因为脚本里面想直接用这个streamID来推流 下面是方法 #!/bin/bash dir="/root/autoHls" ...

  10. IDEA + tomcat 远程调试(JPDA)

    一.修改 tomcat 配置,启动远程调试 Linux(bin\catalina.sh) # 将 localhost 改为 0.0.0.0 if [ -z "$JPDA_ADDRESS&qu ...