Skip to main content

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.

  1. Social-ready (smaller, crisp)
vi2gifx in.mp4 out.gif --preset social

fps=12, width=480 — great balance of size & clarity.

  1. Tiny footprint (docs, PRs, chats)
vi2gifx in.mp4 out.gif --preset tiny

fps=8, width=360, colors=64 — aggressively small.

  1. High-quality demo
vi2gifx in.mp4 out.gif --preset hq

Higher FPS/width; larger files.

  1. Cap width (keep aspect)
vi2gifx in.mp4 out.gif --width 480
  1. Fixed dimensions (may change aspect)
vi2gifx in.mp4 out.gif --width 640 --height 360
  1. Lower FPS for size
vi2gifx in.mp4 out.gif --fps 10
  1. Limit colors for size
vi2gifx in.mp4 out.gif --colors 96
  1. Change dithering style
vi2gifx in.mp4 out.gif --dither floyd_steinberg
  1. Trim a segment
vi2gifx in.mp4 out.gif --start 3.2 --duration 6.5
  1. Frame-accurate trimming (avoid keyframe snap)
vi2gifx in.mp4 out.gif --start 3.2 --duration 6.5 --seek-accurate
  1. Preserve original timing (VFR)
vi2gifx in.mp4 out.gif --keep-vfr

Skips the fps filter; uses per-frame delays.

  1. Crop before scaling
vi2gifx in.mp4 out.gif --crop 480:480:100:60 --width 480
  1. Deinterlace first
vi2gifx in.mp4 out.gif --deinterlace
  1. Control loop count
vi2gifx in.mp4 out.gif --loop 0   # infinite (default)
vi2gifx in.mp4 out.gif --loop 1   # play once
  1. 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).

  1. Size cap with quality floors
vi2gifx in.mp4 out.gif --max-bytes 3_000_000 --min-colors 48 --min-fps 8 --min-width 320
  1. 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 / --duration save 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-accurate for 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)

Source distribution for vid2gifx 0.1.1
File Size Uploaded Provenance
vid2gifx-0.1.1.tar.gz 10.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for vid2gifx 0.1.1
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page