clubmate.fi

A good[ish] website

Web development blog, loads of UI and JavaScript topics

Converting heavy gifs to lighter gif-like videos

Filed under: Tooling— Tagged with: media

Here’s a little guide on how to convert large animated gifs into lighter videos. We’re going to do that with ffmpeg command line tool, or with HandBrake that provides a nice graphical user interface.

I originally wrote this post in 2015, but I’ve now (2020) rewritten it.

Graphics Interchange Format, invented in the late 80s, still persisting in our daily lives. Technologically speaking gifs are in the same club with Macintosh II, Windows 1, and floppy disc.

Animated gif weighing a whooping 1.2MB

The technology behind animated gifs is old and clunky, a remnant of the 90s clipart and guestbooks internet. Gif is an extremely inefficient way to pack video, where as the static gif image is pretty good format for showing graphical shapes with few colors. But gifs were never meant to handle anything else than simple graphics.

Videos can act like gifs and have a much effective compression algorithm, videos also don’t need to be fully loaded to start the playback.

Good things about Gifs

"Old tech" does not necessarily equal bad, we still use hammers for example. I guess gifs are good because:

  • They’re portable, just one file
  • Easy to embed, just an img tag
  • Works on any device
  • Easy to make with Gif cams
  • They’re inherently loopy
  • Autoplay, no matter what

If we’d like to use a video instead of a gifs, the video replacement should more-or-less fill this criteria.

What then if not gifs?

HTML5 video. Here’s the video formats commonly in use in the web and the browser support:

Video format browser support
EdgeIEFirefoxChromeSafariOpera
WebMYep ✅Nope 🚫Yep ✅Yep ✅Nope 🚫Yep ✅
OggYep ✅Nope 🚫Yep ✅Yep ✅Nope 🚫Yep ✅
mp4Yep ✅Yep ✅Yep ✅Yep ✅Yep ✅Yep ✅

Unsurprisingly mp4 is the most supported one. But, it’s not open source nor royalty free. What that means is: although you can freely upload mp4 videos to internet without worrying about royalties, but the companies implementing mp4 to their products need to pay a royalty fee. If I understand right, for instance, Linux distributions do not support mp4 out the box, because of the fees. Here’s an SO thread if you want to dig more into it.

Imgur for example has their own little gifv thingy, that in reality is just a muted video, which auto-plays and loops. The main format behind it is WebM and mp4 as fallback.

Converting gifs to videos with HandBrake

HandBrake provides a nice graphical user interface for compressing, converting, and resizing videos. It’s open source, has solid defaults, and is easy to use. You can also drill into the nitty gritty of the setting if you want more control.

Screen shot of the HandBrake video format converting tool
This random 24MB gif turned into a 1MB mp4.

Download HandBrake at handbrake.fr.

Converting Gifs to videos with ffmpeg

There’s a great command line tool: ffmpeg that’ll convert pretty much anything to any format. The above mentioned HandBrake uses ffmpeg under the hood.

Install ffmpeg

Ffmpeg is bolted pretty deeply into the system, on Mac it needs the Command Line tools to function. You might know this error if you’ve ever installed ffmpeg:

Error: Xcode alone is not sufficient on Catalina.
Install the Command Line Tools:
  xcode-select --install

Go ahead and add the Command Line Tools from xCode:

$ xcode-select --install
Mac OS prompt window

When done, install the actual ffmpeg:

$ brew install ffmpeg

Upgrading ffmpeg can be done with upgrade command:

$ brew upgrade ffmpeg

Test that ffmpeg is actually installed in your system:

$ ffmpeg -version

The gif to video converting process

There’s a lot of ways to using ffmpeg, it’s a bit like tuning a rocket engine. Here’s the best combination of options I’ve found so far, it seems to work pretty well:

$ ffmpeg \
  -i test-gif.gif \
  -movflags faststart \
  -pix_fmt yuv420p \
  -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" \
  test-output.mp4

Here’s what’s happening line-by-line:

