How to create animated GIF images of a screencast?
I've seen animated GIF images of screen casts (like the one below) promoted a few times on this site as a way to improve answers.
What toolchain is being used to create these? Is there a program that does this automagically, or are people taking screencasts, converting them into a series of static frames, and then creating the GIF images?
616 Answers
Peek
Is a new application that lets you easily record GIF's from your screen.
Anyway, keep in mind that GIF's have a very limited color palette so it's not a very good idea to use them.
Since Ubuntu 18.10 you can install Peek directly.
sudo apt install peekFor older versions of Ubuntu, you can install the latest versions of Peek from its PPA.
sudo add-apt-repository ppa:peek-developers/stable
sudo apt update
sudo apt install peekFind more information in the GitHub repo.
10Byzanz
Best software I ever found to record GIF screencasts is Byzanz.
Byzanz is great because it records directly to GIF, the quality and FPS is impressive while maintaining the size of the files to a minimal.
Installation
Byzanz is now available from the universe repository:
sudo apt-get install byzanzUsage
When it is installed you can run it in a terminal.
This is a small example I did just now with
byzanz-record --duration=15 --x=200 --y=300 --width=700 --height=400 out.gifFirst install this:
sudo apt-get install imagemagick mplayer gtk-recordmydesktopthose are the required stuff, ImageMagick, MPlayer and Desktop Recorder. Then use Desktop Recorder to capture a portion of the screen/application to use as the screencast. After the Desktop Recorder has saved the recording into an OGV video, MPlayer will be used to capture JPEG screenshots, saving them into the 'output' directory.
On a terminal:
mplayer -ao null <video file name> -vo jpeg:outdir=outputUse ImageMagick to convert the screenshots into an animated gifs.
convert output/* output.gifyou can optimize the screenshots this way:
convert output.gif -fuzz 10% -layers Optimize optimised.gif 8 byzanz
Overview
This answer contains three shell scripts:
byzanz-record-window- To select a window for recording.byzanz-record-region- To select a part of the screen for recording.- A simple GUI front-end for 1.
Introduction
Thanks Bruno Pereira for introducing me to byzanz! It's quite useful for creating GIF animations. The colours may be off in some cases, but the file size makes up for it. Example: 40 seconds, 3.7Mb.
Usage
Save one/all of the following two scripts in a folder within your $PATH. Here's an example on using the first script to make a screencast of a specific window.
- Run
byzanz-record-window 30 -c output.gif - Go to the window (alt-tab) you want to capture. Click on it.
- Wait 10 seconds (hard-coded in
$DELAY), in which you prepare for recording. - After the beep (defined in the
beepfunction),byzanzwill start. - After 30 seconds (that's the meaning of
30in step 1),byzanzends. A beep will be broadcast again.
I included the -c flag in byzanz-record-window to illustrate that any arguments to my shell script are appended to byzanz-record itself. The -c flag tells byzanz to also include the cursor in the screencast.
See man byzanz-record or byzanz-record --help for more details.
byzanz-record-window
#!/bin/bash
# Delay before starting
DELAY=10
# Sound notification to let one know when recording is about to start (and ends)
beep() { paplay /usr/share/sounds/KDE-Im-Irc-Event.ogg &
}
# Duration and output file
if [ $# -gt 0 ]; then D="--duration=$@"
else echo Default recording duration 10s to /tmp/recorded.gif D="--duration=10 /tmp/recorded.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 --x=$X --y=$Y --width=$W --height=$H $D
beepbyzanz-record-region
Dependency: xrectsel from xrectsel. Clone the repository and run make to get the executable. (If it protests there is no makefile, run ./bootstrap and the ./configure before running `make).
#!/bin/bash
# Delay before starting
DELAY=10
# Sound notification to let one know when recording is about to start (and ends)
beep() { paplay /usr/share/sounds/KDE-Im-Irc-Event.ogg &
}
# Duration and output file
if [ $# -gt 0 ]; then D="--duration=$@"
else echo Default recording duration 10s to /tmp/recorded.gif D="--duration=10 /tmp/recorded.gif"
fi
# xrectsel from
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
beepGui version of byzanz-record-window
Script with a simple GUI dialogue:
#!/bin/bash
# AUTHOR: (c) Rob W 2012, modified by MHC ()
# NAME: GIFRecord 0.1
# DESCRIPTION: A script to record GIF screencasts.
# LICENSE: GNU GPL v3 ()
# DEPENDENCIES: byzanz,gdialog,notify-send (install via sudo add-apt-repository ppa:fossfreedom/byzanz; sudo apt-get update && sudo apt-get install byzanz gdialog notify-osd)
# Time and date
TIME=$(date +"%Y-%m-%d_%H%M%S")
# Delay before starting
DELAY=10
# Standard screencast folder
FOLDER="$HOME/Pictures"
# Default recording duration
DEFDUR=10
# Sound notification to let one know when recording is about to start (and ends)
beep() { paplay /usr/share/sounds/freedesktop/stereo/message-new-instant.oga &
}
# Custom recording duration as set by user
USERDUR=$(gdialog --title "Duration?" --inputbox "Please enter the screencast duration in seconds" 200 100 2>&1)
# Duration and output file
if [ $USERDUR -gt 0 ]; then D=$USERDUR
else D=$DEFDUR
fi
# Window geometry
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")
# Notify the user of recording time and delay
notify-send "GIFRecorder" "Recording duration set to $D seconds. Recording will start in $DELAY seconds."
#Actual recording
sleep $DELAY
beep
byzanz-record -c --verbose --delay=0 --duration=$D --x=$X --y=$Y --width=$W --height=$H "$FOLDER/GIFrecord_$TIME.gif"
beep
# Notify the user of end of recording.
notify-send "GIFRecorder" "Screencast saved to $FOLDER/GIFrecord_$TIME.gif"See also:
- byzanz-gui by rhcarvalho
- This other answer, another improved version of Rob W's
byzanz-record-region.
ffmpeg (install)
One of the best tools I use is ffmpeg. It can take most video from a screencast tool such as kazam and convert it to another format.
Install this from software-center - it is automatically installed if you install the excellent ubuntu-restricted-extras package.
Kazam can output in the video formats mp4 or webm. Generally you get better results outputting in mp4 format.
Example GIF making syntax
The basic syntax to convert video to gif is:
ffmpeg -i [inputvideo_filename] -pix_fmt rgb24 [output.gif]GIFs converted - especially those with a standard 25/29 frame-per-second can be very large. For example - a 800Kb webm 15-second video at 25fps can output to 435 MB!
You can reduce this by a number of methods:
Framerate
Use the option -r [frame-per-second]. For example
ffmpeg -i Untitled_Screencast.webm -r 1 -pix_fmt rgb24 out.gifSize reduced from 435 MB to 19 MB
File-size limit
Use the option -fs [filesize]. For example
ffmpeg -i Untitled_Screencast.webm -fs 5000k -pix_fmt rgb24 out.gifNote: This is an approximate output file size so the size can be slightly bigger than specified.
Size of output video
Use the option -s [widthxheight]. For example
ffmpeg -i Untitled_Screencast.webm -s 320x200 -pix_fmt rgb24 out.gifThis reduced the example 1366x768 video size down to 26 MB
Loop forever
Sometimes you might want the GIF to loop forever.
Use the option -loop_output 0. For example
ffmpeg -i Untitled_Screencast.webm -loop_output 0 -pix_fmt rgb24 out.gifFurther optimise and shrink
If you use imagemagick convert with a fuzz factor between 3% and 10% then you can dramatically reduce the image size
convert output.gif -fuzz 3% -layers Optimize finalgif.gifFinally
Combine some of these options to reduce to something manageable for Ask Ubuntu.
ffmpeg -i Untitled_Screencast.webm -loop_output 0 -r 5 -s 320x200 -pix_fmt rgb24 out.gifFollowed by
convert output.gif -fuzz 8% -layers Optimize finalgif.gifExample
Silentcast
Silentcast is another great gui based tool for creating animated .gif images. Its features include:
4 recording modes:
Entire screen
Inside window
Window with decoration
Custom selection
3 output formats:
.gif.mp4.webm.png(frames).mkv
No installation necessary (portable)
Custom working directory
Custom fps
Installation
If you want a regular installation and are running a supported version of Ubuntu you can install Silentcast by PPA:
sudo add-apt-repository ppa:sethj/silentcast
sudo apt-get update
sudo apt-get install silentcast If you aren't running a supported version of Ubuntu (you should really upgrade!) you will need to download the latest version from the GitHub page and manually satisfy the dependencies (you can procure yad and ffmpeg from here and here respectively) or, if you are running a slightly more recent version such as 13.10 you could try downloading the .deb directly.
If you're using Gnome you might want to install the Topicons extension to make stopping Silentcast easier.
Usage
Start Silentcast from your desktop environment's gui or run the silentcast command in a terminal. Pick your settings and follow the on-screen prompts. When you're done recording you will be presented with a dialog for optimizing the final output by removing a certain number of frames.
For more in depth usage guidelines take a look at the README, either the online GitHub version or the local version stored in /usr/share/doc/silentcast with zless or your favourite editor.
Notes:
Silentcast is still in the development stage and although it is quite stable you might encounter some bugs. If you do please report them on the project's GitHub issues tracker. If you have trouble installing from the PPA and are running a supported version of Ubuntu leave a comment below or contact the maintainer (me) on Launchpad.
5There are all sorts of complicated and well-working (presumably) ways to do this listed here. However, I've never wanted to go through that process before nor since. So, I simply use an online converter which suits my needs the few times I need to do so. I've used this site:
It's not my site and I'm not affiliated with them in any way. They're just the one in my bookmarks and there are many more.
1I created record-gif.sh, an improved version of Rob W's byzanz-record-region:
A lame GUI for
byzanz, improved the user experience (mouse-selectable area, record progress bar, replay-able recording).
- set recording
duration; - set
save_asdestination ; - select –with the mouse– the area to record ;
- create a script to replay recording (cf.
$HOME/record.again).
Install
I also created an installation script
curl --location | bash - 5 - Install these 3 packages:
imagemagickmplayergtk-recordmydesktop - Run Desktop Recorder to capture a portion of the screen/application to use as the screencast
- Download
ogv2gif.shfrom - Run:
./ogv2gif.sh yourscreencast.ogv - The GIF file will be put in the same directory
100% inspired from maniat1k's answer.
Ok, so in order to also capture mouse clicks, the only thing I found was key-mon (via the README of screenkey):
sudo apt-get install key-mon
Then I:
- Start
key-mon - Use
xrectselto get the screen coordinates put into abyzanzcommand - Run the
byzanzcommand
... and it looks sort of like this:
Note that key-mon --visible_click would draw a circle around the mouse pointer upon mouse click - which I would prefer, but in Ubuntu 14.04.5 LTS this is somewhat broken, as this circle does not appear and disappear fast enough in order to correctly illustrate the clicks (i.e. mouse presses and releases).
If you want to get even fancier, you can use a more sophisticated method than animated gifs using HTMl5 canvas screencasting. The x11-canvas-screencast project will create an html5 canvas animated screen capture.
You may have seen some famous examples of this tech on the Sublime Text website. x11-canvas-screencast takes this method a step further by incorporating tracking of the mouse cursor. Here's a demo of what x11-canvas-screencast produces
The result is better than an animated gif since it's not limited to the number of colors it has and it takes less bandwidth.
2I recently created combined version of scripts already posted here.
Basically, it allows you to record screen region, but with simple GUI.
Thanks for Rob W for providing those cool scripts
Here's the code (or gist if you like):
#!/bin/bash
#Records selected screen region, with GUI
#This is combined version of GIF recording scripts, that can be found here:
#Thanks to Rob W, and the other author (unmentioned), for creating this lovely scripts
#I do not own any rights to code I didn't write
# ~Jacajack
DELAY=5 #Delay before starting
DEFDUR=10 #Default recording duration
TIME=$(date +"%Y-%m-%d_%H%M%S") #Timestamp
FOLDER="$HOME/Pictures/Byzanz" #Default output directory
#Sound notification to let one know when recording is about to start (and ends)
beep() { paplay /usr/share/sounds/freedesktop/stereo/message-new-instant.oga &
}
#Custom recording duration as set by user
USERDUR=$(gdialog --title "Duration?" --inputbox "Please enter the screencast duration in seconds" 200 100 2>&1)
#Duration and output file
if [ $USERDUR -gt 0 ]; then D=$USERDUR
else D=$DEFDUR
fi
#Get coordinates using xrectsel from
REGION=$(xrectsel "--x=%x --y=%y --width=%w --height=%h") || exit -1
notify-send "GIFRecorder" "Recording duration set to $D seconds. Recording will start in $DELAY seconds."
for (( i=$DELAY; i>0; --i )) ; do sleep 1
done
#Record
beep
byzanz-record --cursor --verbose --delay=0 ${REGION} --duration=$D "$FOLDER/byzanz-record-region-$TIME.gif"
beep
notify-send "GIFRecorder" "Screencast saved to $FOLDER/byzanz-record-region-$TIME.gif" If you also want visible recordings of mouse clicks or key strokes, then screenkey is your best bet:
1Use gtk-recordmydesktop and ffmpeg :
apt-get install gtk-recordmydesktop ffmpeg
Run RecordMyDesktop capture a portion of the screen/application to use as the screencast :
gtk-recordmydesktopCreate ogv2gif.sh with following content :
INPUT_FILE=$1
FPS=15
WIDTH=320
TEMP_FILE_PATH="~/tmp.png"
ffmpeg -i $INPUT_FILE -vf fps=$FPS,scale=$WIDTH:-1:flags=lanczos,palettegen $TEMP_FILE_PATH
ffmpeg -i $INPUT_FILE -i $TEMP_FILE_PATH -loop 0 -filter_complex "fps=$FPS,scale=$WIDTH:-1:flags=lanczos[x];[x][1:v]paletteuse" $INPUT_FILE.gif
rm $TEMP_FILE_PATHUse it :
./ogv2gif.sh yourscreencast.ogvReferences :
I test all above method, found the most simple one is:
- use gtk-recordmydesktop and key-mon to get a ogv
- ffmpeg -i xx.ogv xx.gif <-- without any parameter.
the fps is original, and the gif size is less than ogv file.
This is the approach that I follow to record high-quality GIFs.
- Record the screen with a screen recorder such as Obs.
- Edit the video if necessary.
- Convert the video to a GIF using GifTuna.