Skip to content

Instantly share code, notes, and snippets.

@joyrexus
Forked from dergachev/GIF-Screencast-OSX.md
Last active April 14, 2024 14:35
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save joyrexus/7042973 to your computer and use it in GitHub Desktop.
Save joyrexus/7042973 to your computer and use it in GitHub Desktop.
Create a GIF screencast

Convert a screencast to animated GIF

This gist shows how to create a GIF screencast using only free OS X tools: QuickTime, ffmpeg, and gifsicle.

Screencapture GIF

Instructions

To capture the video (filesize: 19MB), using the free "QuickTime Player" application:

  • Open "Quicktime Player",
  • Go to File -> New Screen Recording
  • Selected screen portion by dragging a rectangle, recorded 13 second video.
  • Go to File -> Export -> As Movie
    • Saved the video in full quality with the filename in.mov

To convert in.mov into out.gif (filesize: 48KB), open Terminal to the folder with in.mov and run the following command:

ffmpeg -i in.mov -s 600x400 -pix_fmt rgb24 -r 10 -f gif - | gifsicle --optimize=3 --delay=3 > out.gif

Notes on the arguments:

  • -r 10 tells ffmpeg to reduce the frame rate from 25 fps to 10
  • -s 600x400 tells ffmpeg the max-width and max-height
  • --delay=3 tells gifsicle to delay 30ms between each gif
  • --optimize=3 requests that gifsicle use the slowest/most file-size optimization

To share the new GIF using Dropbox and Copy Public URL, run the following:

cp out.gif ~/Dropbox/Public/screenshots/Screencast-`date +"%Y.%m.%d-%H.%M"`.gif

Installation

The conversion process requires the following command-line tools:

  • ffmpeg to process the video file
  • gifsicle to create and optimize the an animated gif

If you use homebrew and homebrew-cask software packages, just type this in:

brew install ffmpeg 
brew cask install x-quartz #dependency for gifsicle, only required for mountain-lion and above
open /usr/local/Cellar/x-quartz/2.7.4/XQuartz.pkg # runs the XQuartz installer
brew install gifsicle

Resources

Related Ideas

  • Extend https://github.com/dergachev/copy-public-url folder action for this use case
    • it would automate the conversion before copying Dropbox public URL
    • assign the folder action to ~/Dropbox/Public/Screenshots/gif
    • consider finding a way to simplify the dependency installation

Performance Testing

Disappointed with the color and quality that ffmpeg's GIF conversion gives. Imagemagick's convert can also be used to do the conversion, though this has serious performance penalties.

The following details experiments of converting a 3.8 second movie to GIF.

FFMPEG to PNG | individually

  • 42 seconds
ffmpeg -i in-trimmed.mov -r 10 -vcodec png out-static-%02d.png 
time for img in out-static*.png; do convert -verbose +dither -layers Optimize "$img" "$img.gif" ;  done

FFMPEG to PNG | bulk

ffmpeg -i in-trimmed.mov -r 10 -vcodec png out-static-%02d.png 
time convert -verbose +dither -layers Optimize -resize 600x600\> out-static*.png  GIF:- > out13.gif

FFMPEG to PNG | bulk | gifsicle

ffmpeg -i in-trimmed.mov -r 10 -vcodec png out-static-%02d.png 
time convert -verbose +dither -layers Optimize -resize 600x600\> out-static*.png  GIF:- | gifsicle --colors 128 --delay=5 --loop --optimize=3 --multifile - > out12.gif

FFMPEG to PPM | bulk

ffmpeg -i in-trimmed.mov -r 10 -vcodec ppm out-static-%02d.ppm
time convert -verbose +dither -layers Optimize -resize 600x600\> out-static*.ppm  GIF:- > out14.gif

FFMPEG to PPM | bulk | gifsicle

time ffmpeg -i  in-trimmed.mov -r 10 -f image2pipe -vcodec ppm - |  time convert -verbose +dither -layers Optimize -resize 600x600\> - gif:- | gifsicle --colors 128 --delay=5 --loop --optimize=3 --multifile ->  out15.gif

FFMPEG to GIF | gifsicle

ffmpeg -i in-trimmed.mov -vf "scale=min(iw\,600):-1" -pix_fmt rgb24 -r 10 -f gif - | gifsicle --optimize=3 --delay=7 --colors 128 > out16.gif

Notes

  • Omitting resizing down to 600x600 before converting to GIF dramatically slows down CONVERT.
  • PPM is the only image format that is compatible with FFMPEG piping directly to CONVERT
    • it has the same performance and compression characteristics as outputting to PNG
    • it avoids creating and cleaning up temporary image files
    • otherwise the temporary files would need to be sorted by numeric order before globbing

Resources

@roblevintennis
Copy link

Thank you so much for sharing all this research! It saved me likely from hours of frustration! 🙏

So, these are notes on using the first approach with ffmpeg only (not the Imagemagick approach in second gist)...

I got:

Error: Cask 'x-quartz' is unavailable: No Cask with this name exists. Did you mean “xquartz”?

Seems like xquartz is indeed what we want:
https://formulae.brew.sh/api/cask/xquartz.json

It seems using the xquartz version of brew above installed without requiring the additional step:

open /usr/local/Cellar/x-quartz/2.7.4/XQuartz.pkg # runs the XQuartz installer

e.g.

==> Running installer for xquartz; your password may be necessary.

After also installing gifsicle, I ran basically as you've instructed:

$ ffmpeg -i ~/Desktop/in.mov -s 600x400 -pix_fmt rgb24 -r 10 -f gif - | gifsicle --optimize=3 --delay=3 > ~/Desktop/out.gif

This worked as advertised and I was delighted. However, my video (given I hadn't been so careful with dragging an exactly 600 x 400 rect) was of course skewed. Also, it appeared to be speed up like an old fashioned 30s movie). So, since for my purposes I didn't need much in terms of optimization (just to make the conversion from QT to an animated gif really), I did:

$ ffmpeg -i ~/Desktop/in.mov -pix_fmt rgb24 -f gif - | gifsicle --delay=3 > ~/Desktop/out.gif

which of course took a while longer, but worked for my purpose which was to leave a recording of the UX results of a pull request submission ✅ Again, thank you!

@trozler
Copy link

trozler commented Jun 30, 2020

Thanks for the guide really helpful. Also @roblevintennis thanks for the comment.
I tried to follow the steps given and they worked mostly, but it seems home-brew now installs the artefact in a different location than before.

So the command should be:
open /usr/local/Caskroom/xquartz/2.7.11/XQuartz.pkg

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