Simple time lapse with ffmpeg

04 Dec 2022 - tsp
Last update 04 Dec 2022
Reading time 4 mins

So the idea is simple: Capturing images at fixed intervals from an attached camera or some webcam reachable via the network. One might for example use an ESP32 cam in ones WiFi and periodically fetch images from this camera onto one’s server to generate a multi-year time lapse. Or one might want to illustrate how algorithms behave over time and simply generate state images at various steps in time. Then one often wants to stitch the images to form a video in the end. A really good tool for this is ffmpeg.

Assembling frames with ffmpeg

Using globber

Globber provides the easiest way to supply a filename pattern. It just performs the typical resolution of wildcards as also done by ones shell:

Then one uses the typical parameters like

This would lead to the following example command line:

ffmpeg -pattern_type glob -r 10 -i "*.jpg" -s 640x480 -vcodec libx264 out.mp4

Using a counter

Unfortunately on some platforms (like Windows) globber is not available as pattern type. Then one has to switch to the sequence pattern type and enumerate images with monotonically increasing numbers - for example calling them image0001.jpg, image0002.jpg, etc. When using sequences ffmpeg will stop after the first image that’s not found any more.

The idea is to:

Then one uses the typical parameters like

This would lead to the following example command line:

ffmpeg -pattern_type sequence -start_number 00000001 -r 10 -i image%08d.png -s 640x480 -vcodec libx264 out.mp4

Capturing frames

So now that one knows how to assemble frames - how does one capture them? This of course depends on the source of the images.

Capturing from ESP32 camera or other HTTP devices

For a HTTP based webcam like the streams exposed for example by ESP32-CAM (note: affiliate link, this pages author profits from qualified purchases) one can simply use tools like fetch or wget that are usually preinstalled to fetch frames at intervals configured in crontab.

The idea is to use a small script fetchframe.sh that builds the filename pattern and executes the fetch. For example:

#!/bin/sh

fdate=`date +"%Y-%m-%d-%H-%M-%S"`
fname="/home/exampleuser/timelapseimages/${fdate}.jpg"

fetch -q -o ${fname} http://example.com/capture?_cb=1665873105911

This script can then be called from a crontab entry (edit either the system wide crontab at /etc/crontab or better the users crontab using crontab -e) For the users crontab an entry that should capture every minute would look like the following:

*      *       *       *       *       /home/exampleuser/timelapseimages/fetchframe.sh

To fetch only every five minutes:

*/5    *       *       *       *       /home/exampleuser/timelapseimages/fetchframe.sh

In case one wants to fetch an image every day at noon for example one can of course also fix the time to 12 o clock every day:

0      12      *       *       *       /home/exampleuser/timelapseimages/fetchframe.sh

When one then wants to assemble all frames one can simply use the above pattern. Of course it’s also possible to automate the process again using a shell script or something similar

Capturing from a webcam

It’s also possible to capture images directly from an attached video4linux device using tools like ffmpeg by simply limiting the number of video frames to one.

#!/bin/sh

fdate=`date +"%Y-%m-%d-%H-%M-%S"`
fname="/home/exampleuser/timelapseimages/${fdate}.jpg"

ffmpeg -f video4linux2 -i /dev/video0 -vframes 1  -video_size 640x480 ${fname}

This article is tagged:


Data protection policy

Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)

This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support