UP | HOME

How to use ffmpeg to make animations

[2013-03-05 Tue] (edited [2013-09-12 Thu])

There are a few considerations when encoding an animation:

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

One day I may use direct HTML5 video streaming on this site, here two pointers: 1 and 2.

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.