utilime

Small tools that finish the job.

Convert a GIF to MP4

The same animation as video, at a fraction of the bytes.

Drop a file hereor click to choose · it stays on your device

How it works

An animated GIF and an H.264 video of the same seconds are nowhere near the same size, and the reason is a twenty-five year gap in what each format is permitted to do. GIF stores a frame as palette indices run through LZW, a general-purpose byte compressor with no idea it is looking at a picture. Its one concession to the similarity between consecutive frames is to redraw a smaller rectangle. Whatever falls inside that rectangle is described again from nothing.

H.264 was built for precisely the thing GIF cannot express. It predicts a block of pixels from a block somewhere in an earlier frame, at an offset the encoder searches for and stores as a motion vector, so a slow pan costs little beyond the vectors themselves. The residue the prediction gets wrong goes through a discrete cosine transform and is quantised, discarding the high-frequency detail the eye is worst at seeing before any entropy coding begins. And it works in continuous colour rather than through a table of 256 entries.

Stack those up and the ratio stops being a surprise. Wikimedia's "Rotating earth (large)" is 1,001,718 bytes holding 44 frames of 400×400, each shown for 90 milliseconds, so 3.96 seconds of animation at about 253,000 bytes per second. The balanced setting below budgets 0.1 bits for every pixel of every frame, which for 400×400 at 11.1 frames per second is roughly 178 kbps, or 88 KB for the whole thing. Camera footage widens the gap further, because reducing a photographic frame to 256 colours introduces dither noise that LZW then has to store.

What an MP4 will not do for you

The cost list is short and every item on it is real. An MP4 has no loop flag. GIF89a carries a Netscape application extension naming a repeat count, and browsers honour it; the ISO base media format has no equivalent field, so a video repeats only when whatever is playing it has been told to, through a `loop` attribute on a `<video>` element or a preference in an app. The same file therefore cycles on one site and stops dead on another, and nothing inside the file decides which.

Autoplay is the second item. A GIF is an image, so it animates anywhere an image renders: an email client, a Markdown preview, a wiki. Video autoplays under rules that differ per platform and generally demand that it be muted first. And a good many forums, issue trackers and chat clients will take an image upload while rejecting a video outright, a policy about file extensions that has nothing to do with size.

The case that actually sends people here

An upload limit, almost always. A recording exported as GIF comes to 40 MB against a 25 MB ceiling, and the reflex is to attack the GIF: fewer colours, fewer frames, half the width, until it fits and looks like something that has been made to fit. Where the destination accepts video, none of that is necessary. The same frames at the same size and the same rate, written as H.264, usually clear the limit with room to spare. The fix is to stop the file being a GIF rather than to make it a worse one.

Frame timing, which is the whole job

GIF delays are per frame, held in hundredths of a second inside each graphic control extension, and they are often unequal — a caption card held for a full second in an animation running at 50 milliseconds everywhere else. A video track carries a timestamp per frame, so each frame here is written at the running total of every delay before it and the pause survives intact. Assuming one constant rate is exactly what makes a converted GIF play at the wrong speed.

One behaviour is copied from browsers rather than from the specification. A stated delay of 0 or 1 hundredth is read as 100 milliseconds, because that is what Chrome, Firefox and Safari do with it, and a file authored at 0 was authored against their behaviour. Honouring such a value literally would play the result ten times faster than its author ever saw it. The frame rate control under Fine tune resamples onto a constant grid on purpose, for editing software that insists on one.

Dimensions, colour and what the encoder adds

H.264 stores colour at half resolution along both axes, so each side of the frame has to be even. An odd width is padded by one duplicated column of the edge rather than rescaled, which leaves every original pixel exactly where it was. Colour improves in the other direction: the 256-entry palette that constrained the GIF is gone, so areas that had to be dithered come out flat.

What the encoder contributes is its own loss, mostly ringing around hard edges and mosquito noise around text. That is the reverse of the GIF failure mode, where edges stay crisp and gradients band, so a screen recording full of small type is worth converting at the crisp setting rather than the small one. Transparent regions are filled with white before encoding, because H.264 carries no alpha channel and the alternative is a black rectangle where the page used to show through.

Questions

Where do the frames go while this runs?

Into memory in this tab and nowhere else. The GIF decoder is a few hundred lines of integer arithmetic shipped with the page, and the encoder is WebCodecs, the browser's own hardware path. Both run in a Web Worker on your machine. There is no endpoint on this site that accepts a file, so there is nothing for a request to be sent to; the Network tab will show this page's own code being fetched and nothing else appearing while the conversion runs.

Will the MP4 loop the way the GIF did?

Only where the player loops it. The repeat count is a field GIF has and MP4 does not, so it cannot be carried across. On a page of your own, add the `loop` attribute to the `<video>` element and it will cycle. On a social platform, the platform decides, and most of the ones that accept short video loop it by default. In a desktop player it is usually a menu item that is off until you turn it on.

Why did a small GIF come out bigger as an MP4?

Because the bitrate is a budget the encoder is allowed to spend, and a short animation of flat colour was not spending anything like it. Twelve frames of a two-colour spinner compress to almost nothing under LZW, while H.264 still writes a keyframe, a header and a moov atom. Below roughly a hundred kilobytes the swap rarely pays. Drop to the small setting, or keep the GIF, which for that kind of graphic is the format that suits it.

Can I get the animation back out of the MP4 afterwards?

Yes, through the mp4-to-gif page, but not without loss. This conversion discards colour precision that the GIF never had, so the round trip does not return the file you started with: the second GIF is quantised from the encoded video, complete with whatever ringing the encoder introduced. Keep the original if it might be needed again.