C表示rtsp客户端,S表示rtsp服务端
C->S:OPTION request //询问S有哪些指令可用
S->C:OPTION response //S回应信息中包括提供的所有可用指令
C->S:DESCRIBE request //要求得到S提供的媒体初始化描述信息
S->C:DESCRIBE response //S回应媒体初始化描述信息,主要是sdp
C->S:SETUP request //设置会话的属性,以及传输模式,提醒S建立会话
S->C:SETUP response //S建立会话,返回会话标识符,以及会话相关信息
C->S:PLAY request //C请求播放
S->C:PLAY response //S回应该请求的信息
S->C:发送流媒体数据
C->S:TEARDOWN request //C请求关闭会话
S->C:TEARDOWN response //S回应该请求
OPTION URL RTSP版本号
CSeq: CSeq号(每发一条方法加一)
User-Agent:
RTSP版本号 状态码 状态字段
CSeq: 服务端发的CSeq号
Date: 时间 时区
Public: 可用方法
DESCRIBE URL RTSP版本号
CSeq: CSeq号(每发一条方法加一)
User-Agent:
Accept:
RTSP版本号 状态码 状态字段
CSeq: 服务端发的CSeq号
Date: 时间 时区
WWW-Authenticate: Digest realm=" ", nonce=""
DESCRIBE URL RTSP版本号
CSeq: CSeq号(每发一条方法加一)
Authorization: Digest username="", realm=" ", nonce="", uri=" ", response=" "
User-Agent:
Accept:
RTSP版本号 状态码 状态字段
CSeq: 服务端发的CSeq号
Date: 时间 时区
Content-Base: URL(用于拼接具体通道号URL的主URL,注意结尾带/)
Content-Type: 客户端发来的Accept
Content-Length: SDP包长度
v=0 //SDP版本号
o=- 1558173732855598 1 IN IP4 192.168.0.46 //[username] [session id] [version] [network type] [address type] [ip address]。 [username]没有,就填-。[session id]填写NTP时间戳。[version]填1。[network type] 一般为IN 。[address type]一般为IP4 。[ip address]填服务端IP地址。
s=IChinaE IPC Camera Stream//[session name ]按照用户自定义需求填写
i=stream1//[session info]按照相机url填写,通道几就写stream几,不同相机url不同
t=0 0//[start time] [end time] 实时流都填0
a=tool:LIVE555 Streaming Media v2010.07.29//a字段是可选字段,这6个a字段除了x-qt-text-inf要根据不同的通道号改变,其他都是固定不变的,也是live555添加的,为了安全起见先固定加上这些字段
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:IChinaE IPC Camera Stream
a=x-qt-text-inf:stream1
m=video 0 RTP/AVP 96//[media] [port] [transport] [fmt list] 。[media] vedio或audio 。[port]先默认填0 。[transport]先默认填RTP/AVP。[fmt list]表示这路数据的编码类型,0-95是已定义好的编码类型,如果是这些类型,则填写相应的编号,否则,填写其他值并在rtpmap中指定编码类型
c=IN IP4 0.0.0.0//默认这样填
b=AS:12000//[modifier]CT(总带宽)或AS(单个媒体的最大带宽)。[bandwidth]带宽值
a=rtpmap:96 H264/90000//若m的[fmt list]填写了自定义编号,则在这里指定自定义编号的编码类型和时钟速率,h264为90000
a=fmtp:96 packetization-mode=1;profile-level-id=64002A;sprop-parameter-sets=Z2QAKq2EAQwgCGEAQwgCGEAQwgCEO1A8ARPyzcBAQECAAAAAAQ==,aO48sA==//指定对应编号的通道的信息。[packetization-mode]为1代表I帧要拆成多个包发送,默认填1 。[profile-level-id]重要程度,[ sprop-parameter-sets]pps和sps,计算方法下边给出。
a=control:track1//代表这一路码流的通道号,不同相机这个也不同
m=audio 0 RTP/AVP 0//余下信息同上
c=IN IP4 0.0.0.0
b=AS:64
a=control:track2
response = md5(md5(username:realm:password):nonce:md5(method:url));
SETUP URL RTSP版本号
CSeq: CSeq号(每发一条方法加一)
Transport: 连接方式;unicast;client_port=端口号或识别码
User-Agent:
RTSP版本号 状态码 状态字段
CSeq: 服务端发的CSeq号
Date: 时间 时区
Transport: 连接方式;unicast;destination=客户端IP;source=服务端IP;服务端和客户端的端口号或识别码
Session: 8位16进制随机数,相同会话的session相同
PLAY URL RTSP版本号
CSeq: CSeq号(每发一条方法加一)
Session:
Range: npt=0.000-(实时流的ntp时间为0.000-,否则格式为起始时间-结束时间)
User-Agent:
RTSP版本号 状态码 状态字段
CSeq: 服务端发的CSeq号
Date: 时间 时区
Range: npt=0.000-
Session:
RTP-Info: url=;seq=;rtptime=,url=;seq=;rtptime=
(因为一般都是音视频两路数据,所以会有两组反馈数据)
TEARDOWN URL RTSP版本号
CSeq: CSeq号(每发一条方法加一)
Session:和之前命令的session保持一致
User-Agent:
RTSP版本号 状态码 状态字段
CSeq: 服务端发的CSeq号
Date: 时间 时区
M:8位,固定设置为0x24
C:8位,通道号,和SETUP中设置的通道号对应
L:16位,不包括RTSP头,直到载荷结束的总字节数
RTP头格式如下所示
unsigned int t_sec = (freq*tv.tv_sec);
timestamp = t_sec + (unsigned int)((2.0* freq *tv.tv_usec + 1000000.0)/2000000) + t_base
直接把数据接到CSRC后边作为载荷即可。
如果帧长大于MTU长度,则使用FU-A方式分片发送
如果帧长小于MTU长度,则使用单一NAL单元模式一次发送
F:默认设置成0
NRI:默认设置为3
Type:NAL单元模式设置为1,FU-A分片模式设置为28
FU header只在FU-A模式下才有
S:start 如果这一包数据是这一帧数据的开始包,则设为1,否则设为0
E:end 如果这一包数据是这一帧数据的结束包,则设为1,否则设为0
R:reseived 默认设为0
Type:设为和FU indicator中相同的值,帧实际类型,PPS,SPS :7 I帧:1
struct timeval timeNow;
gettimeofday(&timeNow, NULL);
MSW = timeNow.tv_sec + 0x83AA7E80;//算出来的结果可能由于时区不同而差8小时
double temp = (timeNow.tv_usec/15625.0)*0x04000000;
LSW = (unsigned int)(temp+0.5);
总结整套交互流程中的注意点
1.describe方法若有鉴权,则服务端会收到两次descibe,第一次是不带鉴权的,服务端以realm和nonce质询,第二次describe若鉴权通过,则返回sdp消息,注意sdp消息中不同相机的组包信息不同,要根据相机而定。
2.setup方法由客户端发起,有可能服务端在describe时告诉客户端有两路流,但客户端只请求一路流,比如vlc就会请求全部的流,但onvif工具会只请求视频
3.setup时确定rtp/.rtcp的发送方式是udp还是tcp。若是tcp则rtp/rtcp都从信令端口发送,而且rtp/rtcp要加4字节rtsp头。udp方式的端口号创建要求rtp是偶数端口,rtcp是它下一个端口
4.rtp/rtcp中的时间戳如果发送错误会导致vlc拉流失败
5.回放流中的play会带时间段,回放流还存在很多问题,有遗留问题欢迎交流