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
Metadata
Release files for vid2gifx 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| vid2gifx-0.1.1.tar.gz | 10.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vid2gifx-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.2 kB
Release files / vid2gifx-0.1.1.tar.gz
| Download URL | vid2gifx-0.1.1.tar.gz |
|---|---|
| Size | 10.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0a24b1ab2bc5c9aa9668fa30053d4465a702255859cbb93184f90b3975f39588
|
|
BLAKE2b-256 checksum How to use checksums |
7a3c80e8cfeeae60df8bb1c6e03d9f303ac7742093855b0e7f382b917eae7ecb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.0
|
Release files / vid2gifx-0.1.1-py3-none-any.whl
| Download URL | vid2gifx-0.1.1-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
eb438e1f4f0ce3a27ab0abbce6e1db747328cc405c131b4121a787204032352d
|
|
BLAKE2b-256 checksum How to use checksums |
df94ec35a9e69cb2a4b91b2f22a19049587f66f8e596668184b553db579e1507
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.0
|
Security for vid2gifx 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.