Skip to content

Capture a RTSP Stream

January 6th, 2020 - IT(2 mins)

With the house, I’m also building a security system. A first phase in the project is to get a couple of IP cameras and play with their streams. So I got a Reolink camera and set it up with the Android app.

While the mobile app is OK for live streaming, I need also recording capabilities, ideally with piping with e.g. motion detection. I’ve started first with Shinobi and ZoneMinder, but I figured I have time to see what the surveillance systems would actually see and learn a bit. I have split the process in two:

  1. Record the camera stream on disk
  2. Post-process either in real time or offline.

Record on disk

The first phase for me is to be able to record the video stream from the camera on disk.

Surveillance systems do this by default. ZoneMinder for example uses ffmpeg or VLC. I have not looked at Shinobi in detail, but I assume they also use ffmpeg. I figured that if they use these systems, I could also do the same.

VLC

I’ve started with VLC because it’s easy. You can get it for any platform and has an UI to make the attempts a bit more interactive.

Streaming to screen is trivial via their Open network stream option which allows RTSP streams. Saving the said stream to disk proved to be a bit of an issue. I’ve looked after solutions, but the answers were more on the line that ‘it works for me’ (or so it seemed). Consequently, I’ve built a solution that works for me…

A first command was:

cvlc \
    rtsp://user:[email protected]:554//h264Preview_01_main \
    -vvv \
    --sout "#transcode{vcodec=h264,acodec=mpga,ab=128,channels=2,samplerate=44100,scodec=none}:file{dst=/path/to/data/file-h264.mp4,no-overwrite}" \
    --run-time 60 --stop-time=60 \
    vlc://quit

This version is supposed to encode a 60 second H264 stream and then quit VLC. This proved a bit too much for me and for VLC and I found a better option:

vlc rtsp://user:[email protected]:554//h264Preview_01_main \
    -vvv \
    --sout "#duplicate{dst=standard{access=file,dst='/path/to/file.mp4',mux=mp4}" \
    --run-time 60 --stop-time=60 \
    vlc://quit

This variant provides a pass-through (no re-encoding the stream).

Ffmpeg

ffmpeg is an almost magical tool to me (read: swiss army knife). I could do EXIF reading, transcoding and now I found that I can also save RTSP streams! I have started directly from automatic segment saving:

ffmpeg -loglevel debug \
    -i rtsp://user:[email protected]:554//h264Preview_01_main \
    -c copy -map 0 -c:a aac \
    -f segment -segment_time 300 \
    -segment_format mp4 /path/to/capture-%03d.mp4

This command creates 5-minute segments, auto-numbered, with audio. The command is also logging debug messages to stdout.

The command I ended up using is:

ffmpeg \
    -i rtsp://user:[email protected]:554//h264Preview_01_main \
    -c copy -map 0 \
    -c:a aac \
    -f segment -segment_time 3600 -segment_format mp4 \
    /path/to/capture-%03d.mp4

This command does the following:

  • uses the RTSP input
  • performs a copy of the stream (no transcoding)
  • writes AAC audio
  • writes auto-numbered segments
  • each segment has 3600 seconds (1 hour)
  • the segments have a mp4 envelope
  • the path is /path/to/capture-%03d.mp4

Conclusions

Writing streams from command line is quite possible and you can even transcode the stream on the fly if you have a beefy CPU :)

A 5k camera would get you 2.5-3 Gb of data per hour (a rate of about 6Mbps).

WI-FI is unreliable:

  • The bandwidth makes it tricky to record via WI-FI (I got a lot of dropped frames).
  • If the connection drops, the commands also stop and need to be restarted.

HTH,

Share on
Reddit
Linked in
Whatsapp

A little experiment: