我买了一个便宜的中国ip相机(GWIPC-26/Yoosee)。我想用ffmpeg记录它的溪流。
在FFMPEG上,我设法使它只使用,使用RTSP/UDP传输协议,如下所示。它也完美地在VLC上播放。
ffmpeg -rtsp_transport udp -i rtsp://admin:pass@192.168.0.103:554/onvif1 streamfile.mkvpass是在安卓摄像头应用程序客户端上定义的密码。
但是I非常喜欢RTSP/TCP传输,因为使用UDP时,图像经常会被损坏。出现涂抹和流泪的图像。所以我测试了几乎所有的东西,甚至用最新储存库从源代码中编译了最新储存库。但没有什么东西能让android或windows的功能发挥作用。如果使用-rtsp_transport tcp i,则最终接收:
[rtsp @ 0xxxxxxx] Nonmatching transport in server reply最后发现了使用VLC使用的相同库的openRTSP。使用它,我设法使它连接使用RTSP/TCP (在从源代码编译后)。
openRTSP -n -D 1 -c -B 10000000 -b 10000000 -q -Q -F cam_file \
-d 60 -P 30 -t -u admin pass rtsp://192.168.0.103:554/onvif1关于openRTSP params 这里的更多细节。
最奇怪的部分是RTSP设置消息 (FFMPEG与openRTSP)的比较。显然,ip摄像机服务器支持RTP/AVP/TCP。RTP交织到现有的TCP连接中。
而看看ffmpeg/libavformat/rtsp.c的源代码,它的接缝是否存在识别问题?
...
if (reply->transports[0].lower_transport != lower_transport) {
av_log(s, AV_LOG_ERROR, "Nonmatching transport in server reply\n");
err = AVERROR_INVALIDDATA;
goto fail;
}
...发布于 2021-02-19 18:18:20
IP摄像头的质量参差不齐,有些在我的经验中表现不正常。处理他们的RTSP流需要一定的容错能力。 这似乎是央视低端行业的副产品之一,该行业快速而松散地使用标准,RTSP和ONVIF of 是最常被滥用的两家。幸运的是,您通常可以解决这些问题。除非您的IP相机和控制器都设计得很好,否则只能使用ONVIF进行一次发现和设置管理。
在RTSP设置中FFMPEG不太宽容
挣扎之后,我开始比较RTSP/设置openRTSP和ffmpeg之间的消息。默认情况下,openRTSP已经输出了大量冗长的诊断。
openRTSP
openRTSP发送命令OPTIONS、DESCRIBE和SETUP。设置消息如下:
Sending request: SETUP rtsp://192.168.0.103:554/onvif1/track2 RTSP/1.0
CSeq: 6
Authorization: Digest username="admin", realm="HIipCamera", nonce="ddd21dbd0620b6fb4b1f9bcbb06340a0", uri="rtsp://192.168.0.103:554/onvif1", response="91d9c611aa004eeb1390b3fbb9373648"
User-Agent: ./openRTSP (LIVE555 Streaming Media v2021.02.11)
Transport: RTP/AVP/TCP;unicast;interleaved=2-3
Session: 3a4d2e6d摄象机回应:
Received a complete SETUP response:
RTSP/1.0 200 OK
CSeq: 6
Transport: RTP/AVP;unicast;destination=192.168.0.100;source=192.168.0.103;interleaved=2-3
Session: 3a4d2e6d;timeout=60FFMPEG
对于FFMPEG,您必须使用-v 9 and -loglevel 99参数来查看RTSP消息。它只发送了一个DESCRIBE请求:
DESCRIBE rtsp://192.168.0.103:554/onvif1 RTSP/1.0
Accept: application/sdp
CSeq: 2
User-Agent: Lavf58.67.100摄象机回应:
Transport: RTP/AVP;unicast;destination=192.168.0.100;source=192.168.0.103;interleaved=0-1
Session: 37287775;timeout=60RTSP滥用与FFMPEG黑客解决方案
通过对信息的比较,可以清楚地看到,摄像机可以使用RTSP/AVP/TCP交织TCP进行连接。但我们可以通过摄像头看到,在“传输:”行中,它不包括'TCP'后'RTP/AVP'的请求。比如:
Transport: RTP/AVP/('TCP' missing here);....我分析了on和ffmpeg/libavformat/rtsp.c的代码,发现了直观的调用顺序:ff_rtsp_connect、ff_rtsp_make_setup_request、ff_rtsp_send_cmd、ff_rtsp_read_reply和ff_rtsp_parse_line。在最后一个例子中,我找到了rtsp_parse_transport和下面的代码:
if (!av_strcasecmp(lower_transport, "TCP"))
th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
else
th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;lower_transport是在'RTP/AVP;'之后解析的文本,在我的例子中是""空字符字符串,因为相机服务器没有包含它。
我在代码中插入了|| !av_strcasecmp(lower_transport, "")。使其假设传输是RTSP_LOWER_TRANSPORT_TCP时,lower_transport被取消。就像咆哮:
if (!av_strcasecmp(lower_transport, "TCP") || !av_strcasecmp(lower_transport, ""))
th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
else
th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;这个用于ffmpeg的小补丁(git)是可用的这里。使用git am < RTSP_lower_transport_TCP.patch在ffmpeg git回购上的应用。
重新编译后: FFMPEG运行良好!
我黑下了FFMPEG,使得它能够容忍摄像机服务器所做的RTSP滥用。因为我的FFMPEG版本只会在我未使用的android电视上运行(作为cctv/nvr摄像头服务器),这不会造成任何其他问题。
一个更好的解决方案是FFMPEG (票证)考虑在rtsp服务器答案上丢失较低传输的情况。然后与客户端发送的请求进行比较,以确定是否放弃了较低的传输。试着和它连接起来。
建议
可能,如果您到达这里,您的ip相机可能正在遭受一些RTSP滥用。我建议您先尝试使用openRTSP,看看它是否能够连接。如果是,那么试着调试它的RTSP/setup消息。如果您修改(冒着自己的风险) ffmpeg/libavformat/rtsp.c代码,就有可能存在一些自定义或黑客解决方案。或者您可以/应该使用live555库、VLC或mplayer。
https://stackoverflow.com/questions/66280861
复制相似问题