首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FFMPEG:“服务器应答中的非匹配传输”但openRTSP工作

FFMPEG:“服务器应答中的非匹配传输”但openRTSP工作
EN

Stack Overflow用户
提问于 2021-02-19 15:57:37
回答 1查看 1.7K关注 0票数 1

我买了一个便宜的中国ip相机(GWIPC-26/Yoosee)。我想用ffmpeg记录它的溪流。

在FFMPEG上,我设法使它只使用,使用RTSP/UDP传输协议,如下所示。它也完美地在VLC上播放。

代码语言:javascript
复制
ffmpeg -rtsp_transport udp -i rtsp://admin:pass@192.168.0.103:554/onvif1 streamfile.mkv

pass是在安卓摄像头应用程序客户端上定义的密码。

但是I非常喜欢RTSP/TCP传输,因为使用UDP时,图像经常会被损坏。出现涂抹和流泪的图像。所以我测试了几乎所有的东西,甚至用最新储存库从源代码中编译了最新储存库。但没有什么东西能让android或windows的功能发挥作用。如果使用-rtsp_transport tcp i,则最终接收:

代码语言:javascript
复制
[rtsp @ 0xxxxxxx] Nonmatching transport in server reply

最后发现了使用VLC使用的相同库的openRTSP。使用它,我设法使它连接使用RTSP/TCP (在从源代码编译后)。

代码语言:javascript
复制
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的源代码,它的接缝是否存在识别问题?

代码语言:javascript
复制
...
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;
}
...
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-19 18:18:20

引用智慧

IP摄像头的质量参差不齐,有些在我的经验中表现不正常。处理他们的RTSP流需要一定的容错能力。 这似乎是央视低端行业的副产品之一,该行业快速而松散地使用标准,RTSP和ONVIF of 是最常被滥用的两家。幸运的是,您通常可以解决这些问题。除非您的IP相机和控制器都设计得很好,否则只能使用ONVIF进行一次发现和设置管理。

在RTSP设置中FFMPEG不太宽容

挣扎之后,我开始比较RTSP/设置openRTSPffmpeg之间的消息。默认情况下,openRTSP已经输出了大量冗长的诊断。

openRTSP

openRTSP发送命令OPTIONSDESCRIBESETUP。设置消息如下:

代码语言:javascript
复制
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

摄象机回应:

代码语言:javascript
复制
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=60

FFMPEG

对于FFMPEG,您必须使用-v 9 and -loglevel 99参数来查看RTSP消息。它只发送了一个DESCRIBE请求:

代码语言:javascript
复制
DESCRIBE rtsp://192.168.0.103:554/onvif1 RTSP/1.0
Accept: application/sdp
CSeq: 2
User-Agent: Lavf58.67.100

摄象机回应:

代码语言:javascript
复制
Transport: RTP/AVP;unicast;destination=192.168.0.100;source=192.168.0.103;interleaved=0-1
Session: 37287775;timeout=60

RTSP滥用与FFMPEG黑客解决方案

通过对信息的比较,可以清楚地看到,摄像机可以使用RTSP/AVP/TCP交织TCP进行连接。但我们可以通过摄像头看到,在“传输:”行中,它不包括'TCP'后'RTP/AVP'的请求。比如:

代码语言:javascript
复制
Transport: RTP/AVP/('TCP' missing here);....

我分析了on和ffmpeg/libavformat/rtsp.c的代码,发现了直观的调用顺序:ff_rtsp_connectff_rtsp_make_setup_requestff_rtsp_send_cmdff_rtsp_read_replyff_rtsp_parse_line。在最后一个例子中,我找到了rtsp_parse_transport和下面的代码:

代码语言:javascript
复制
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被取消。就像咆哮:

代码语言:javascript
复制
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。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66280861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档