Video tools

GIF to video

Convert an animated GIF into a video, in the browser only, like video-convert (src/tools/video-convert.ts), because encoding needs WebCodecs, which Node has no equivalent of. WebCodecs has no GIF codec at all, so this parses the GIF89a bytes itself (src/gif.ts), including disposal method and transparency compositing, so a GIF built from partial-frame deltas decodes to the same full frames a browser would show, not only its raw per-frame rectangles. It then feeds the composited frames to mediabunny/WebCodecs to encode. Always outputs MP4, following every other Node-native remux tool in this codebase; each frame's own GIF delay becomes its video frame duration. MP4 has no alpha channel, so any transparent GIF pixel, composited onto a canvas that starts fully transparent black, becomes opaque black in the video, not the checkerboard a GIF viewer shows; verified by executing this tool against a transparent fixture and reading the pixel back out. Nothing is uploaded.

Runs on your device. The file is never uploaded.

GIF to video turns an animated GIF into an MP4 named after the file, timing every frame from the delay stored beside it. Transparent pixels come out opaque black, since MP4 carries no alpha channel. The encode goes through WebCodecs, which Node lacks, so the command line refuses it.

Input

Questions

Why did my transparent GIF come out with a black background?

Because MP4 has no alpha channel. Frames are composited onto a canvas that starts fully transparent black, and any pixel that stayed transparent is written as opaque black in the video, not as the checkerboard a GIF viewer shows. This was checked by running the tool against a transparent file and reading the pixel back. Flatten the GIF onto the background colour you want first.

Does it keep the original timing?

Yes, per frame. Each GIF frame carries its own delay and that becomes that frame duration in the video. A GIF is allowed to declare a zero delay, meaning render as fast as possible, and a video sample cannot have zero duration, so those frames get a 20 millisecond floor instead. The result reports the total length it produced.

Does it handle GIFs built from partial frames?

Yes. The GIF is parsed by a GIF decoder built into this site, including disposal methods and transparency compositing, so a file made of small delta rectangles decodes to the same full frames a browser would show rather than to bare patches. That is why the tool does not simply hand raw frame data to the encoder.

What video format do I get?

Always MP4, named after your GIF with .mp4 on the end. The video codec is whichever encodable codec your browser offers first for MP4 at your GIF dimensions, encoded at medium quality. If your browser can encode nothing at that size, the tool says so: "this browser cannot encode a video into MP4" with the width and height named.

Why does it need a browser?

Because encoding runs through WebCodecs, which Node has no equivalent of. The command line and MCP surfaces refuse it with "gif-to-video needs a browser (OffscreenCanvas). Use it at /video/gif-to-video instead." Nothing is uploaded either way: the parse and the encode both happen in a Web Worker in your tab.

Why did my file fail to parse as a GIF?

Because the bytes did not parse as GIF89a. That covers a truncated download, a file renamed to .gif that is something else, and formats the decoder does not implement. The underlying parse error is included in the message so you can see what went wrong. Static images are better served by the image conversion tools.

Related Video tools