Start from a sequence of images, i.e. a high rate continuous shooting with a camera or a smartphone. You end up with a series of jpg named for example img000.jpg
, img001.jpg
, img002.jpg
, etc.
Let's assume that you also know the speed at which the camera has fired off the shots, for example 5 fps.
This is how to merge them into a video:
ffmpeg -r 5 -i img%03d.jpg -vcodec h264 -pix_fmt yuv420p -crf 22 -s 1920x1080 MOVIE.mp4
The key parameter is the -r
(or -framerate
) followed by the fps (frame-per-second) value that will be equivalent to the one used to shoot the sequence (increasing the framerate gives accelerated video). This parameter has to be specified before the input frames!
The quality factor (crf
) 22 is a good compromise, if you want to stick to Vimeo's guidelines either use -crf 18
or set the exact bitrate with -b:v xxM
(Vimeo suggests between 10 and 20 Mbps for a full HD (1080p) video).
As a reference, keep in mind that raw video shot with common cameras are between 20 and 50 MBps:
DJI Spark | Gopro 5 | Nikon D600 | Olympus OMD EM10 |
---|---|---|---|
24 | 45 | 22 | 21 |
And the size of the output files (input file = 1.79 Gb) are:
- crf 10 = 3.6 Gb
- crf 18 = 1.4 Gb
- crf 22 = 740 Mb
- crf 25 = 455 Mb
To join together a few clips:
ffmpeg -f concat -safe 0 -i <(for f in *.mp4; do echo "file '$PWD/$f'"; done) -c copy OUT.mp4
To crop while creating the video (for example in this case I started from a sequence of vertical i.e. portrait oriented photos and wanted to cut only the middle part of the frame changing the orientation to horizontal):
ffmpeg -framerate 5 -i IMG%03d.jpg -filter:vf "crop=in_w:in_h-2844,scale=1920x1080" -OUT.mp4
The input dimensions to the crop filter have shortcuts like in_w
and in_h
which are equivalent to original width and height respectively. The frames are 2340x4160 px so the above crop means keeping the horizontal unchanged and the vertical cut so that I end up with 1316 pixel (=4160-2844) which gives back a 16:9 ratio. Then I rescale the output to Full HD size (1920x1080).
To batch process multiple sequences I can use a for loop like in the script below.
To make it smooth and create interpolated frames between each frame use butterflow:
butterflow -r 3x ${OU}.mp4 -o ${OU}_bf.mp4