04 Dec 2022 - tsp
Last update 04 Dec 2022
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.
Globber provides the easiest way to supply a filename pattern. It just performs the typical resolution of wildcards as also done by ones shell:
-pattern_type glob
-i
. In case one wants to join
all images ending in .jpg
one could for example supply -i "*.jpg"
. In
this case the quotes are important to prevent expansion of the parameter by
the shell itselfThen one uses the typical parameters like
-r
to specify the framerate like -r 10
for 10 frames per second
in the output video-s 640x480
to supply the desired output size (in this example 640 times 480 pixels)-vcodec libx264
This would lead to the following example command line:
ffmpeg -pattern_type glob -r 10 -i "*.jpg" -s 640x480 -vcodec libx264 out.mp4
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:
-pattern_type sequence
-start-number 00000001
%d
for a non zero padded number or something like %08d
that would specify a decimal number zero padded to 8 digits.Then one uses the typical parameters like
-r
to specify the framerate like -r 10
for 10 frames per second
in the output video-s 640x480
to supply the desired output size (in this example 640 times 480 pixels)-vcodec libx264
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
So now that one knows how to assemble frames - how does one capture them? This of course depends on the source of the images.
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
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:
Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/