Skip to content
Create a gist now

Instantly share code, notes, and snippets.

OS X Screencast to animated GIF

OS X 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

See also

I ended up rewriting this gist's functionality into screengif, a ruby script with significant quality improvements and a few gratuitous features. Check it out at https://github.com/dergachev/screengif

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

GIF-Screencast-OSX performance testing

I was 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 my experiments of converting a 3.8 second movie to a GIF.

FFMPEG to PNG -> CONVERT to GIF individually

  • 42 seconds in CONVERT, did not determine file size
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 -> CONVERT TO GIF in 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 -> CONVERT to GIF in 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 -> CONVERT to GIF in 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 -> CONVERT to GIF in 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

@thany
thany commented Jan 30, 2013

This is, of course, not completely specific to OSX. The first part yes, but screen capture software is available for any graphical OS. And so is ffmpeg.

@tdm00
tdm00 commented Sep 4, 2013

Should include directions for installing cask if it's not already installed on the users system, see https://github.com/phinze/homebrew-cask for installation directions.

@jamiecurle

When I tried to install x-quartz using cask I got this

brew cask install x-quartz
Error: No available cask for x-quartz

changing it to this worked a charm

brew cask install xquartz
==> Downloading http://xquartz.macosforge.org/downloads/SL/XQuartz-2.7.5.dmg
# blah blah

Just in case anyone else has this problem.

@Ruxton
Ruxton commented Nov 25, 2013

Or just use licecap.

http://www.cockos.com/licecap/

@ronanguilloux

+1 for licecap !

@mandymcclausky

I love LICEcap, but it has a few issues to keep in mind for screen capture, both in interface and implementation --

  • Doesn't allow you to capture the full screen
  • The interface doesn't adapt well to smaller widths, leaving you to resize after the recording has begun (i.e. when capturing from iOS Simulator) and then crop it accordingly in post
  • Doesn't account for retina devices, leaving you with a lower resolution than you'd expect
  • The native format that allows you to record in lossless requires paid software (Reaver) to open/manipulate. Even recording in this format doesn't seem to account for HiDPI and I had issues with color depth (banding gradients in particular)
@nealrs
nealrs commented Mar 7, 2014

This is an awesome workflow! I had some issues with homebrew and had to download XQuartz manually, but it was smooth sailing after that. I decided to take it a step further, adding resizing options in bash & incorporating Andrea Fabrizi's Dropbox Uploader.

Now, you can automatically resize & convert .mov, upload to Dropbox, and get a public link for your .gif!

$ movgif input.mov [max-width]

FYI - You'll need to install Dropbox Uploader, setup a new app, add your API keys, and alias the script as dbu in your .bash_profile, but that takes all of 3 minutes.

movgif(){

  # check for input file
  if [ -z "$1" ]
    then
      echo "$(tput setaf 1)$(tput setab 7)PROPER USAGE: $ movgif input.mov [max width in pixels]$(tput sgr 0)"
      kill -INT $$
  fi

  # check for & set optional max-width
  if [ ! -z "$2" ]
    then
      maxsize="-vf scale=$2:-1"
    else
      maxsize=""
  fi    

  # set output & run conversion
  out="$1_$(LC_CTYPE=C tr -cd '[:alnum:]' < /dev/urandom | fold -w8 | head -n1).gif"    
  ffmpeg -i $1 $maxsize -pix_fmt rgb24 -r 10 -f gif - | gifsicle --optimize=3 --delay=3 > $out
  echo "$(tput setaf 2)output file: $out$(tput sgr 0)"

  # upload to dropbox & get sharing link
  dbu upload "$out" /
  dbu share "$out"
}
@timuric
timuric commented Apr 23, 2014

Neat tool for converting video to gif http://www.gifrocket.com/

@jwerle
jwerle commented May 28, 2014

I made a small shell script for automating this process and decided to user convert to generate the gif :]

https://github.com/bpkg/osx-screencast

@d1egoaz
d1egoaz commented Jul 28, 2014

Tks @jwerle, I prefer using convert, and not to have to install xquartz

@thom-nic
thom-nic commented Oct 2, 2014

I had best results using imagemagick like this:

ffmpeg -i input.mov -vf scale=800:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 5 -layers Optimize -loop 0 - out.gif

Fast, better color quality, still small and no intermediate files seems like the best of all worlds.

@acarrillo

Fantastic writeup -- thank you!!!

@verpixelt

I get empty gifs and this message in the terminal. Any ideas what I'm doing wrong?

