I Built a Tool on Google Colab to Convert Demo Videos to GIF and MP4
When you share a tool or product on GitHub or social media, attaching a demo video or GIF makes a huge difference in how well it communicates. But the moment you actually try to convert a video, you hit a wall: "SaaS tools require a subscription," "local apps are bloated," or "I have to look up the FFmpeg command every single time."
So I built a tool that runs FFmpeg in Google Colab's free environment and converts screen recordings directly to GIF or MP4 — no environment setup, no software installation, just a browser.
[New Feature] The tool now includes an optional zoom feature that lets you highlight specific moments in your screen recordings. Perfect for drawing attention to key interactions in demo videos.
What I Built
No setup required. Click the links below to run it in your browser instantly.
⚡️ Run in Google Colab
Make Demo GIF / MP4
Just open the link and run the cells from top to bottom.🐙 View the code on GitHub
hiroaki-com/colab-video-converter
Browse the source code, or leave a Star / Fork.
Why I Built This
Embedding a GIF in a GitHub README noticeably improves a project's first impression. Because visitors can instantly see the tool in action, I think it also increases the chances they'll actually read the page.
That said, the process of converting a screen recording to GIF has always been quietly tedious.
- SaaS tools: Convenient because everything runs in the browser, but fine-grained quality settings often require a paid plan.
- Local GUI apps: Some are downloadable and usable, but they tend to break with OS updates and become a maintenance headache.
- Using FFmpeg directly: The most flexible option, but looking up the right options every time is a drag. I always forget how to write the
palettegen+paletteusecombination.
As an engineer, getting up to speed on video conversion tools isn't where my learning should go, and paying ongoing SaaS fees didn't sit right either. I figured I'd rather build something myself that I could reuse however I wanted.
Google Colab lets you run FFmpeg for free, and building a UI inside a notebook means I never have to type the same commands again. That was the idea behind this tool.
How to Use It
No Python code required. Just run the cells from top to bottom and interact with the UI.
① Setup
Run the first cell. FFmpeg installs automatically.
② Upload Your Video
A file selection dialog opens — choose the video(s) you want to convert. Select multiple files if you want to merge them together.
Supported input formats: .mov .mp4 .avi .mkv .webm
③ Set the Merge Order (for multiple files)
If you uploaded multiple videos, use the dropdowns to specify the order they should be merged. This step is skipped automatically for a single file.
④ Configure Output Format, Quality, and Speed
Use the radio buttons to select your output format and quality.
Choosing an Output Format
| Format | Characteristics | Best For | Not Ideal For |
|---|---|---|---|
| GIF | Auto-plays, loops, works in any Markdown renderer. 256 colors, larger file size. | GitHub README, Zenn / Qiita | Size-constrained environments |
| MP4 (H.264) | High quality, small file size, full color. Requires a media player. | X / Slack / GitHub README (click-to-play) | Scenarios requiring auto-play or looping |
GIF Quality Presets
| Preset | Width | FPS | Colors | Use Case |
|---|---|---|---|---|
| GitHub README | 960px | 15fps | 256 | README embedding (recommended) |
| SNS / Lightweight | 640px | 10fps | 128 | Minimize file size |
| High Quality | 1280px | 20fps | 256 | Quality-first output |
| Custom | any | any | any | Fine-grained control |
MP4 Quality Presets
| Preset | CRF | Notes |
|---|---|---|
| High Quality | 18 | Larger file size |
| Standard | 23 | Balanced (recommended) |
| Lightweight | 28 | Smaller file size |
| Custom | 0–51 | Fine-grained control |
You can also adjust playback speed. Bumping a long recording to 1.5x or 2.0x is a great way to condense it into a tighter demo.
⑤ Generate Preview
Press the play button (▶) to generate a preview. This creates a preview video at the same resolution and frame rate as your final output, allowing you to check timestamps for zoom settings. If you want to tweak the settings and regenerate the preview, just change the settings in step ④ and re-run this cell — no need to start from the top.
The preview uses a fast encoding preset and excludes audio to speed up generation.
⑥ Review Preview
The preview video plays directly in the notebook with playback controls. Use the play/pause controls to identify the exact timestamps where you want to apply zoom effects. Note down these times — you'll need them for the next step if you want to add zoom.
⑦ Zoom Settings (Optional)
New Feature: You can now add zoom effects to highlight specific moments in your demo video.
How it works:
- Check the "Add zoom" checkbox to enable the zoom feature
- Click "+ Add Zoom Event" to add a new zoom configuration
- For each zoom event, configure:
- Zoom area: Select from a 3×3 grid (top-left, center, bottom-right, etc.)
- Max zoom: Peak zoom multiplier (1.1× to 5.0×)
- Start (s): Timestamp when zoom begins
- In (s): Duration to ramp from 1× to peak zoom
- Hold (s): Duration to hold at peak zoom
- Out (s): Duration to ramp from peak zoom back to 1×
Example Timeline: If you set Start=5.0, In=0.3, Hold=1.0, Out=0.3, the zoom will:
- Start at 5.0 seconds
- Zoom in from 1× to max over 0.3 seconds (5.0 → 5.3s)
- Hold at max zoom for 1.0 seconds (5.3 → 6.3s)
- Zoom out from max to 1× over 0.3 seconds (6.3 → 6.6s)
- Return to normal playback after 6.6 seconds
Tips:
- You can add multiple zoom events — perfect for highlighting several key moments
- Make sure zoom events don't overlap in time
- The 3×3 grid makes it easy to zoom into UI elements at specific screen positions
- Uncheck "Add zoom" to disable all zoom effects and return to standard output
Use Cases:
- Drawing attention to a button click in a UI walkthrough
- Highlighting code changes in an editor
- Emphasizing specific data in a dashboard demo
- Zooming into form fields during an input demonstration
⑧ Final Export
Press the play button (▶) to generate the final output with all your settings applied, including any zoom effects you configured. If you want to adjust zoom settings and re-export, just modify step ⑦ and re-run this cell.
The final export uses:
- For GIF: Full palette generation with your chosen dithering method
- For MP4: Slow preset for maximum compression efficiency (with audio if enabled)
⑨ Save
Select a save destination using the radio buttons and run the cell.
| Destination | Description |
|---|---|
| Download locally | Saved via the browser download dialog |
| Save to Google Drive | Auto-copied to the specified path (includes mount step) |
| Both | Executes both options simultaneously |
Key Features and Technical Notes
A few things I put thought into:
-
High-quality GIF conversion
GIF output quality depends heavily on FFmpeg filter configuration. This tool uses a two-pass
palettegen+paletteuseapproach:
[0:v] fps=15,scale=960:-1:flags=lanczos,split [a][b];
[a] palettegen=max_colors=256:stats_mode=full [p];
[b][p] paletteuse=dither=floyd_steinberg:diff_mode=rectangle
The lanczos filter improves resize quality, and floyd_steinberg dithering produces smoother color gradients. Custom mode also supports bayer dithering, letting you tune the quality-vs-file-size tradeoff.
-
Automatic file size warning
If a GIF exceeds 15 MB, the notebook automatically displays a warning with suggestions for reducing the size. Since GitHub's GIF limit is 10 MB, this lets you catch the issue before trying to embed it in a README.
-
Playback speed adjustment
Speed is controlled with the
setptsfilter. Bumping a longer recording to 1.5x or 2.0x also meaningfully reduces file size.
speed_filter = f'setpts={1/speed:.4f}*PTS,' # e.g., 1.5x speed → setpts=0.6667*PTS
-
Merging multiple videos
Uses FFmpeg's concat with
-c copyto copy the codec without re-encoding, so merging is fast. The dropdown UI lets you freely specify the merge order. -
Separated preview and final output
The workflow is now split into preview generation (step ⑤) and final export (step ⑧). This lets you review the exact timestamps in a full-quality preview before configuring zoom effects, and you can iterate on zoom settings without re-generating the base video.
-
Zoom functionality with FFmpeg zoompan filter
The zoom feature uses FFmpeg's
zoompanfilter to create smooth, dynamic zoom effects. Each zoom event is converted into a series of mathematical expressions that control the zoom level, x-position, and y-position frame-by-frame:# Example: Zoom into the center (area 5) with max zoom 2.0x
# Timeline: start=5.0, in=0.3, hold=1.0, out=0.3
# → Zoom from 1x to 2x over 0.3s, hold 2x for 1.0s, return to 1x over 0.3s
zoompan=z='if(gte(on,150),if(lt(on,159),(1+(2.0-1)*(on-150)/9),\
if(lt(on,189),2.0,\
if(lt(on,198),(2.0-(2.0-1)*(on-189)/9),1))),1)':
x='if(between(on,150,198),max(0,min(iw-iw/zoom,480-iw/(2*zoom))),0)':
y='if(between(on,150,198),max(0,min(ih-ih/zoom,270-ih/(2*zoom))),0)':
d=1:s=960x540:fps=15The tool automatically:
- Converts timestamps to frame numbers based on the video's FPS
- Calculates zoom center coordinates from the 3×3 grid position
- Generates smooth interpolation curves for zoom in/out transitions
- Handles multiple overlapping zoom events with proper precedence
-
Audio tempo adjustment for speed changes
When playback speed is adjusted for MP4 output with audio enabled, the tool uses FFmpeg's
atempofilter. Sinceatempoonly supports 0.5× to 2.0× per filter instance, the tool chains multiple filters for speeds outside this range:# Example: 3.0x speed requires two atempo filters
# 3.0 = 2.0 × 1.5
speed_filter = 'atempo=2.0,atempo=1.5' -
Efficient preview workflow
The preview (step ⑤) is generated with the
fastpreset to speed up iteration. The final export (step ⑧) then uses theslowpreset for maximum compression efficiency. If no zoom effects are configured, step ⑧ can reuse the preview's video stream directly with-c:v copy, making the final export nearly instantaneous.
Platform Size Limits
Limits vary by platform, so here's a reference. Zenn's 3 MB cap is quite strict — a realistic target is the SNS / Lightweight preset (640px / 10fps / 128 colors) combined with 1.5x playback speed.
| Platform | Supported Formats | Size Limit |
|---|---|---|
| GitHub README | GIF / MP4 / MOV | 100 MB (video) / 10 MB (GIF) |
| Zenn | GIF | 3 MB |
| Qiita | GIF / MP4 | 100 MB |
| X (standard) | MP4 / MOV | 512 MB |
| Slack | GIF / MP4 / MOV and more | 1 GB |
Wrapping Up
Three things aligned: I was tired of looking up FFmpeg commands every time, I didn't want to keep paying for a SaaS conversion tool, and I didn't want to install yet another local app. So I built this myself.
Packaging it as a Google Colab notebook means it runs in any browser, anywhere, with a GUI for all the settings. The new zoom feature makes it even easier to create professional-looking demo videos that highlight exactly what matters. Personally, attaching GIFs to READMEs has gotten dramatically easier since I started using it.
If you've ever thought "converting demo videos is such a pain every time" or "I wish I could emphasize specific moments in my screen recordings," I hope this helps.