| Name | vid2gifx JSON |
| Version |
0.1.1
JSON |
| download |
| home_page | None |
| Summary | FFmpeg-only video to GIF converter with palettegen/paletteuse and size targeting. |
| upload_time | 2025-10-10 14:26:42 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.8 |
| license | MIT |
| keywords |
ffmpeg
gif
video
conversion
palettegen
paletteuse
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# 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)
```bash
# 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
```bash
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)**
```bash
vi2gifx in.mp4 out.gif --preset social
```
`fps=12`, `width=480` — great balance of size & clarity.
2. **Tiny footprint (docs, PRs, chats)**
```bash
vi2gifx in.mp4 out.gif --preset tiny
```
`fps=8`, `width=360`, `colors=64` — aggressively small.
3. **High-quality demo**
```bash
vi2gifx in.mp4 out.gif --preset hq
```
Higher FPS/width; larger files.
4. **Cap width (keep aspect)**
```bash
vi2gifx in.mp4 out.gif --width 480
```
5. **Fixed dimensions (may change aspect)**
```bash
vi2gifx in.mp4 out.gif --width 640 --height 360
```
6. **Lower FPS for size**
```bash
vi2gifx in.mp4 out.gif --fps 10
```
7. **Limit colors for size**
```bash
vi2gifx in.mp4 out.gif --colors 96
```
8. **Change dithering style**
```bash
vi2gifx in.mp4 out.gif --dither floyd_steinberg
```
9. **Trim a segment**
```bash
vi2gifx in.mp4 out.gif --start 3.2 --duration 6.5
```
10. **Frame-accurate trimming (avoid keyframe snap)**
```bash
vi2gifx in.mp4 out.gif --start 3.2 --duration 6.5 --seek-accurate
```
11. **Preserve original timing (VFR)**
```bash
vi2gifx in.mp4 out.gif --keep-vfr
```
Skips the `fps` filter; uses per-frame delays.
12. **Crop before scaling**
```bash
vi2gifx in.mp4 out.gif --crop 480:480:100:60 --width 480
```
13. **Deinterlace first**
```bash
vi2gifx in.mp4 out.gif --deinterlace
```
14. **Control loop count**
```bash
vi2gifx in.mp4 out.gif --loop 0 # infinite (default)
vi2gifx in.mp4 out.gif --loop 1 # play once
```
15. **Hard cap the final size (size targeting)**
```bash
vi2gifx in.mp4 out.gif --max-bytes 4_000_000
```
Iteratively shrinks **colors → fps → width** until ≤ 4 MB (respects floors).
16. **Size cap with quality floors**
```bash
vi2gifx in.mp4 out.gif --max-bytes 3_000_000 --min-colors 48 --min-fps 8 --min-width 320
```
17. **Motion-first preference**
```bash
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
```text
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
Raw data
{
"_id": null,
"home_page": null,
"name": "vid2gifx",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "ffmpeg, gif, video, conversion, palettegen, paletteuse",
"author": null,
"author_email": "thecoderider <thecoderider42@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/7a/3c/80e8cfeeae60df8bb1c6e03d9f303ac7742093855b0e7f382b917eae7ecb/vid2gifx-0.1.1.tar.gz",
"platform": null,
"description": "# vi2gifx \u2014 FFmpeg-only video \u2192 GIF converter\r\n\r\nA clean, configurable Python CLI that converts and optimizes videos to GIFs using FFmpeg\u2019s **palettegen \u2192 paletteuse** workflow.\r\nIncludes optional **size targeting** (stay under a byte budget), **frame-accurate seek**, and **VFR preservation**.\r\n\r\n---\r\n\r\n## Installation (from PyPI)\r\n\r\n```bash\r\n# 1) Have FFmpeg installed and on your PATH\r\n# macOS: brew install ffmpeg\r\n# Ubuntu: sudo apt-get install ffmpeg\r\n# Windows: winget install ffmpeg (or download from gyan.dev)\r\n# Verify: ffmpeg -version\r\n\r\n# 2) Install the CLI\r\npip install vi2gifx\r\n```\r\n\r\n> After install you\u2019ll have a shell command named **`vi2gifx`**.\r\n\r\n---\r\n\r\n## Quick start\r\n\r\n```bash\r\nvi2gifx input.mp4 output.gif\r\n```\r\n\r\nConverts the whole video using a good default FPS and an adaptive palette for quality colors.\r\n\r\n---\r\n\r\n## Common recipes (copy-paste friendly)\r\n\r\n> Each example includes what it does.\r\n\r\n1. **Social-ready (smaller, crisp)**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --preset social\r\n```\r\n\r\n`fps=12`, `width=480` \u2014 great balance of size & clarity.\r\n\r\n2. **Tiny footprint (docs, PRs, chats)**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --preset tiny\r\n```\r\n\r\n`fps=8`, `width=360`, `colors=64` \u2014 aggressively small.\r\n\r\n3. **High-quality demo**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --preset hq\r\n```\r\n\r\nHigher FPS/width; larger files.\r\n\r\n4. **Cap width (keep aspect)**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --width 480\r\n```\r\n\r\n5. **Fixed dimensions (may change aspect)**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --width 640 --height 360\r\n```\r\n\r\n6. **Lower FPS for size**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --fps 10\r\n```\r\n\r\n7. **Limit colors for size**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --colors 96\r\n```\r\n\r\n8. **Change dithering style**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --dither floyd_steinberg\r\n```\r\n\r\n9. **Trim a segment**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --start 3.2 --duration 6.5\r\n```\r\n\r\n10. **Frame-accurate trimming (avoid keyframe snap)**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --start 3.2 --duration 6.5 --seek-accurate\r\n```\r\n\r\n11. **Preserve original timing (VFR)**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --keep-vfr\r\n```\r\n\r\nSkips the `fps` filter; uses per-frame delays.\r\n\r\n12. **Crop before scaling**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --crop 480:480:100:60 --width 480\r\n```\r\n\r\n13. **Deinterlace first**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --deinterlace\r\n```\r\n\r\n14. **Control loop count**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --loop 0 # infinite (default)\r\nvi2gifx in.mp4 out.gif --loop 1 # play once\r\n```\r\n\r\n15. **Hard cap the final size (size targeting)**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --max-bytes 4_000_000\r\n```\r\n\r\nIteratively shrinks **colors \u2192 fps \u2192 width** until \u2264 4 MB (respects floors).\r\n\r\n16. **Size cap with quality floors**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --max-bytes 3_000_000 --min-colors 48 --min-fps 8 --min-width 320\r\n```\r\n\r\n17. **Motion-first preference**\r\n\r\n```bash\r\nvi2gifx in.mp4 out.gif --max-bytes 4_000_000 --min-fps 12\r\n```\r\n\r\nKeeps FPS higher; reduces colors/width instead.\r\n\r\n---\r\n\r\n## How size targeting works (brief)\r\n\r\nWhen you pass `--max-bytes`, **vi2gifx** performs first-fit trials that reduce **colors \u2192 fps \u2192 width** along gentle ladders (e.g., colors 256\u2192128\u219296\u219264, fps 12\u2192\u2026\u21926, width 720\u2192\u2026\u2192min) 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\u2019s over budget. Steer trade-offs with `--min-colors`, `--min-fps`, `--min-width`.\r\n\r\n---\r\n\r\n## CLI reference\r\n\r\n```text\r\nusage: vi2gifx INPUT OUTPUT [options]\r\n\r\npositional arguments:\r\n INPUT Input video file\r\n OUTPUT Output GIF path (e.g., out.gif)\r\n\r\ncore quality/size:\r\n --fps INT Frames per second (default 12 unless --keep-vfr)\r\n --width INT Scale to this width (keeps aspect unless height also set)\r\n --height INT Scale to this height (keeps aspect unless width also set)\r\n --colors INT Palette colors (2\u2013256). Fewer = smaller\r\n\r\nadvanced tuning:\r\n --dither {none,bayer,floyd_steinberg,sierra2,sierra2_4a}\r\n Dither algorithm (default: sierra2_4a)\r\n --stats-mode {full,diff}\r\n palettegen statistics mode (default: full)\r\n\r\ntrim/crop/deinterlace:\r\n --start FLOAT Start time in seconds\r\n --duration FLOAT Duration in seconds\r\n --crop W:H:X:Y Crop region before scaling\r\n --deinterlace Apply yadif for interlaced sources\r\n\r\ntiming/mux:\r\n --keep-vfr Preserve source timing (omit fps filter; per-frame delays)\r\n --seek-accurate Put -ss/-t after -i for frame-accurate trimming\r\n --loop INT GIF loop count (0=infinite, 1=once, ...)\r\n\r\npresets:\r\n --preset {social,tiny,hq}\r\n Convenience starting points you can still override\r\n\r\nsize targeting:\r\n --max-bytes INT Try to keep final GIF \u2264 this many bytes\r\n --min-fps INT Floor when shrinking FPS (default: 6)\r\n --min-width INT Floor when shrinking width (default: 240)\r\n --min-colors INT Floor when shrinking colors (default: 32)\r\n```\r\n\r\n---\r\n\r\n## Quality tips\r\n\r\n* Tiny yet readable: `--fps 10 --width 360 --colors 64`\r\n* Keep text/UI sharp: prefer lowering **colors** before **width**\r\n* Preserve pacing: `--keep-vfr` (if viewers act weird, go back to fixed `--fps`)\r\n* Trim aggressively: `--start` / `--duration` save more bytes than any other knob\r\n\r\n---\r\n\r\n## Troubleshooting\r\n\r\n* **\u201cffmpeg not found\u201d** \u2192 Install FFmpeg and ensure it\u2019s on your PATH (`ffmpeg -version`).\r\n* **Starts a bit early** \u2192 Use `--seek-accurate` for frame-accurate trims.\r\n* **Choppy playback** \u2192 Increase `--fps`, or relax size floors so FPS doesn\u2019t drop too low.\r\n* **Persistent banding with low colors** \u2192 Try a different `--dither` (e.g., `floyd_steinberg`).\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "FFmpeg-only video to GIF converter with palettegen/paletteuse and size targeting.",
"version": "0.1.1",
"project_urls": {
"Homepage": "https://github.com/the-code-rider/vid2gif",
"Issues": "https://github.com/the-code-rider/video2gif/issues"
},
"split_keywords": [
"ffmpeg",
" gif",
" video",
" conversion",
" palettegen",
" paletteuse"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "df94ec35a9e69cb2a4b91b2f22a19049587f66f8e596668184b553db579e1507",
"md5": "e5c42b01a7cda19d4ff7889dce04a9cc",
"sha256": "eb438e1f4f0ce3a27ab0abbce6e1db747328cc405c131b4121a787204032352d"
},
"downloads": -1,
"filename": "vid2gifx-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e5c42b01a7cda19d4ff7889dce04a9cc",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 8625,
"upload_time": "2025-10-10T14:26:41",
"upload_time_iso_8601": "2025-10-10T14:26:41.119077Z",
"url": "https://files.pythonhosted.org/packages/df/94/ec35a9e69cb2a4b91b2f22a19049587f66f8e596668184b553db579e1507/vid2gifx-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7a3c80e8cfeeae60df8bb1c6e03d9f303ac7742093855b0e7f382b917eae7ecb",
"md5": "dcd244c65a73d8d83ee3c9b6cfdee789",
"sha256": "0a24b1ab2bc5c9aa9668fa30053d4465a702255859cbb93184f90b3975f39588"
},
"downloads": -1,
"filename": "vid2gifx-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "dcd244c65a73d8d83ee3c9b6cfdee789",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 10610,
"upload_time": "2025-10-10T14:26:42",
"upload_time_iso_8601": "2025-10-10T14:26:42.032643Z",
"url": "https://files.pythonhosted.org/packages/7a/3c/80e8cfeeae60df8bb1c6e03d9f303ac7742093855b0e7f382b917eae7ecb/vid2gifx-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-10 14:26:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "the-code-rider",
"github_project": "vid2gif",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "vid2gifx"
}