TOGIF(1)toolbelt manualTOGIF(1)

togif

Turn a video clip into a small GIF.

Synopsis

togif [options] video [-- ffmpeg options]

Description

togif cuts a part of a video and writes it as a GIF beside the video. It suits a bug report, a README or a chat message, where a video would not play inline.

demo.mp4 0:12 to 0:16 -> demo.gif (1.7MB, 48 frames, 480px, 2.1s)

A GIF holds at most 256 colours per frame. Made the plain way, with ffmpeg -i demo.mp4 demo.gif, it uses one fixed palette for everything, and the picture comes out grainy and banded. togif runs ffmpeg twice instead:

  1. The first run looks at every frame of the part you picked and builds the best 256 colours for it, with ffmpeg's palettegen filter.
  2. The second run draws each frame with that palette, with paletteuse.

It also scales the picture down to 480 pixels wide and drops the frame rate to 12 a second. A GIF has no real compression between frames, so its size grows with the width squared, the frame rate and the length. Those two defaults keep a few seconds of screen recording near 1 or 2 MB.

The video itself is never changed. The GIF goes beside it as name.gif, or name-1.gif when that name is taken.

Options

OptionWhat it does
-s, --start TIMEWhere to start. The default is the beginning.
-d, --duration SECSHow long the GIF runs, in seconds, such as 4 or 2.5.
-t, --to TIMEWhere to stop, instead of -d.
-w, --width PXWidth in pixels, 480 by default. A narrower video keeps its own width. The height follows.
-f, --fps NFrames a second, from 1 to 50. The default is 12.
--loopPlay again and again. By default the GIF plays once and stops on the last frame.
-o, --out NAMEName the GIF yourself.
-y, --yesAllow a GIF longer than 60 seconds.
-q, --quietShow only the result line.
-v, --verboseShow both ffmpeg commands before they run.
-h, --helpShow the help.

With no -d and no -t, the GIF runs to the end of the video. A length past the end stops at the end.

Times

You typeIt means
1212 seconds in
12.512 and a half seconds in
0:1212 seconds in, as a player shows it
1:051 minute 5 seconds in
1:02:031 hour, 2 minutes and 3 seconds in

Copy the times from the player, the way you watched the clip. togif -s 1:05 -t 1:09 gives the 4 seconds between them.

Safety checks

Size

A GIF has no real compression between frames, so the width counts twice. Half the width gives about a quarter of the size. The frame rate and the length count once each. Film and camera footage comes out larger than a screen recording of the same length, since every pixel changes in every frame.

To make a GIF smaller, lower -w first, then -f, then cut the part shorter.

Pass-through

Options after -- go to both ffmpeg runs, as output options. For example:

togif -d 4 demo.mp4 -- -threads 2

-threads 2 keeps ffmpeg from taking every core. Do not pass -vf or -filter_complex. togif builds its own filter, and ffmpeg refuses two.

Needs

ffmpeg, and ffprobe from the same package. The package is ffmpeg on Debian, Ubuntu, Arch and Alpine, ffmpeg-free on Fedora and ffmpeg-7 on openSUSE.

Examples

Four seconds from the middle

togif -s 0:12 -d 4 demo.mp4
demo.mp4 0:12 to 0:16 -> demo.gif (1.7MB, 48 frames, 480px, 2.1s)

From one time to another, looping

togif -s 5 -t 9.5 -w 320 -f 10 --loop demo.mp4
demo.mp4 0:05 to 0:09.5 -> demo-1.gif (410KB, 45 frames, 320px, 1.4s)

The ffmpeg commands

togif -v -s 0:12 -d 4 demo.mp4
+ ffmpeg -nostdin -hide_banner -loglevel error -y -ss 0:12 -t 4 -i demo.mp4 -vf 'fps=12,scale='\''min(480,iw)'\'':-1:flags=lanczos,palettegen' ./.togif-0dSakf/palette.png
+ ffmpeg -nostdin -hide_banner -loglevel error -y -ss 0:12 -t 4 -i demo.mp4 -i ./.togif-0dSakf/palette.png -lavfi 'fps=12,scale='\''min(480,iw)'\'':-1:flags=lanczos[x];[x][1:v]paletteuse' -loop -1 ./.togif-0dSakf/out.gif
demo.mp4 0:12 to 0:16 -> demo.gif (1.7MB, 48 frames, 480px, 2.1s)

A whole short clip

togif bug.webm
bug.webm 0:00 to 0:07.2 -> bug.gif (2.4MB, 86 frames, 480px, 3.0s)

A long video without a part picked

togif talk.mp4
togif: talk.mp4 from 0:00 is 9:42 long, over the 60s limit
togif: refused. Pick a part with -s and -d, or add -y

A start past the end

togif -s 1:05 -d 3 demo.mp4
togif: demo.mp4 is 0:30.5 long, so a start at 1:05 is past the end

A name of your own

togif -s 0:12 -d 4 -o docs/img/login-bug.gif demo.mp4
demo.mp4 0:12 to 0:16 -> docs/img/login-bug.gif (1.7MB, 48 frames, 480px, 2.2s)

Troubleshooting

The GIF is too big
Lower the width first, since it counts twice. -w 320 is about half the size of 480. Then lower the frame rate, and cut the part shorter.
The GIF looks choppy
Raise -f to 15 or 20. Screen recordings with a moving mouse show it most.
The colours band or flicker
A GIF has 256 colours per frame, and gradients and video footage need more. Shorter parts help, since the palette covers fewer scenes.
togif: ffmpeg could not read X. Run it with -v to see the command
Run the first command from -v by hand without -loglevel error to see ffmpeg's message.
togif: ffmpeg wrote an empty GIF, check the start and the length
The part holds no video frames, often a start inside the last fraction of a second.

Exit status

CodeMeaning
0The GIF was written.
1It failed. The file is missing, the start is past the end, or ffmpeg failed.
2Bad usage, such as -d and -t together, or a time it cannot read.
3ffmpeg or ffprobe is missing.
4Refused. Over 60 seconds without -y, or the -o name is taken.

See also

shrink, ffmpeg(1), ffprobe(1)