Skip to content

Instantly share code, notes, and snippets.

@Potherca
Last active March 28, 2023 04:29
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Potherca/18423260e2c9a4324c9ecb0c0a284066 to your computer and use it in GitHub Desktop.
Save Potherca/18423260e2c9a4324c9ecb0c0a284066 to your computer and use it in GitHub Desktop.
Converting a webm file to GIF (using FFmpeg and Gifsicle)

Introduction

Sometimes I want to make a screencapture of a websites behaviour.

In Chrome, I am quite happy doing this with the Awesome Screenshot: Screen Video Recorder extension.

Besides screenshots, the extension offers the ability to make a recording. (Limited to 30 seconds in the free version).

The recording can be uploaded to Youtube or Google Drive. It can also be downloaded as WebM file.

Often, I want to share the recording with co-workers on Slack.

Besides the fact that Slack does not support WebM, I dislike uploading several MBs of recording.

To remedy this, I convert the recording to a (smaller) GIF and share that on Slack.

Converting

To convert the WebM to GIF, I use FFmpeg. I then use Gifsicle to resize and optimize the created GIF.

I've found that 600 pixels height is a nice compromise between size and readablility (when text is involved).

The command I use for this is:

sInput='/path/to/file.webm';
sOutput="$(basename "${sInput%.*}")";
ffmpeg -i "${sInput}" -pix_fmt rgb8 "${sOutput}.gif" \
    && gifsicle --optimize=3 --output "${sOutput}-optimized.gif" --resize-height 600 "${sOutput}.gif"

This will easily turn a 2.5M WebM file to a 600K GIF. Without optimization it would be roughly 3.5M.

I'm sure more optimizations are possible, I might add these later.

It would also be simple to turn the command into a function. I might do that later as well.

@jerabaul29
Copy link

I wonder if this would be even more robust using instead (i.e. adding a pair of " around the basename argument):

sOutput="$(basename "${sInput%.*}")";

The posted command fails with filenames or pathes with spaces in the name, while this slightly modified version works in this case too.

@Potherca
Copy link
Author

@jerabaul29 You are absolutely right! The inner command really should have been double quoted to prevent globbing and word splitting. I've ammended the code.

Thansk for pointing that out! 🙌

@mmirus
Copy link

mmirus commented Feb 10, 2022

Thanks for this! I turned it into a shell script and substituted a different ffmpeg command.

#!/bin/bash
# Adapted from https://gist.github.com/Potherca/18423260e2c9a4324c9ecb0c0a284066

INPUT="$1"
OUTPUT="$(basename "${INPUT%.*}")"
ffmpeg -i "${INPUT}" \
        -vf "fps=10,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
        -loop -1 \
        "${OUTPUT}.gif"
gifsicle --optimize=3 --output "${OUTPUT}-optimized.gif" --resize-height 600 "${OUTPUT}.gif"

@Potherca
Copy link
Author

@mmirus I like the -loop -1 and fps=10 additions, they make a lot of sense!

I think I'll include those in my version as well 🤩

ffmpeg isn't my strong suit, so I'll have to take a closer look at the other changes, They might also make good improvements.

Regarding the shell script, since error handling is not set,1 you might want to add a check for the parameter in case it is not given:

INPUT="${1?One parameter required: <path-to-gif>}"

1 Or set error handling with either set -e or the more verbose set -o errexit . With that the script will balk if $1 is not set.

@mmirus
Copy link

mmirus commented Feb 10, 2022

@Potherca Glad it's helpful! I actually ended up switching to -loop -0 so that the GIF will loop infinitely (-loop -1 just repeats once). Might be something that depends on the use case.

I'm not an ffmpeg wizard either--I just found that elsewhere and it seemed to result in better quality and size for the specific video I was converting. 😅

Good suggestion on error handling!

@aaneja
Copy link

aaneja commented Mar 28, 2023

This was super helpful, thanks folks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment