使用两种方式进行推流,udp 和tcp,必须先理解udp 和tcp推流方式的不同
udp 推流
./ffmpeg -re -i d:/test.mp4 -c copy -av -f rtsp rtsp://192.168.0.24/live/1
OPTIONS rtsp://192.168.0.24:554/live/1 RTSP/1.0
CSeq: 1
User-Agent: Lavf60.16.100
RTSP/1.0 200 OK
CSeq: 1
Date: Sat, Sep 28 2024 01:33:39 GMT
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, ANNOUNCE, RECORD, SET_PARAMETER, GET_PARAMETER
Server: ViewPointserver
ANNOUNCE rtsp://192.168.0.24:554/live/1 RTSP/1.0
Content-Type: application/sdp
CSeq: 2
User-Agent: Lavf60.16.100
Content-Length: 2xx
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 192.168.0.24
t=0 0
a=tool:CRYPT
m=video 0 RTP/AVP 96
b=AS:13152
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z01AKZWQB4AiflwEQAAA+gAAMNQh,aOuPIA==; profile-level-id=4D4029
a=control:streamid=0
RTSP/1.0 200 OK
CSeq: 2
Date: Sat, Sep 28 2024 01:33:39 GMT
Server: ViewPointserver
Session: NOzALlDctEdM
SETUP rtsp://192.168.0.24:554/live/1/streamid=0 RTSP/1.0
Transport: RTP/AVP/UDP;unicast;client_port=28590-28591;mode=record
CSeq: 3
User-Agent: Lavf60.16.100
Session: NOzALlDctEdM
RTSP/1.0 200 OK
CSeq: 3
Date: Sat, Sep 28 2024 01:33:39 GMT
Server: ViewPointServer
Session: NOzALlDctEdM
Transport: RTP/AVP/UDP;unicast;client_port=28590-28591;mode=record;server_port=31006-31007;ssrc=00000000
RECORD rtsp://192.168.0.24:554/live/1 RTSP/1.0
Range: npt=0.000-
CSeq: 4
User-Agent: Lavf60.16.100
Session: NOzALlDctEdM
RTSP/1.0 200 OK
CSeq: 4
Date: Sat, Sep 28 2024 01:33:39 GMT
RTP-Info: url=rtsp://192.168.0.24:554/live/1/streamid=0
Server: ViewPointServer,build time:2024-04-11T13:25:49)
Session: NOzALlDctEdM
RTSP 交互日志的分析:
一、OPTIONS 请求与响应
首先,客户端向服务器 rtsp://192.168.0.24:554/live/1 发送了一个 OPTIONS 请求。这个请求通常用于获取服务器支持的方法列表。
请求中包含了一些信息:
CSeq: 1 表示这个请求的序列号为 1。
User-Agent: Lavf60.16.100 表明了发出请求的客户端软件信息。
服务器响应:
RTSP/1.0 200 OK 表示请求成功。
CSeq: 1 与请求中的序列号对应。
Date: Sat, Sep 28 2024 01:33:39 GMT 给出了响应的时间。
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, ANNOUNCE, RECORD, SET_PARAMETER, GET_PARAMETER 告知客户端服务器支持的方法列表。
Server: 显示了服务器的软件信息。
二、ANNOUNCE 请求与响应
客户端发送 ANNOUNCE 请求,通常用于向服务器提供媒体描述信息。注意sdp本身也是一个协议
请求包含:
Content-Type: application/sdp 表明请求体中的内容类型为 SDP(Session Description Protocol)。
CSeq: 2 序列号为 2。
User-Agent: Lavf60.16.100 客户端软件信息。
Content-Length: 299 表示请求体的长度为 299 字节。
请求体中是 SDP 描述信息,包括版本号、源信息、媒体信息等。
服务器响应:
RTSP/1.0 200 OK 请求成功。
CSeq: 2 对应请求的序列号。
Date: Sat, Sep 28 2024 01:33:39 GMT 响应时间。
Server:ViewPointServer 服务器软件信息。
Session: NOzALlDctEdM 分配给这个会话的唯一标识符。
三、SETUP 请求与响应
客户端发送 SETUP 请求,用于建立媒体传输连接。
请求包含:
Transport: RTP/AVP/UDP;unicast;client_port=28590-28591;mode=record 指定了传输协议、传输方式、客户端端口和模式。
CSeq: 3 序列号为 3。
User-Agent: Lavf60.16.100 客户端软件信息。
Session: NOzALlDctEdM 使用之前分配的会话标识符。
服务器响应:
RTSP/1.0 200 OK 请求成功。
CSeq: 3 对应请求的序列号。
Date: Sat, Sep 28 2024 01:33:39 GMT 响应时间。
Server: 服务器软件信息。
Session: NOzALlDctEdM 会话标识符。
Transport: RTP/AVP/UDP;unicast;client_port=28590-28591;mode=record;server_port=31006-31007;ssrc=00000000 服务器返回的传输信息,包括服务器端口和同步源标识符。
四、RECORD 请求与响应
客户端发送 RECORD 请求,开始录制媒体流。
请求包含:
Range: npt=0.000- 可能指定了录制的时间范围。
CSeq: 4 序列号为 4。
User-Agent: Lavf60.16.100 客户端软件信息。
Session: NOzALlDctEdM 会话标识符。
服务器响应:
RTSP/1.0 200 OK 请求成功。
CSeq: 4 对应请求的序列号。
Date: Sat, Sep 28 2024 01:33:39 GMT 响应时间。
RTP-Info: url=rtsp://192.168.0.24:554/live/1/streamid=0 提供了 RTP 流的信息。
Server: ViewPointServer 观点服务器软件信息。
Session: NOzALlDctEdM 会话标识符。
总体来说,交互展示了客户端使用 RTSP 协议与服务器进行交互的过程,包括获取服务器支持的方法、提供媒体描述、建立传输连接和开始录制媒体流等步骤。
tcp rtsp 推流
使用ffmpeg 进行推流,关键字如下
-rtsp_transport tcp
注意rtsp_transport 的位置,不要放在开头,要在v 和 a 的后面, rtsp协议的前面
./ffmpeg -re -i d:/test.mp4 -c:v copy -c:a copy -rtsp_transport tcp -f rtsp rtsp://192.168.0.24/live/1
包如下
OPTIONS rtsp://192.168.0.24:8554/live/1 RTSP/1.0
CSeq: 1
User-Agent: Lavf60.16.100
RTSP/1.0 200 OK
CSeq: 1
Public: DESCRIBE, ANNOUNCE, SETUP, PLAY, RECORD, PAUSE, GET_PARAMETER, TEARDOWN
Server: gortsplib
ANNOUNCE rtsp://192.168.0.24:8554/live/1 RTSP/1.0
Content-Type: application/sdp
CSeq: 2
User-Agent: Lavf60.16.100
Content-Length: 372
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 192.168.0.24
t=0 0
a=tool:libavformat 60.16.100
m=video 0 RTP/AVP 96
a=rtpmap:96 H265/90000
a=fmtp:96 sprop-vps=QAEMAf//AUAAAAMAgAAAAwAAAwC0rAk=; sprop-sps=QgEBAUAAAAMAgAAAAwAAAwC0oAKAgC0WWuSytmuXE0BAAAADAEAAAAUP4sSg; sprop-pps=RAHA4w8DMkAA
a=control:streamid=0
m=audio 0 RTP/AVP 0
b=AS:64
a=control:streamid=1
RTSP/1.0 200 OK
CSeq: 2
Server: gortsplib
SETUP rtsp://192.168.0.24:8554/live/1/streamid=0 RTSP/1.0
Transport: RTP/AVP/TCP;unicast;interleaved=0-1;mode=record
CSeq: 3
User-Agent: Lavf60.16.100
RTSP/1.0 200 OK
CSeq: 3
Server: gortsplib
Session: 541f23a1bc914e78bc405253a7f8c037
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
SETUP rtsp://192.168.0.24:8554/live/1/streamid=1 RTSP/1.0
Transport: RTP/AVP/TCP;unicast;interleaved=2-3;mode=record
CSeq: 4
User-Agent: Lavf60.16.100
Session: 541f23a1bc914e78bc405253a7f8c037
RTSP/1.0 200 OK
CSeq: 4
Server: gortsplib
Session: 541f23a1bc914e78bc405253a7f8c037
Transport: RTP/AVP/TCP;unicast;interleaved=2-3
RECORD rtsp://192.168.0.24:8554/live/1 RTSP/1.0
Range: npt=0.000-
CSeq: 5
User-Agent: Lavf60.16.100
Session: 541f23a1bc914e78bc405253a7f8c037
RTSP/1.0 200 OK
CSeq: 5
Server: gortsplib
Session: 541f23a1bc914e78bc405253a7f8c037
接下来后面就是rtp的包直接跟在后面
tcp的rtp协议和udp 的rtp 有所不同,每个rtp包前面会多出四个字节
static void set_buf_rtp_over_rtsp_tag(uint8_t* pbuffer, uint8_t bychannel, uint16_t dwlen)
{
pbuffer[0] = 0x24;//$ magic char
pbuffer[1] = bychannel;
pbuffer[2] = (dwlen >> 8) & 0xff;
pbuffer[3] = dwlen & 0xff;
}
一个是0x24 ,一个是chhannel
后面两个字节是包长,根据这个再去接收包
其他
如果sdp协议里没有sps,pps,h265 包含vps,sps,pps则要在关键帧前面加这些信息,sdp协议里面是base64编码的sps,pps等信息
ViewPointServer 实现
1 接收3588 rtsp tcp 推流,为什么要用tcp,防止要推送到外网,server如果在外网,内网使用udp是无法推送的
2 ViewPointServer 接收流后解码进行超分服务
依据以上包,实现server,比较重要的是应用,1 是超分服务,2 是融合服务,由于rtsp 协议非常普遍,可能还需要拉流rtsp,由于ffmpeg 能够拉流解码,所以拉流这部分可以直接使用ffmpeg