简体   繁体   English

FFMPEG:“服务器回复中的传输不匹配”但 openRTSP 有效

[英]FFMPEG: 'Nonmatching transport in server reply' But openRTSP works

I bought a cheap chinese ip camera ( GWIPC-26xxx / Yoosee ).我买了一个便宜的中国 ip 相机( GWIPC-26xxx / Yoosee )。 I want to record its stream with ffmpeg.我想用ffmpeg记录它的stream。

On FFMPEG I manage to make it work only using the RTSP/UDP transport protocol, like bellow.FFMPEG 上,我设法使其使用RTSP/UDP传输协议工作,如下所示。 It also plays flawlessly on VLC.它在 VLC 上也能完美播放。

ffmpeg -rtsp_transport udp -i rtsp://admin:pass@192.168.0.103:554/onvif1 streamfile.mkv

pass is a password defined on the android camera app client. pass是在 android 相机应用程序客户端上定义的密码。

But I highly prefer the RTSP/TCP transport because using UDP the images are frequently corrupted.我更喜欢 RTSP/TCP 传输,因为使用 UDP 图像经常损坏。 Images that appear smeared and teared.出现涂抹和撕裂的图像。 So I tested almost anything and even compiled FFMPEG from source using the latest repository .所以我测试了几乎所有东西,甚至使用最新的存储库从源代码编译FFMPEG But nothing makes ffmpeg work, android or windows.但是没有什么可以使 ffmpeg、android 或 windows 工作。 If use -rtsp_transport tcp I allways end-up receiving:如果使用-rtsp_transport tcp我总是最终收到:

[rtsp @ 0xxxxxxx] Nonmatching transport in server reply

Finally discovered openRTSP that uses the same library that VLC uses.终于发现了使用与 VLC 相同的库的openRTSP With it I managed to make it connect using RTSP/TCP ( after compiling from source ).有了它,我设法使它使用 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

More details on openRTSP params here .有关openRTSP参数的更多详细信息,请点击此处

The weirdest part is the comparison of the RTSP setup messages (FFMPEG vs openRTSP).最奇怪的部分是RTSP 设置消息的比较(FFMPEG 与 openRTSP)。 It seams clear that the ip camera server supports RTP/AVP/TCP.很明显,ip 摄像头服务器支持 RTP/AVP/TCP。 RTP interleaved into the existing TCP connection. RTP 交织到现有的 TCP 连接中。

And looking the source code of ffmpeg/libavformat/rtsp.c it seams ffmpeg is having some problem indentifying it?并查看ffmpeg/libavformat/rtsp.c的源代码,它接缝 ffmpeg 是否有识别它的问题?

...
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;
}
...

Quoting Wisdom引用智慧

IP cameras are of varying quality, some behaving erratically in my experience. IP 相机质量参差不齐,根据我的经验,有些表现不正常。 Dealing with their RTSP streams requires a dose of fault-tolerance.处理他们的 RTSP 流需要一定的容错能力。
This appears to be a byproduct of the low-end of the CCTV industry playing fast and loose with standards, RTSP and ONVIF being the two most frequently abused .这似乎是 CCTV 行业低端行业对标准的快速和松散的副产品, RTSP和 ONVIF最常被滥用的两个。 Fortunately, you can usually work around these problems.幸运的是,您通常可以解决这些问题。 Unless your IP cameras and controller are all designed to play nicely together, only use ONVIF for once-only discovery and settings management.除非您的 IP 相机和 controller 都设计为可以很好地协同工作,否则只能使用 ONVIF 进行一次性发现和设置管理。

FFMPEG not very tolerant in RTSP setup FFMPEG 在 RTSP 设置中不是很宽容

After struggling I started comparing the RTSP/ SETUP messages between openRTSP and ffmpeg .在挣扎之后,我开始比较openRTSPffmpeg之间的 RTSP/ SETUP消息。 openRTSP by default already outputs a lot of verbose diagnostic.默认情况下, openRTSP已经输出了很多详细的诊断信息。

openRTSP开放式RTSP

openRTSP sends the commands OPTIONS , DESCRIBE and then SETUP . openRTSP发送命令OPTIONSDESCRIBE然后SETUP The SETUP messages were:设置消息是:

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

response by camera:相机回应:

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

