January 12, 2020
If you’re a human that doesn’t want to download a whole new application just to do a bit of video manipulation or make a GIF, stop what you’re doing and check out ffmpeg. It’s a command-line tool you can use to do all sorts of things, but what I most often end up doing is converting a screen recording to a GIF. There are dozens of articles around the web on how to do this, but I wanted to note the command I use here for my own quick reference. I avoid creating a script with variables and instead prefer to keep it as copy and paste-able as possible.
Keep in mind this post covers less than 0.1% of what ffmpeg can do — it’s an incredible library that most of us will never fully appreciate.
ffmpeg -i my-video.mp4 my-gif.gif
This is how to create a GIF with zero manipulation. The problem is, if you turn up the brightness on your display and look closely at the GIF below, there’s a visible crosshatch pattern overlay that wasn’t in the original video:
To remove this, you need to do some fancy manipulation.
The reason why the crosshatch exists is something called dither:
For our case, all we need to understand is that ffmpeg uses dithering algorithms to avoid visual errors and make the media we create more predictable.
To remove it, ffmpeg has these really neat features called palettegen and paletteuse, which allow you to create a color palette of 256 pixels from your video, define a dithering algorithm, and use it when creating your GIF. Here’s how we do that in one command:
ffmpeg -i my-video.mp4 -vf palettegen palette.png && ffmpeg -i my-video.mp4 -i palette.png -filter_complex “paletteuse=dither=none” my-gif.gif
If you look closely again, you can see the crosshatch is gone!
Note this command actually contains two commands that you can run separately:
ffmpeg -i my-video.mp4 -vf palettegen palette.pngto create a color palette from your MP4, and
ffmpeg -i my-video.mp4 -i palette.png -filter_complex “paletteuse=dither=none” my-gif.gifto use your color palette and a few other filters to make a GIF.
Finally, I want to reduce the file size, resize the GIF, and crop the resized GIF too. With the
-filter_complex flag, we can add as many filters as we want with comma-separation:
ffmpeg -i my-video.mp4 -vf palettegen palette.png && ffmpeg -i my-video.mp4 -i palette.png -filter_complex “fps=15, scale=320:-1, crop=in_w:in_h-18:0:18, paletteuse=dither=none” my-gif.gif
The added filters include:
fps=15to set the frames-per-second to 15, effectively reducing the file size
scale=320:-1to set the width to 320 pixels and determine the height based on the original aspect ratio
crop=in_w:in_h-18:0:18 to crop 18 pixels from the top of the frame. This filter breaks down like this:
in_wis the input file’s width,
in-his the input file’s height,
wis the pixel to crop from on the x axis, and
his the pixel to crop from on the y axis
And there we have it! Copy and paste away, future self.