繁体   English   中英

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

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

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

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

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

pass是在 android 相机应用程序客户端上定义的密码。

我更喜欢 RTSP/TCP 传输,因为使用 UDP 图像经常损坏。 出现涂抹和撕裂的图像。 所以我测试了几乎所有东西,甚至使用最新的存储库从源代码编译FFMPEG 但是没有什么可以使 ffmpeg、android 或 windows 工作。 如果使用-rtsp_transport tcp我总是最终收到:

[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参数的更多详细信息,请点击此处

最奇怪的部分是RTSP 设置消息的比较(FFMPEG 与 openRTSP)。 很明显,ip 摄像头服务器支持 RTP/AVP/TCP。 RTP 交织到现有的 TCP 连接中。

并查看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;
}
...

引用智慧

IP 相机质量参差不齐,根据我的经验,有些表现不正常。 处理他们的 RTSP 流需要一定的容错能力。
这似乎是 CCTV 行业低端行业对标准的快速和松散的副产品, RTSP和 ONVIF最常被滥用的两个。 幸运的是,您通常可以解决这些问题。 除非您的 IP 相机和 controller 都设计为可以很好地协同工作,否则只能使用 ONVIF 进行一次性发现和设置管理。

FFMPEG 在 RTSP 设置中不是很宽容

在挣扎之后,我开始比较openRTSPffmpeg之间的 RTSP/ SETUP消息。 默认情况下, openRTSP已经输出了很多详细的诊断信息。

开放式RTSP

openRTSP发送命令OPTIONSDESCRIBE然后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=60

FFMPEG

对于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=60

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

比较消息,很明显相机可以使用 RTSP/AVP/TCP 交错 TCP 进行连接。 但是我们可以通过摄像头的回答看到,在“传输:”行中, “RTP/AVP”之后没有包含“TCP” ,因为它是请求的。 喜欢:

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

我分析了ffmpeg/libavformat/rtsp.c上的代码,发现了以下直观的调用顺序: ff_rtsp_connectff_rtsp_make_setup_requestff_rtsp_send_cmdff_rtsp_read_replyff_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, "") lower_transport RTSP_LOWER_TRANSPORT_TCP时,假设传输是 RTSP_LOWER_TRANSPORT_TCP。 像下面这样:

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 工作正常!

破解了 FFMPEG使其能够容忍相机服务器正在执行的 RTSP 滥用 由于我的 FFMPEG 版本只能在我未使用的 android 电视(作为 cctv/nvr 摄像机服务器)上运行,因此不会产生任何其他问题。

更好的解决方案是 FFMPEG ( Ticket ) 还要考虑 rtsp 服务器答案上缺少较低传输的情况。 然后与客户端发送的请求进行比较,以定义是否省略了较低的传输。 并尝试与之建立联系。

建议

如果您到达这里,您的 ip 相机可能会遭受一些 RTSP 滥用。 我建议您先尝试使用openRTSP看看它是否能够连接。 如果是这样,则尝试调试其 RTSP/设置消息。 如果您修改(自担风险) ffmpeg/libavformat/rtsp.c代码,则可能存在一些自定义或黑客解决方案。 或者你可能/应该使用 live555 库、VLC 或 mplayer。

暂无
暂无

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

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