37

I see lots of folks posting animated GIF's showing off Emacs features, but I haven't seen a nice walk through on creating one. Is there any code that tries to link the keyframes of the gif to keypresses in Emacs? Is there any elisp packages or functions to automate the process? I'd love to be able to press a key to start recording, press it again to stop, and have it prompt for a filename to save the gif to.

Related question, is there a package for recording longer screencasts from within Emacs?

dgtized
  • 4,169
  • 20
  • 41
  • 90% of the question is off topic - asking about tools to make animated GIFs (of Emacs or anything else). The only part on topic is asking for Elisp code to automate that process. Consider editing the question title and body to ask only the latter: Elisp code to facilitate creating animated GIFs. – Drew Oct 08 '14 at 02:43
  • If you're looking for a Windows alternative, ScreenToGif (see screentogif.codeplex.com) might be your friend. It's an executable that allows you to speficiy frame a part of your screen, record it, edit it with text, or delete frames or speed it up, or slown down if you want. I use it for my screencasts. – ReneFroger Aug 16 '15 at 19:25

5 Answers5

24

Yes there is a package for recording screencasts in Emacs, it's called

camcorder.el

I can't promise anything yet, as I've only tested it on my computer, but I can tell you it works for me. :-)

  • To use it, simply call M-x camcorder-record.
  • A new smaller frame will popup and recording starts.
  • When you're finished, hit F12 and wait for the conversion to finish.

Screencasts can be generated in any format understood by imagemagick's convert command. You can even pause the recording with F11!

If you want to record without a popup frame, use M-x camcorder-mode.

Dependencies

For the recording, camcorder.el uses the following linux utilities. If you have these, it should work out of the box. If you use something else, you should still be able to make it work by configuring the camcorder-recording-command variable.

  • recordmydesktop
  • mplayer
  • imagemagick

Troubleshooting

On my machine, I noticed that the window-id Emacs reported with

(format "%x" 
 (string-to-number
  (frame-parameter (selected-frame) 'window-id)))

differed from the id that the WM reported with the wminfo utility.

I added the variable camcorder-window-id-offset to correct that. The default value is -4, but you might need to increase or decrease that to make those two numbers match.

Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • Purely because all the other answers used or mentioned Byzanz, I'm curious to know why it was that you rejected it? (in favour of recordmydesktop, it seems). – phils Nov 30 '14 at 06:08
  • @phils I couldn't get byzanz to work with variable duration, I had to give it a predetermined duration. recordmydesktop works with kill signals. – Malabarba Dec 03 '14 at 09:18
  • I used `xwininfo` to determine the right ID to use (I don't have a `wminfo` on my system). – YoungFrog Mar 18 '19 at 20:05
  • I also noticed newer versions of camcorder use `outer-window-id` (instead of `window-id`) and there's no need for an offset anymore, but this change hasn't landed on melpa-stable yet. – YoungFrog Mar 18 '19 at 20:06
  • 1
    @YoungFrog thanks for the reminder. I've pushed a stable release now. – Malabarba Mar 18 '19 at 21:46
20

I posted a similar question on /r/Emacs.

For recording GIFs, your main options are:

  • byzanz-record:
# 12 second duration, top left corner, 700x800 pixel gif
$ byzanz-record -d 12 -x 0 -y 0 -w 900 -h 700 output.gif
# more documentation at https://wiki.ubuntu.com/CreatingScreencasts
  • LICEcap (Windows and OS X)
  • ffmpeg/avconv (avconv is a fork of ffmpeg):
$ avconv -y -video_size 200x100 -f x11grab -i :0.0+0,50 frame-%04d.gif
$ gifsicle --loop -O3 -d5 frame-*.gif > emacs.gif

To show keystrokes, you just need an application that shows keystrokes. key-mon provides a GUI app for this. There is, of course, an Emacs mode for showing keys pressed: command-log-mode.

Wilfred Hughes
  • 6,890
  • 2
  • 29
  • 59
5

I used Byzanz to generate all my GIFs. I record with one screen to run the byzanz command, one for recording. Some examples are in my guide here.

Tu Do
  • 6,772
  • 20
  • 39
4

I used Byzanz to record gifs

Install it first, put this snippet into rr(record region) into your $PATH:

#!/bin/bash
# record screencast of a region into a gif using `byzanz-record`

# Delay before starting
DELAY=5

# Sound notification to let one know when recording is about to start (and ends)
beep() {
    paplay /usr/share/sounds/KDE-Im-Irc-Event.ogg &
}

printf "usage: rr [time] [file]\n"

# Duration and output file
if [ $# -gt 0 ]; then
    D="--duration=$@"
else
    echo Default recording duration 10s to $HOME/recorded.gif
    D="--duration=10 $HOME/rarecorded.gif"
fi

# xrectsel from https://github.com/lolilolicon/xrectsel
ARGUMENTS=$(xrectsel "--x=%x --y=%y --width=%w --height=%h") || exit -1

echo Delaying $DELAY seconds. After that, byzanz will start
for (( i=$DELAY; i>0; --i )) ; do
    echo $i
    sleep 1
done
beep
byzanz-record --verbose --delay=0 ${ARGUMENTS} $D
beep

and this into rw(record window) into your $PATH:

#!/bin/bash
# record screencast of a region into a gif using `byzanz-record`

# Delay before starting
DELAY=5

# Sound notification to let one know when recording is about to start (and ends)
beep() {
    paplay /usr/share/sounds/KDE-Im-Irc-Event.ogg &
}

printf "usage: rr [time] [file]\n"

# Duration and output file
if [ $# -gt 0 ]; then
    D="--duration=$@"
else
    echo Default recording duration 10s to $HOME/recorded.gif
    D="--duration=10 $HOME/rarecorded.gif"
fi


XWININFO=$(xwininfo)
read X < <(awk -F: '/Absolute upper-left X/{print $2}' <<< "$XWININFO")
read Y < <(awk -F: '/Absolute upper-left Y/{print $2}' <<< "$XWININFO")
read W < <(awk -F: '/Width/{print $2}' <<< "$XWININFO")
read H < <(awk -F: '/Height/{print $2}' <<< "$XWININFO")

echo Delaying $DELAY seconds. After that, byzanz will start
for (( i=$DELAY; i>0; --i )) ; do
    echo $i
    sleep 1
done
beep
byzanz-record --verbose --delay=0 ${ARGUMENTS} $D
beep

Now you can use rr and rw to record region/window to gifs(you can change the time and position for your needs.)

CodyChan
  • 2,599
  • 1
  • 19
  • 33
2

One more option using QuickTime player (it works on OSX, I don't know on Windows). Requisites are: ffmpeg and gifsicle

  • Open QuickTime and start File -> New Screen Recording
  • When finish File -> Export -> As Movie with option full quality
  • Now convert your screen cast with this command:
    • ffmpeg -i yourscreen.mov -s 600x400 -pix_fmt rgb24 -r 10 -f gif - | gifsicle --optimize=3 --delay=3 > out.gif
Enrico Pirani
  • 367
  • 2
  • 10