Convert a video clip to an animated GIF with a palette built from your own frames, four dithering modes each labelled with its measured size cost, a loop count that really reaches the file, and frame rates marked for whether a GIF can hold them exactly.
Initializing in your browser…
Build an animated GIF89a written from the specification and read back before download, so the frame count, the delays, the loop count and the palette size are reported from the finished file rather than from the request.
Cut a clip out of a video, choosing whether the cut lands on the exact frame (re-encodes to MP4) or leaves the streams untouched (instant and lossless, but only at a keyframe). The result says which ran and reads the real length back off the file.
Convert a video between MP4, WebM, OGG, MOV, AVI and MKV, each naming the codecs it really writes and each producing a file that actually plays. One quality dial normalised into four different encoder scales.
One second of a 30 fps clip, starting at 0.700 s, as a 320 px wide GIF that plays through once.
Input
counter.mp4 · start 0.700 s · 1.0 s · 10 fps · 320 px · Once
Output
10 frames, every delay exactly 10 hundredths, total 1.00 s, no loop block
Every one of those numbers is checkable in the file the tool produced, and each was wrong before: the GIF started one source frame after the previewed one because the frame rate filter centred its output slots, and it looped forever whatever the loop buttons said. 10 fps is one of the rates a GIF can hold exactly, since its frame delays are whole hundredths of a second, and Once is written as no loop extension at all rather than as a count.
GIF is a 1987 format that should have been retired two decades ago and stuck around because every platform renders it inline without asking. Its limits are hard ones: at most 256 colours per frame taken from a palette written into the file, no audio, and LZW compression that is far behind any video codec. A five second 1080p clip as a GIF is routinely five to fifteen times the size of the same clip as MP4, and worse to look at. People convert anyway because Slack, Discord, GitHub and most email clients autoplay a GIF and are inconsistent about video. Two of those limits decide almost everything this tool does. The first is the palette. Left alone, ffmpeg quantises to a fixed RGB lattice that has nothing to do with your pictures: measured on a smooth gradient, that gave a mean per-channel error of 18.2 levels in a 119 KB file. Building the palette from your own frames instead gave a mean error of 4.4 in a 72 KB file, so it is both four times more accurate and forty percent smaller. That is not a tradeoff, it is just better, and it is what this tool now does. The second is the clock. A GIF stores each frame's delay as a whole number of hundredths of a second, so the only rates it can hold exactly are 100 divided by a whole number: 50, 33.3, 25, 20, 16.7, 12.5, 10, 5. 15, 24 and 30 fps are not among them. ffmpeg deals with this better than you might fear, alternating delays (15 fps comes out as 7, 6, 7, 7, 6, 7 hundredths) so the total length stays exact and only individual frames land up to a hundredth of a second early or late. The frame rate buttons here say which rates are exact and which are not.
Pick the moment with the start and end frame previews, then keep it short: the file is close to linear in frame count.
Screen recordings are mostly flat colour, so 64 colours is often indistinguishable from 256 and about half the size.
Use Once rather than Forever for a step-by-step demo, so the reader sees it play through and stop.
10 fps at 480 pixels wide is usually under a megabyte for a few seconds and is exact on a GIF clock.
Dithering is the one genuine tradeoff, and it is worth stating with numbers rather than adjectives. On the gradient test clip, one 640x480 frame, all with a palette built from the pictures: no dithering gave the lowest error of all (4.39) in the smallest file (72 KB) but left flat bands up to 68 pixels wide across the gradient, which is the artefact people actually notice; ordered (Bayer) dithering broke those bands into 6 pixel runs for 129 KB and an error of 5.17; and Floyd-Steinberg error diffusion produced 1,185 KB, sixteen times the no-dither file, because the fine noise it scatters is exactly what LZW cannot compress. Ordered is the default here for that reason. All four are offered, each button labelled with its measured size cost.
Colour count is the other lever and it behaves predictably. Measured on the same clip with ordered dithering: 32 colours gave 38 KB, 64 gave 56 KB, 128 gave 79 KB and 256 gave 111 KB, and the number of distinct colours in the decoded output matched the request exactly each time. Fewer colours is a smaller file and more banding, and on flat graphic content (screen recordings, diagrams, line art) 64 is often indistinguishable from 256.
The two biggest levers are still frame count and width. A GIF is a sequence of separately compressed frames, so its size is close to linear in the frame count: halving the rate roughly halves the file. Width is stronger than that, because bytes scale with pixel count, so 320 pixels wide is about a quarter of 640 pixels wide. The size prediction here is measured rather than guessed: press Measure a sample and it builds half a second of GIF at your exact settings and scales the bytes per frame, which works well precisely because GIF frames do not depend on each other.
Two smaller details this tool gets right. The clip starts on the frame you selected: input seeking is frame accurate in this build, but the frame rate filter's default rounding centres each output slot, which put the first GIF frame one source frame after the one the Start frame preview was showing; it now rounds so that output frame k is the frame the video was showing at exactly start plus k over fps. And the loop setting reaches the file: Forever writes loop count 0, "3 times" writes loop count 3, and Once writes no loop extension at all, which is the only reading every decoder agrees on.
Because GIF stores every frame separately with no motion prediction. Cut the frame count (a lower frame rate or a shorter clip) or the width, which is stronger still because bytes scale with pixel count. Switching the dithering to None also cuts the size sharply at the cost of visible banding on gradients.
Ordered is the default and usually right: on the test gradient it removed the banding for about eighty percent more bytes. None is the smallest and the most accurate pixel for pixel, but leaves wide flat bands on anything smooth. The two error diffusion modes look best on photographic content and are roughly sixteen times larger, because the noise they add is exactly what LZW cannot compress.
A GIF holds at most 256 colours, chosen here from your own frames rather than from a fixed table. On a smooth gradient that gets the mean per-channel error down to about 4 levels out of 255. On content with a lot of distinct hues, raising the colour count to 256 and using ordered dithering is as close as the format allows.
You can pick any listed rate, but a GIF delay is a whole number of hundredths of a second, so 30 fps is 3.33 of them and cannot be held exactly. The exact rates are 100 divided by a whole number: 50, 33.3, 25, 20, 16.7, 12.5, 10 and 5. The rates offered here are mostly exact ones, and the ones that are not say so and explain that the total length still comes out right.
Yes. GIF89a does not define a loop count at all; looping is the NETSCAPE2.0 extension block that came later. Once writes no such block, which every decoder reads as a single play. A numbered choice like 3 times writes loop count 3, which Chrome and Firefox play three times and some older viewers play four.
Yes, and it did not before. Seeking to your start time is frame accurate, but the frame rate filter used to centre each output slot, which put the first GIF frame one source frame later than the preview pane was showing. It now takes the frame the video was showing at exactly your start time, and at each multiple of one over the frame rate after it.
Video is decoded and re-encoded on your own device. Large files never leave your machine.