GIF screencasting; the UNIX way

OK then

GIF vimcast!

I started ffcast, did vim, quit ffcast, then converted .avi.gif.

I ran the recording commands in another terminal. Polished script for your $PATH at the end of this answer.

What happened?

Capturing

FFcast helps the user interactively select a screen region and hands over the geometry to an external command, such as FFmpeg, for screen recording.

ffcast is the glorious product of some hacking at the Arch Linux community (mainly lolilolicon). You can find it on github (or in the AUR for Archers). Its dependency list is just bash and ffmpeg, though you'll want xrectsel (AUR link) for interactive rectangle selection.

You can also append ffmpeg flags right after the command. I set -r 15 to capture at 15 frames per second and -codec:v huffyuv for lossless recording. (Play with these to tweak the size/quality tradeoff.)

GIFfing

ImageMagick can read .avi videos and has some GIF optimisation tricks that drastically reduce file size while preserving quality: The -layers Optimize to convert invokes the general-purpose optimiser. The ImageMagick manual has a page on advanced optimisations too.

Final script

This is what I have in my $PATH. It records into a temporary file before converting.

#!/bin/bash
TMP_AVI=$(mktemp /tmp/outXXXXXXXXXX.avi)
ffcast -s % ffmpeg -y -f x11grab -show_region 1 -framerate 15 \
    -video_size %s -i %D+%c -codec:v huffyuv                  \
    -vf crop="iw-mod(iw\\,2):ih-mod(ih\\,2)" $TMP_AVI         \
&& convert -set delay 10 -layers Optimize $TMP_AVI out.gif

Thanks to BenC for detective work in figuring out the correct flags after the recent ffcast update.

If you'd like to install the dependencies on a Debian-based distro, Louis has written helpful installation notes.

Wheeeeee!


For me, the answer was to use ffcast with ffmpeg like so:

ffcast -w % ffmpeg -f x11grab -show_region 1 -framerate 20 -video_size %s -i %D+%c -codec:v huffyuv -vf crop="iw-mod(iw\\,2):ih-mod(ih\\,2)" out.avi

I then used ffmpeg to do the conversion from avi to gif - it's very fast and it keeps the framerate intact:

ffmpeg -i out.avi -pix_fmt rgb24 out.gif

Lastly I used convert in the same way as @anko's answer to optimise the gif, but I set a limit on resource usage to stop convert exiting with a killed message, and I removed the delay as ffmpeg has already handled that:

convert -limit memory 1 -limit map 1 -layers Optimize out.gif out_optimised.gif

for my setup(ubuntu 16.04), ffcast doesn't work well as it's not updated on github for quite a while.

so I put up a script using slop(https://github.com/naelstrof/slop) and ffmpeg.

an example:

yay it's working

#!/bin/bash

read -r X Y W H G ID < <(slop -f "%x %y %w %h %g %i")
TMP_AVI=$(mktemp /tmp/outXXXXXXXXXX.avi)

ffmpeg -s "$W"x"$H" -y -f x11grab -i :0.0+$X,$Y -vcodec 
huffyuv -r 25 $TMP_AVI 

convert -set delay 5 -layers Optimize $TMP_AVI out.gif 

Update: Code updated, ffmpeg returns exit code 2 that prevents convert from executing as mentioned by Rub. After recording, hit ctrl+C will exit ffmpeg and run convert to generate the out.gif.