ffmpeg -i grunt-livereload.mov -s 600x400 -pix_fmt rgb24 -r 10 -f gif - | gifsicle —optimize=3 —delay=3 > grunt-livereload.gif
gifsicle:—optimize=3: No such file or directory
gifsicle:—delay=3: No such file or directory
ffmpeg version 2.5.3 Copyright (c) 2000-2015 the FFmpeg developers
  built on Jan 17 2015 12:08:40 with Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/2.5.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libmp3lame --enable-libvo-aacenc --enable-libxvid --enable-vda
  libavutil      54. 15.100 / 54. 15.100
  libavcodec     56. 13.100 / 56. 13.100
  libavformat    56. 15.102 / 56. 15.102
  libavdevice    56.  3.100 / 56.  3.100
  libavfilter     5.  2.103 /  5.  2.103
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'grunt-livereload.mov':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2015-03-03 18:44:53
  Duration: 00:00:10.02, start: 0.000000, bitrate: 3168 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 2880x1800, 3160 kb/s, SAR 1:1 DAR 8:5, 60 fps, 60 tbr, 6k tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2015-03-03 18:44:53
      handler_name    : Core Media Data Handler
      encoder         : H.264
Incompatible pixel format 'rgb24' for codec 'gif', auto-selecting format 'rgb8'
@mejackreed

Ok a shout out to my co-worker @jkeck who made this: https://github.com/jkeck/make-me-a-gif

@jasonmelgoza

Here's a blog post I wrote a few months back on the subject. http://eng.rightscale.com/2014/08/20/gif-and-tell.html

Enjoy

@jasonm23
jasonm23 commented Mar 6, 2015

Alternatively

Wrap up that ffmpeg / imagemagick one-liner (and forget gifsicle, it produces low quality gif frames.)

movtogif(){
    ffmpeg -i "$1" -vf scale=800:-1 -r 10 -f image2pipe -vcodec ppm - |\
    convert -delay 5 -layers Optimize -loop 0 - "$2"
}

(You could call it vidtogif if preferred, FFMpeg will handle pretty much anything you throw at it.)

Usage

movtogif input.mov out.gif

Dependencies

  • ImageMagick
  • FFMpeg

OSX / Brew

brew update
brew install ffmpeg
brew install imagemagick
@slhck
slhck commented Mar 6, 2015

You definitely need to change -s 600x400 to a scaling filter. Otherwise you'll end up distorting your video.

ffmpeg -i input.mov -filter:v scale=800:-1 -pix_fmt rgb24 -r 10 -f gif - 
@osaft
osaft commented Mar 6, 2015

Mhmm why not just use http://www.cockos.com/licecap/ (Open Source for Win/OSX)?

@RodrigoEspinosa

Thanks @dergachev! I am using this alias for convert from mov to gif https://gist.github.com/RodrigoEspinosa/68e61f5aff3846fc974e

@Demcka
Demcka commented May 5, 2015

I remember being fairly unimpressed of QuickTime Player, is there any particular reason you went for it? Currently using Gif Master (https://itunes.apple.com/ru/app/gif-master/id957314225?l=en&mt=12), a very decent application, albeit not free.

@aaron-elkins

Or just use Capture Gif if on Mac.

http://www.pixelegg.me/capture-gif

@rafaelrinaldi

Just FYI, XQuartz's id on Cask's registry has changed.

$ brew install xquartz # no hyphen
@davidcalhoun

Thanks for the tip about xquartz above! That fixed my error. Pasting the error here for folks searching for solution:

Error: No available Cask for x-quartz. Did you mean:
xquartz
Error: nothing to install

The fix:
$ brew install xquartz

@ldong
ldong commented Oct 9, 2015

I will just use screengif then.

@Poltergeist

@verpixelt you need to install gifsicle.

@andreif
andreif commented Oct 30, 2015

It worked only with @slhck's command for me. Thanks!

@kuno
kuno commented Dec 8, 2015

thanks, this save my day : >

@danielabar

Thanks for sharing, this worked for me perfectly!
(didn't have to run the xquartz installer (OSX 10.10.5)

@cdaringe

you rock so hard.

@soferio
soferio commented May 8, 2016

I downloaded Gifox, and then use gifsicle with the -O3 setting "gifsicle -O3 --colors 256 < BeforeGif.gif -o AfterGif.gif". It is a pretty good combination. Thanks for the reference to gifsicle. Cheers.

@Vinc26
Vinc26 commented May 22, 2016

Hi, if you make gif to tweet it, you have a very quicker solution: https://twitter.com/arcticwhiteness/status/733682833382907905

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.