Skip to content

Instantly share code, notes, and snippets.

@TomHumphries
Created January 31, 2022 16:15
Show Gist options
  • Save TomHumphries/f565e0ce479e4acae4a6ecb1d244dbbc to your computer and use it in GitHub Desktop.
Save TomHumphries/f565e0ce479e4acae4a6ecb1d244dbbc to your computer and use it in GitHub Desktop.
Saving RTSP Camera Streams with FFmpeg

Saving RTSP Streams from Tapo C310 Cameras with FFmpeg

The full FFmpeg command to copy-paste:

ffmpeg -hide_banner -y -loglevel error -rtsp_transport tcp -use_wallclock_as_timestamps 1 -i rtsp://username:[email protected]:554/stream1 -vcodec copy -acodec copy -f segment -reset_timestamps 1 -segment_time 900 -segment_format mkv -segment_atclocktime 1 -strftime 1 %Y%m%dT%H%M%S.mkv

The input stream URL is for a Tapo C310 camera with the RTSP username and password "username" and "password".

I've put a fair bit of experimentation into the settings in this command. I've included the what and whys below, as well as a camera recommendation for RTSP.

Breaking Down The Script

-hide_banner -y

This supresses the copyright notice, build options, and library versions from printing to the console.

-loglevel error

I received a lot of warning messages from most RTSP camera streams. We can fix most of these warnings with the other command line options, and I didn't want these warnings filling up my logs during normal use.

-rtsp_transport tcp

Our options here are TCP or UDP. In my experiments with recording UDP streams, the video files were regularly corrupted. I assume this is due to the non-guaranteed packet delivery or order. I have tried tweaking various FFmpeg settings such as the buffer size, but could not get files saving reliability on UDP. It does provide a good lower-latency, lighter-bandwidth live streaming option though.

-use_wallclock_as_timestamps 1

This rebuilds the timestamps in the video feed. In my experiments with various network cameras this was needed to make the saved videos correctly seek-able. I think this resolves issues with varying framesrates from some network cameras, and streams from some brands not including correct timestamps.

-i rtsp://username:[email protected]:554/stream1

This is the address of the RTSP video stream we want to use as the input. Each camera will have a different URL that you can find with an online search. The URL above is for a Tapo C310. If the camera needs a username and password it is prefixed to the IP address.

-vcodec copy 
-acodec copy

These parameters tell FFmpeg not to reencode the video or audio streams, and instead just to copy them. This will minimise the CPU usage which is good for recording multiple streams on something like a Raspberry PI. The trade-off is that the video will probably be larger than if re-encoded into a more efficient format. The quality and size of the “copied” video stream files will depend on the specific camera and its settings.

-f segment

These next few parameters tell FFmpeg to save the video stream to smaller segment files, instead of writing to one never-ending file.

-reset_timestamps 1

This resets the timestamps at the start of each segment file to zero. It was needed to fix problems with video files not being seekable. I assume it was due to the timestamps being saved incorrectly.

-segment_time 900

This tells FFmpeg that each file should be 15 minutes (900 seconds) long before a new one is started.

-segment_atclocktime 1 

This makes FFmpeg start and finish recording files at “round” times, e.g. 09:00, 09:15, 09:30 etc. The start and finish times will not be exactly on the times, since videos must start and stop on keyframes. You can expect the files start/end to be within a few seconds of the round-times though.

-segment_format mkv

Save the videos as .mkv files. I chose .mkv over .mp4 due to the increased resilience to corruption .mkv provided. I tried pulling the plug on my cameras while recording streams to simulate someone stealing the camera. The .mkv files recorded right up to the moment the power was cut, whereas .mp4 files often became corrupt and unplayable.

-strftime 1 
%Y%m%dT%H%M%S.mkv

This is the naming convention for the video files. The collection of letters and percent signs is a formatting string that tells FFmpeg how to use the date to name this files. We're using this ISO8601-like format because it allows us to order by the files by date by sorting alphabetically. The video starting at 2022–01–30 21:30:00 will be saved as 20220130T213000.mkv (give or take a few seconds). You can also add a directory before this string to save the videos in a different location to where you're running the command line. e.g. C:\Users\you\Videos\front_door\%Y%m%dT%H%M%S.mkv on Windows.

Note

On Windows, when I used a lower case z in the date formatting string it was parsed to a descriptor like “GMT Summer Time” instead of “+0100”. This is not the behaviour the documentation describes, which is that a capital Z should output the descriptor and a lower case z should output an offset. This didn't happen when running the command on Linux (i.e. z outputs an offset like +0100).

@pythonzz0622
Copy link

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment