Search code examples
macosffmpegstreamingrtsp

Using Unicast RTSP URIs via ffmpeg


I'm fairly new to ffmpeg, so I'd certainly appreciate being given an "M" to "RTFM." The ffmpeg docs are...not-so-easy...to navigate, but I'm trying.

The goal is to develop a compiled server that incorporates ffmpeg, but first, I need to get it working via CLI.

I have a standard AXIS Surveillance camera (AXIS M5525-E), set up as an ONVIF device (but that isn't really relevant to this issue).

When I query it, I get the following URI as its video streaming URI:

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

The IP is local to a sandboxed network.

I add the authentication parameters to it, like so:

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

(Yeah, I know that's not secure, but this is just for testing and feasibility study. The whole damn sandbox is an insecure mess).

Now, if I use VLC to open the URI, it works great (of course). Looking at it with a packet analyzer, I see the following negotiation between the device and my computer (at .2 - Clipped for brevity):

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)

Followed immediately by UDP stream packets.

If, however, I feed the same URI to 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

I get nothing. No negotiation at all between the device and my computer.

After that, if I then remove the &streamtype=unicast argument, I get a negotiation, and a stream:

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)

I will, of course, be continuing to work out why this is [not] happening, and will post any solutions that I find, but, like I said, I'm fairly new to this, so it's entirely possible that I'm missing some basic stuff, and would appreciate any guidance.

Thanks!


Solution

  • You need to escape the special characters on the command line URL, they are "?" and "&" because the command line is running on Bash, and those characters means something to bash (wildcard and fork, respectively), so it interprets them.

    By escaping those chars the full URL will be sent to ffmpeg as you want.

    To escape a char, put a dash before it, like I did on the command line below.

    Everytime you have a & char on the command line: use \&

    the same applies to ? char: use \?

    Try it please: (eg. 1)

    ffmpeg -i rtsp://LOGIN:[email protected]/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
    

    There is also a second way to send the full parameter line, without having to escape individual characters: is to use single quote ' around the URL.

    Like this: (eg. 2)

    ffmpeg -i 'rtsp://LOGIN:[email protected]/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
    

    Both should work and solve your issue. If you still get any additional problem, please report here so I can help you get this fully working.

    PS: There is no pros and cons of example 1 and 2, they are just different ways of doing the same thing for your situation. Use the way you feel better in accordance with your style.