Linux and FOSS, Misc

How I used ffmpeg to create time-laps videos on my Mac

I have always been stunned by the beautiful time-laps videos of clouds slowly rolling by on a beautiful blue sky. Or why not a building project slowly taking form by having hours or sometimes days become compressed into seconds or minutes. It is of course no secret how those are done. Setup your camera to take pictures every few seconds, download them to your computer and stitch them together. Simple!? Well, not so much. Especially if you don’t want to buy expensive software just to try something out.

A few years ago I made a short test that I recently found on a SD-card in my GoPro. This was a perfect sample to test with, to find a working process, for creating time lapses. My sample was pretty good sized for a normal time laps. 1856 images taking almost 9GB of disk space. The process of stitching the images together takes quite some time so I started experience on a subset containing only 10 images. This is the process I came up with.

There are multiple different open source applications that are able to create videos from pictures. ImageMagick and ffmpeg is two of these. I started out with ImageMagick but I was not successful. Something went wrong and I ran out of storage space while it was working. I then decided to look into ffmpeg and it did the trick for me.

Using docker to avoid installing software on my computer

While experimenting I didn’t want to install a bunch of different software that I may never ever use again on my computer. I opted to use docker images to house the needed software. In #61 – How to Create Animated GIFs with Docker and ImageMagick Justin Weissig describes how he is using ImageMagick in a docker container for his workflow. This was a great way to get started with a docker-file and it ended up as this.

FROM alpine:3.8
RUN apk update
RUN apk add --no-cache imagemagick bash pngcrush ffmpeg optipng=0.7.7-r0
CMD ["/bin/bash”]()

You need to have docker desktop installed. When you have that you can simply build and start the container with the following commands:

docker build -t alpine-imagemagick .
docker run -it --rm -v ~/WorkingFolder/:/DATA alpine-imagemagick

The -v parameter is pretty important. Here I map the ~/WorkingFolder directory from outside of the container to be mounted on the /DATA directory inside of the container. This makes it possible to work on files in your Mac filesystem from tools inside your docker container.

Preparing the files and running ffmpeg

Now we can start preparing the image files we want to stitch together. Put a copy of them into the “WorkingFolder”. Them being a copy is pretty important. Ffmpeg will require the files to be named in sequence and we will use a small script to rename them. On the circle’s Notes blog I found a small bash script posted into the comments by Paul Sommer back in 2010. The script looks like this

#!/bin/bash
i=0
ind=0000
for x in $1*.JPG ; do
  mv “$x” “$1$ind.JPG”
  ((++i))
  ind=$i
  # $ind must have four digits
  for d in 10 100 1000 ; do
    if [ $i -lt $d ]
    then
      ind=0$ind
    fi
  done
done

By running this I renamed my 1800+ images from names such as

G0019229.JPG to G0001.JPG

This is the reason you should work on a copy of your data set. If something goes wrong while running the script you can copy the originals into a fresh working set. Also please note that the Linux filesystem is case sensitive e.g. if your files is not suffixed with capital JPG the script needs to be updated accordingly on line 4 and 5. I called the script rename.sh and thus the following command line will rename all the files in the folder.

./rename.sh G

ffmpeg is a complex tool and it took a bit of digging before I got it to work as I wanted. Using ffmpeg to convert a set of images into a video web page contains quite a lot of information and this was a great starting point to figure out the parameters needed to do what I wanted.

ffmpeg -r 25 -f image2 -s 1920x1080 -i G%04d.JPG -vcodec mpeg4 -crf 25  -pix_fmt yuv420p output.mp4

One important parameter is the -r parameter. It determines the number frames per seconds you want to use. This will determine how smooth but also how long your video will be. You probably want to experiment with this setting until you get the result you want. And you probably want to do that on a subset of your images. It took my computer roughly 10 minutes to create a video from 1800+ images. With the frame rate set to 25, 1800 images will give you 72 seconds of video (1800/25).

It is not only the frame rate that will determine the smoothness of you clip. Also the time in-between the images in your time lapse will impact how smooth the video rolls. This is especially true if thee is a lot of movement in the scene.

Reference information about ffmpeg can be found on the ffmpeg webpage – ffmpeg Documentation

And now if everything went well you should have a smoking hot time lapse in the output.mp4 file.

The result and how to improve it

I am pretty happy with the result. It took quite sometime to figure it out but well worth it. It was a good learning experience. You can see the result here:

Video: Cutting The Tree – Creating my first time lapse

There are a few way that the result can be improved. More and more digital cameras can be setup to continuously snap a picture. By setting the exposure and focus to manual you can better improve the video end result. Most modern cameras have a pretty big resolution and a HD-video has as low resolution as 1920×1080. This means that the time laps images doesn’t have to be done in full size and quality. This will reduce the file sizes and make your battery life and SD-card space last longer.

After you have rendered you time laps, you can (and probably should) edit it in your video editing software of choice. This to cut it and polish it to live up to all of your expectations on a nice and modern video. The clip is also without sound that is something that you may want to change.

Good luck with your own time lapsing and feel free to share your creation with me!