通过 ffmpeg 使用单播 RTSP URI

Using Unicast RTSP URIs via ffmpeg

我是 ffmpeg 的新手,所以我当然很高兴能得到 "M" 到 "RTFM." ffmpeg 文档...不是那么容易...导航, 但我正在尝试。

目标是开发一个包含 ffmpeg 的编译服务器,但首先,我需要通过 CLI 让它工作。

我有一个标准的 AXIS 监控摄像头 (AXIS M5525-E),设置为 ONVIF 设备(但这与此问题无关)。

当我查询它时,我得到以下 URI 作为其视频流 URI:

rtsp://192.168.4.12/onvif-media/media.amp?profile=profile_1_jpeg&streamtype=unicast

IP 是沙盒网络的本地 IP。

我给它添加认证参数,像这样:

rtsp://<LOGIN>:<PASSWORD>@192.168.4.12/onvif-media/media.amp?profile=profile_1_jpeg&streamtype=unicast

(是的,我知道那不安全,但这只是为了测试和可行性研究。整个该死的沙箱都是一团不安全的东西)。

现在,如果我使用 VLC 打开 URI,效果很好(当然)。使用数据包分析器查看它,我看到设备和我的计算机之间进行了以下协商(在 .2 - 为简洁起见被剪掉):

Id = 11
Source = 192.168.4.12
Destination = 192.168.4.2
Captured Length = 82
Packet Length = 82
Protocol = TCP
Date Received = 2019-08-06 12:18:37 +0000
Time Delta = 1.342024087905884
Information = 554 -> 53755 ([ECN, ACK, SYN], Seq=696764098, Ack=3139240483, Win=28960)
                    °
                    °
                    °
Id = 48
Source = 192.168.4.12
Destination = 192.168.4.2
Captured Length = 366
Packet Length = 366
Protocol = TCP
Date Received = 2019-08-06 12:18:38 +0000
Time Delta = 2.09382700920105
Information = 554 -> 53755 ([ACK, PUSH], Seq=696765606, Ack=3139242268, Win=1073)

紧随其后的是 UDP 流数据包。

但是,如果我将相同的 URI 提供给 ffmpeg:

ffmpeg -i rtsp://<LOGIN>:<PASSWORD>@192.168.4.12/onvif-media/media.amp?profile=profile_1_jpeg&streamtype=unicast -c:v libx264 -crf 21 -preset veryfast -g 30 -sc_threshold 0 -f hls -hls_time 4 /Volumes/Development/webroot/fftest/stream.m3u8

我一无所获。设备和我的电脑之间根本没有协商。

在那之后,如果我删除 &streamtype=unicast 参数,我会得到一个协商和一个流:

Id = 10
Source = 192.168.4.12
Destination = 192.168.4.2
Captured Length = 82
Packet Length = 82
Protocol = TCP
Date Received = 2019-08-06 10:37:48 +0000
Time Delta = 3.047425985336304
Information = 554 -> 49606 ([ECN, ACK, SYN], Seq=457514925, Ack=2138974173, Win=28960)
                    °
                    °
                    °
Id = 31
Source = 192.168.4.12
Destination = 192.168.4.2
Captured Length = 345
Packet Length = 345
Protocol = TCP
Date Received = 2019-08-06 10:37:49 +0000
Time Delta = 3.840152025222778
Information = 554 -> 49606 ([ACK, PUSH], Seq=457516393, Ack=2138975704, Win=1039)

当然,我会继续弄清楚为什么这 [不会] 发生,并且会 post 我找到的任何解决方案,但是,就像我说的,我对此很陌生,所以我完全有可能遗漏了一些基本的东西,非常感谢任何指导。

谢谢!

您需要对命令行中的特殊字符URL进行转义,它们是“?”和“&”,因为命令行是 Bash 上的 运行,并且这些字符对 bash(分别是通配符和分叉符)有某种意义,因此它会解释它们。

通过转义这些字符,完整的 URL 将根据需要发送到 ffmpeg。

要转​​义一个字符,在它前面放一个破折号,就像我在下面的命令行中所做的那样。

每当你在命令行上有一个 & 字符时:使用 \&

同样适用于? 字符:使用\?

请试一试:(例1)

ffmpeg -i rtsp://LOGIN:PASS@192.168.4.12/onvif-media/media.amp\?profile=profile_1_jpeg\&streamtype=unicast -c:v libx264 -crf 21 -preset veryfast -g 30 -sc_threshold 0 -f hls -hls_time 4

还有第二种方法可以发送完整的参数行,而不必转义单个字符:在 URL.

周围使用单引号 '

像这样:(例如 2)

ffmpeg -i 'rtsp://LOGIN:PASS@192.168.4.12/onvif-media/media.amp?profile=profile_1_jpeg&streamtype=unicast' -c:v libx264 -crf 21 -preset veryfast -g 30 -sc_threshold 0 -f hls -hls_time 4

两者都应该可以解决您的问题。如果您仍然遇到任何其他问题,请在此处报告,以便我可以帮助您充分发挥作用。

PS:示例1和示例2没有优缺点,它们只是针对您的情况做同样事情的不同方式。按照你的风格使用你感觉更好的方式。