-i input
This flag simply sets the script input, test-gif.gif in this case.
-movflags
This option optimizes the structure of the MP4 file so the browser can load it as quickly as possible.
-pix_fmt Pixel format
MP4 videos store pixels in different formats. We include this option to specify a specific format which has maximum compatibility across all browsers. This is the chroma subsampling.
-vf filtergraph
This defines a filter (an alias for -filter:v) which in this case is using a crop filter: "crop=trunc(iw/2)*2:trunc(ih/2)*2", in which the iw stands for "input width" and ih stands for "input height". This math operation: iw/2*2, makes sure that the video’s dimensions are divisible by 2, because an MP4 video using H.264 just needs that. See the cropping examples in the ffmpeg docs for more.

Additional option:

-b:v bitrate
With this you can control the quality of the video. The value to use here depends on the size of the video, but try setting it to 500K to start with.

When converting gifs to videos the quality settings doesn’t matter too much, because gifs are usually pretty shitty looking to start with. Try playing around with the bitrate to get a good weight/quality ratio:

$ ffmpeg \
  -i test-gif.gif \
  -movflags faststart \
  -pix_fmt yuv420p \
  -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" \
  -b:v 500K \  test-output.mp4

The originally 1.2MB gif file turned into 32KB mp4:

A gif-like mp4 video weighing only 32KB

The below one is done with -c:v 50K, it weighs only 16K but starts look pretty knackered.

So small, so bad

Alias the convert command

I wrapped that into a simple function:

function videoConverter() {
  local default_format="mp4"
  local input=$1
  local output=$2

  # Bail if no input given
  if [ -z $input ]; then
    echo "Usage: gif_to_vid input.gif"
    exit
  fi

  # Replace .gif with .mp4
  local generated_file_name=${input/.gif/.$default_format}
  # If output is empty, use the generated filename
  local output_file=${output:-$generated_file_name}

  ffmpeg \
    -i $input \
    -movflags faststart \
    -pix_fmt yuv420p \
    -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" \
    $output_file
}

Usage:

$ videoConverter some-file.gif

That will create some-file.mp4, because mp4 is set as the default format. Or give the output as the second param if you want to use another file format, or want to otherwise rename the output file:

$ videoConverter some-file.gif some-other-name.webm

ℹ️ ffmpeg will prompt you if the output file exists.

Converting videos to gifs

The same script can convert videos to gifs, too. It doesn’t really care what you throw at it, ffmpeg is doing its magic:

$ videoConverter video-file.mp4 a-gif-file.gif

Displaying the gif-like videos

HTML5 video syntax for a gif-like video:

<video autoplay loop muted playsinline src="/videos/some-vid.mp4">
  <p>Your browser doesn’t supporting this video format</p>
</video>

For browsers to autoplay videos, they need to have muted and playsinline attributes, and of course the autoplay attr.

If you want to use WebM videos, mp4 can be added as a fallback by using multiple source elements. Browser will pick up the first format it supports, so the order matters:

<video autoplay loop muted playsinline>
  <source src="/videos/some-vid.webm" type="video/webm" />
  <source src="/videos/some-vid.mp4" type="video/mp4" />
  <p>Your browser doesn’t supporting this video format</p>
</video>

Also, noteworthy video element attributes that I’ve excluded from the above example:

preload="metadata"
Preloads the video’s dimensions, first frame, duration etc. Making it play faster when the play button is pressed, but also adding to the initial page load.
poster="img.jpg"
This image is shown while the video loads, or before play is pressed. Since autoplaying videos don’t really have a stopped state, this isn’t so important.

Making videos

Here’s few handy GifCams and screen recorders:

  • If you’re on Mac, you can press Cmd+Shift+5 to record your screen.
  • LICEap has been around for a long time.
  • Kap is a super nice looking and modern Electron based screen recording app that also convert videos to gifs and gifs to videos.
  • MonoSnap is a screenshot tool (like Skitch, remember that?) that’s also good at screen recording. Can save gifs.
  • Then there’s of course Giphy.

Comments would go here, but the commenting system isn’t ready yet, sorry. Tweet me @hiljaa if you want to make a correction etc.

  • © 2021 Antti Hiljá
  • About
  • Follow me in Twatter → @hiljaa
  • All rights reserved yadda yadda.
  • I can put just about anything here, no one reads the footer anyways.
  • console.log('Smash the patriarchy!')
  • I love u!