Sunday, 3 January 2010

Creating time lapse videos using ffmpeg


First Year Installation on Vimeo
Originally uploaded by Gary Edwards

It is very easy to turn sequences of jpegs captured on a stills camera into a single compressed video file using the free cli tool ffmpeg.

I will explain the basic the example below which I use as part of my work flow:

# ffmpeg -i %05d.jpg -r 25 -croptop 99 -cropbottom 100 -s hd1080 -vcodec dnxhd -mbd rd -b 120Mb -an output.mov


For this example I used a sequence captured on my Canon 400D using the small jpeg file size (1936 x 1288 pixels).

I imported them using gThumb on my GNU/Linux box which defaults to renaming the images, 00001.jpg, 00002.jpg, etc (with a padding of 4). It is important that the images are named like this (padding can be different 001.jpg or 0001.jpg etc) so that you do not have issues with the next step.

Ok now I have all the pictures on my computer and correctly named lets look at the conversion.

ffmpeg is a command line tool so you will have to open your favourite terminal emulator. Popular ones are gnome-terminal on GNU/Linux and Apple terminal on OS X. Then use the cd command to navigate to the directory containing your images.


# ffmpeg -i %05d.jpg -r 25 -croptop 99 -cropbottom 100 -s hd1080 -vcodec dnxhd -mbd rd -b 120Mb -an output.mov

The first part of the command tells ffmpeg what the input is. In this case it is a sequence of jpg's with a padding of 4. So each file name will have 5 characters hence the %05. If you have a padding of 2 (eg 001.jpg) you will use:

-i "%03.jlp"


# ffmpeg -i %05d.jpg -r 25 -croptop 99 -cropbottom 100 -s hd1080 -vcodec dnxhd -mbd rd -b 120Mb -an output.mov

-r defines the frame rate that you want your time lapse to be at. I set a frequency on my camera with the intention of playing at 1080 25p so my value is set to 25. You can set this to whatever you want but keep in mind how this may effect you work flow later on editing etc.

# ffmpeg -i %05d.jpg -r 25 -croptop 99 -cropbottom 100 -s hd1080 -vcodec dnxhd -mbd rd -b 120Mb -an output.mov

This part of the command gets the photos to size so that they can work with other videos. For my example I have to work at 1080 resolution as this is a requirement of the dnxhd codec. As the ratio of the images from my camera do not match that of HD video I have to crop them before scaling them.

crop = height - (width / (16.0 / 9.0))

This formula calculates what the total crop should be. So:

crop = 1288 - (1936 / (16.0 / 9.0)) = 199

So half of that is 99.5 which must be split 99, 100 as you can not have half pixels. This could be 2, 197 depending on your image but for me 99, 100 works:

-croptop 99 -cropbottom 100

Then the scale is added with -s hd1080.

You may choose not to crop or scale at all and have a 24Mpixel video... or depending on your images you may want to using something like The Foundry's Nuke to have more control over the crops and transforms, using their "DeFlicker" plug-ins to reduce flicker. You could then use the output from that as your input for ffmpeg.

# ffmpeg -i %05d.jpg -r 25 -croptop 99 -cropbottom 100 -s hd1080 -vcodec dnxhd -mbd rd -b 120Mb -an output.mov

There are loads of codecs supported by ffmpeg and you can transcode directly into any that are supported. For my example I am using AVID's DNxHD. DNxHD is an intermediate codec, which means it is intended for use during video editing and maintains image quality while reducing disk usage. The options available for this codec can be found here.

# ffmpeg -i %05d.jpg -r 25 -croptop 99 -cropbottom 100 -s hd1080 -vcodec dnxhd -mbd rd -b 120Mb -an output.mov

Last but not least you must define and output file. This involves giving the file a name and file extension which will define its container format. In my example I am using the .mov extension as it supports DNxHD. If you where using xvid as your codec you could use avi and so on.

I hope this helps some people and feel free to point errors so that I can fix them.

Quick extra for encoding directly for Vimeo et al.:

# ffmpeg -y -i %05d.jpg -mbd 2 -an -pass 1 -vcodec libx264 -r 25 -croptop 23 -cropbottom 176 -s hd720 -sws_flags lanczos -vpre fastfirstpass -b 5000k -bt 4000k -threads 0 OUTPUT.mp4 && ffmpeg -y -i %05d.jpg -mbd 2 -acodec aac -ab 128k -ar 44100 -pass 2 -vcodec libx264 -r 25 -croptop 23 -cropbottom 176 -s hd720 -sws_flags lanczos -vpre hq -b 5000k -bt 4000k -threads 0 OUTPUT.mp4

0 comments: