FFmpeg-only video to GIF converter with palettegen/paletteuse and size targeting.
Project description
vi2gifx — FFmpeg-only video → GIF converter
A clean, configurable Python CLI that converts and optimizes videos to GIFs using FFmpeg’s palettegen → paletteuse workflow. Includes optional size targeting (stay under a byte budget), frame-accurate seek, and VFR preservation.
Installation (from PyPI)
# 1) Have FFmpeg installed and on your PATH
# macOS: brew install ffmpeg
# Ubuntu: sudo apt-get install ffmpeg
# Windows: winget install ffmpeg (or download from gyan.dev)
# Verify: ffmpeg -version
# 2) Install the CLI
pip install vi2gifx
After install you’ll have a shell command named
vi2gifx.
Quick start
vi2gifx input.mp4 output.gif
Converts the whole video using a good default FPS and an adaptive palette for quality colors.
Common recipes (copy-paste friendly)
Each example includes what it does.
- Social-ready (smaller, crisp)
vi2gifx in.mp4 out.gif --preset social
fps=12, width=480 — great balance of size & clarity.
- Tiny footprint (docs, PRs, chats)
vi2gifx in.mp4 out.gif --preset tiny
fps=8, width=360, colors=64 — aggressively small.
- High-quality demo
vi2gifx in.mp4 out.gif --preset hq
Higher FPS/width; larger files.
- Cap width (keep aspect)
vi2gifx in.mp4 out.gif --width 480
- Fixed dimensions (may change aspect)
vi2gifx in.mp4 out.gif --width 640 --height 360
- Lower FPS for size
vi2gifx in.mp4 out.gif --fps 10
- Limit colors for size
vi2gifx in.mp4 out.gif --colors 96
- Change dithering style
vi2gifx in.mp4 out.gif --dither floyd_steinberg
- Trim a segment
vi2gifx in.mp4 out.gif --start 3.2 --duration 6.5
- Frame-accurate trimming (avoid keyframe snap)
vi2gifx in.mp4 out.gif --start 3.2 --duration 6.5 --seek-accurate
- Preserve original timing (VFR)
vi2gifx in.mp4 out.gif --keep-vfr
Skips the fps filter; uses per-frame delays.
- Crop before scaling
vi2gifx in.mp4 out.gif --crop 480:480:100:60 --width 480
- Deinterlace first
vi2gifx in.mp4 out.gif --deinterlace
- Control loop count
vi2gifx in.mp4 out.gif --loop 0 # infinite (default)
vi2gifx in.mp4 out.gif --loop 1 # play once
- Hard cap the final size (size targeting)
vi2gifx in.mp4 out.gif --max-bytes 4_000_000
Iteratively shrinks colors → fps → width until ≤ 4 MB (respects floors).
- Size cap with quality floors
vi2gifx in.mp4 out.gif --max-bytes 3_000_000 --min-colors 48 --min-fps 8 --min-width 320
- Motion-first preference
vi2gifx in.mp4 out.gif --max-bytes 4_000_000 --min-fps 12
Keeps FPS higher; reduces colors/width instead.
How size targeting works (brief)
When you pass --max-bytes, vi2gifx performs first-fit trials that reduce colors → fps → width along gentle ladders (e.g., colors 256→128→96→64, fps 12→…→6, width 720→…→min) and stops at the first result under your byte budget. If nothing fits, it writes a best-effort file using the floors and warns that it’s over budget. Steer trade-offs with --min-colors, --min-fps, --min-width.
CLI reference
usage: vi2gifx INPUT OUTPUT [options]
positional arguments:
INPUT Input video file
OUTPUT Output GIF path (e.g., out.gif)
core quality/size:
--fps INT Frames per second (default 12 unless --keep-vfr)
--width INT Scale to this width (keeps aspect unless height also set)
--height INT Scale to this height (keeps aspect unless width also set)
--colors INT Palette colors (2–256). Fewer = smaller
advanced tuning:
--dither {none,bayer,floyd_steinberg,sierra2,sierra2_4a}
Dither algorithm (default: sierra2_4a)
--stats-mode {full,diff}
palettegen statistics mode (default: full)
trim/crop/deinterlace:
--start FLOAT Start time in seconds
--duration FLOAT Duration in seconds
--crop W:H:X:Y Crop region before scaling
--deinterlace Apply yadif for interlaced sources
timing/mux:
--keep-vfr Preserve source timing (omit fps filter; per-frame delays)
--seek-accurate Put -ss/-t after -i for frame-accurate trimming
--loop INT GIF loop count (0=infinite, 1=once, ...)
presets:
--preset {social,tiny,hq}
Convenience starting points you can still override
size targeting:
--max-bytes INT Try to keep final GIF ≤ this many bytes
--min-fps INT Floor when shrinking FPS (default: 6)
--min-width INT Floor when shrinking width (default: 240)
--min-colors INT Floor when shrinking colors (default: 32)
Quality tips
- Tiny yet readable:
--fps 10 --width 360 --colors 64 - Keep text/UI sharp: prefer lowering colors before width
- Preserve pacing:
--keep-vfr(if viewers act weird, go back to fixed--fps) - Trim aggressively:
--start/--durationsave more bytes than any other knob
Troubleshooting
- “ffmpeg not found” → Install FFmpeg and ensure it’s on your PATH (
ffmpeg -version). - Starts a bit early → Use
--seek-accuratefor frame-accurate trims. - Choppy playback → Increase
--fps, or relax size floors so FPS doesn’t drop too low. - Persistent banding with low colors → Try a different
--dither(e.g.,floyd_steinberg).
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vid2gifx-0.1.1.tar.gz.
File metadata
- Download URL: vid2gifx-0.1.1.tar.gz
- Upload date:
- Size: 10.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a24b1ab2bc5c9aa9668fa30053d4465a702255859cbb93184f90b3975f39588
|
|
| MD5 |
dcd244c65a73d8d83ee3c9b6cfdee789
|
|
| BLAKE2b-256 |
7a3c80e8cfeeae60df8bb1c6e03d9f303ac7742093855b0e7f382b917eae7ecb
|
File details
Details for the file vid2gifx-0.1.1-py3-none-any.whl.
File metadata
- Download URL: vid2gifx-0.1.1-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb438e1f4f0ce3a27ab0abbce6e1db747328cc405c131b4121a787204032352d
|
|
| MD5 |
e5c42b01a7cda19d4ff7889dce04a9cc
|
|
| BLAKE2b-256 |
df94ec35a9e69cb2a4b91b2f22a19049587f66f8e596668184b553db579e1507
|