For FFMPEG you have to use -v 9 and -loglevel 99 params to see RTSP messages.对于FFMPEG ,您必须使用-v 9 and -loglevel 99参数来查看 RTSP 消息。 It only sent a DESCRIBE request is:它只发送了一个DESCRIBE请求是:

DESCRIBE rtsp://192.168.0.103:554/onvif1 RTSP/1.0
Accept: application/sdp
CSeq: 2
User-Agent: Lavf58.67.100

response by camera:相机回应:

Transport: RTP/AVP;unicast;destination=192.168.0.100;source=192.168.0.103;interleaved=0-1
Session: 37287775;timeout=60

RTSP abused and FFMPEG hacking-Solution RTSP被滥用和FFMPEG hacking-解决方案

Comparing the messages it's clear the camera can connect using RTSP/AVP/TCP interleaved TCP.比较消息,很明显相机可以使用 RTSP/AVP/TCP 交错 TCP 进行连接。 But we can see by the camera answer that in the 'Transport:' line it doesn't include 'TCP' after 'RTP/AVP' as it was requested.但是我们可以通过摄像头的回答看到,在“传输:”行中, “RTP/AVP”之后没有包含“TCP” ,因为它是请求的。 Like:喜欢:

Transport: RTP/AVP/('TCP' missing here);....

I analysed the code on and ffmpeg/libavformat/rtsp.c and found the intuitive following calling sequence: ff_rtsp_connect , ff_rtsp_make_setup_request , ff_rtsp_send_cmd , ff_rtsp_read_reply and ff_rtsp_parse_line .我分析了ffmpeg/libavformat/rtsp.c上的代码,发现了以下直观的调用顺序: ff_rtsp_connectff_rtsp_make_setup_requestff_rtsp_send_cmdff_rtsp_read_replyff_rtsp_parse_line Inside this last one I found rtsp_parse_transport and the following code:在最后一个中,我找到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 is the text parsed after 'RTP/AVP;' lower_transport是在'RTP/AVP;'之后解析的文本in my case being "" empty char string since the camera server did not include it.在我的情况下是""空字符字符串,因为相机服务器不包含它。

I insertd ||,av_strcasecmp(lower_transport, "") in the code.我在代码中插入了||,av_strcasecmp(lower_transport, "") Making it assume that the transport is RTSP_LOWER_TRANSPORT_TCP when lower_transport is ommited.lower_transport RTSP_LOWER_TRANSPORT_TCP时,假设传输是 RTSP_LOWER_TRANSPORT_TCP。 Like bellow:像下面这样:

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;

After recompiling: FFMPEG is working perfectly!重新编译后:FFMPEG 工作正常!

I hacked FFMPEG making it tolerant with the RTSP abuse the camera server was doing.破解了 FFMPEG使其能够容忍相机服务器正在执行的 RTSP 滥用 Since my version of FFMPEG will only run on my unused android tv (as a cctv/nvr camera server) this won't create any other problems.由于我的 FFMPEG 版本只能在我未使用的 android 电视(作为 cctv/nvr 摄像机服务器)上运行,因此不会产生任何其他问题。

A better solution would be the FFMPEG ( Ticket ) consider also the case of a missing lower transport on a rtsp server answer.更好的解决方案是 FFMPEG ( Ticket ) 还要考虑 rtsp 服务器答案上缺少较低传输的情况。 Then compare with the client-sent request to define whether the lower transport was ommitted.然后与客户端发送的请求进行比较,以定义是否省略了较低的传输。 And try to connect with it.并尝试与之建立联系。

Advice建议

Probably if you reached here your ip camera might be suffering from some RTSP abuse.如果您到达这里,您的 ip 相机可能会遭受一些 RTSP 滥用。 I recommend you to try using openRTSP first to see if it manages to connect.我建议您先尝试使用openRTSP看看它是否能够连接。 If so, then try to debug its RTSP/setup messages.如果是这样,则尝试调试其 RTSP/设置消息。 It's possible that some custom or hacking solution exists if you modify (at your own risk) the ffmpeg/libavformat/rtsp.c code.如果您修改(自担风险) ffmpeg/libavformat/rtsp.c代码,则可能存在一些自定义或黑客解决方案。 Or you might/should use live555 library, VLC or mplayer.或者你可能/应该使用 live555 库、VLC 或 mplayer。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM