Monday, August 27, 2018

Video to GIF shell script using ffmpeg

This is an old post that I copied from my old blog.

I like to capture my Xbox One gaming moments to share with friends and have been working on a shell script to quickly convert videos to animated GIFs, I've put together this fairly simple little shell script that takes an input video and uses ffmpeg to convert to an animated GIF.

The GIF file format has a colour limitation of 256 colours, so optimisation needs to be done to ensure a good quality output. The script utilises ffmpegs palettegen options to generate a palette of colours to use in the second pass using the bayer dither option. This is what the palette PNG file looks like (upscaled from 16x16):

The resulting animated GIF turns out quite nice, this was captured from my Xbox One in the Battlefield 1 beta, the file is 480x260 and 4.3MB at 15 frames per second:

The script is available as a gist on my github or it can be copied and pasted from below. First download the script and set it as executable, the simplest method is wget:
$ wget
$ chmod +x
To use this script just execute it with the filename of a video appended, the script defaults to a width of 480 pixels and frame rate of 15fps:
$ ./ video.mp4
To change the width and fps of the gif add -w and -f arguments to the script:
$ ./ -w 320 -f 10 video.mp4

UPDATE: I've recently done some testing with different bayer dithering levels, results are below, I've also added a dithering argument to the script.

To specify a different dithering level use the -d argument:
$ ./ -w 320 -f 10 -d 5 video.mp4

Dither Size Notes
0 3.91MB Largest file, worst image quality,
1 3.33MB Noticeable vertical lines
2 3.19MB Vertical lines still visible but better than 1
3 3.05MB Vertical lines gone, very good image quality
4 2.90MB Hard to pick a difference from 3
5 2.82MB Hard to notice a difference from 4 but some colour banding evident

Bonus: if you want to be able to run the script from anywhere without specifying the full path or ./ simply copy it to /usr/local/bin:
$ sudo cp /usr/local/bin/
The script can now be run from any directory:
Script: More information on GIF optimisation and bayer dithering can be found here, this was also the basis of my original script:

Just a warning, keep the input videos short, GIFs can get very large very quickly.

No comments:

Post a Comment

Raspberry Pi 4 heatsink testing

With all the talk of how hot the Raspberry Pi 4 runs I thought I’d do some testing to see how different heatsinks perform. I had a few heats...