How to use ffmpeg to make animations
(edited )
There are a few considerations when encoding an animation:
- size
- quality
- for presentations:
- compatibility (Linux, Mac, Windows and different players)
- embed in pdf, or not
- for web:
- for upload to youtube
- for including in html5 site
Generally I found that the h264 codec delivers very good results, both for compression and quality. The down-side is that it is non-free and also not played by the Windows Media player without installing extra codecs.
For cross compatibility try the mjpeg, msmpeg4 or wmv2 codecs in a avi container, but these are not as nice as h264.
The ffmpeg
recommendations below are derived from some google
inspired trial and error. One thing to note about ffmpeg
is that
the location of an input argument is significant: before the input
file, marked by -i
it refers to that, after it refers to the output.
Producing an animation from a series of pictures
I had good results with using this command
ffmpeg -r $fps -y -i infiles_%04d.png -vf 'scale=710:804' -c:v libx264 -profile:v baseline -preset $speed -tune animation -crf $quality -pix_fmt yuv420p outfile.mp4
to turn a bunch of files of form infiles\_0001.png
into a movie.
The variables need to be set: $fps
frames per second, $speed
encoding speed (one of ultrafast, superfast, veryfast, faster, fast,
medium, slow, slower, veryslow), and $quality
is the quality
probably in the range 20-40. See here for details.
Notes:
-y
will lead to overwriting without asking!,- use
-start_number x
if the numbering of files does not start at 1. - removing the (second)
-r 24
may result in a bit smaller files, but youtube compatible.
For youtube upload
Youtube, among other stuff, only likes certain fps values: 30 is preferred. 23.98, 24, 25, 29.97 are also acceptable. If the upload animation does not have those values it will result in jerky playback.
This changes the fps to 30 without changing the speed:
ffmpeg -i infile.mp4 -r 30 -tune zerolatency outfile.mp4
For HTML5 video streaming
Transcode in the different formats
H264
As above with added -tune zerolatency
. See here for more
advanced option.
ffmpeg -i inmovie -c:v libx264 -profile:v baseline -preset slow -tune animation -crf $quality -pix_fmt yuv420p outfile.mp4
Ogg Theora
ffmpeg2theora -p pro inmovie
VP8 (WebM)
ffmpeg -i inmovie -c:v libvpx -pix_fmt yuv420p -b:v 1024k outfile.mp4
two pass
ffmpeg -i inmovie -pass 1 -vcodec libvpx -b:v 1024k -f rawvideo -y -an /dev/null && ffmpeg -i inmovie -pass 2 -an -vcodec libvpx -b:v 1024k output.webm
Include movies in webpage
Here is an example page which has youtube as a fallback, which we follow here:
<video width="640" height="360" controls preload> <source src="../img/greenland_season.avi.webm" type="video/webm" /><!-- WebM/VP8/Vorbis --> <source src="../img/greenland_season.avi.mp4" type="video/mp4" /><!-- WebKit video --> <source src="../img/greenland_season.ogv" type="video/ogg" /><!-- Firefox / Opera --> <object width="640" height="505" type="application/x-shockwave-flash" data="http://www.youtube.com/v/YE7VzlLtp-4"> <param name="movie" value="http://www.youtube.com/v/YE7VzlLtp-4" /> <!-- fallback image --> <img src="poster.jpg" width="640" height="360" alt="Big Buck Bunny" title="No video playback capabilities, please download the video below" /> </object> </video>
Which should look like this, but I haven't tested the youtube fallback.