Media2Gif is a command-line tool that walks through a movie file, finds every quote in the subtitles, and exports a GIF for each one — sized to fit Giphy with the line burned in. Run it once and you have hundreds of upload-ready clips, every filename already encoding the movie, timestamp, and quote.
Every quote from these films has been processed end-to-end and uploaded to the Media2Gif Giphy channel. More on the way.
Every card is a generated GIF — quote burned in, file under 4 MB, name pre-tagged. Filter by film. Drop your own corpus in and the wall keeps growing.
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0s
Heat · 19955.0sFilenames are the upload form. Each GIF saves as Heat-Start[00-12-04]-End[00-12-08]-Quote[dontletyourselfgetattached].gif, so the title, timestamp, and quote populate themselves on upload.
The script reads your subtitle track, walks the timeline at your interval, and re-encodes each clip in a tightening loop until it lands inside your size budget.
ffprobe inspects the source. External SRT or embedded track, your call. HDR sources can be flattened with --noHDR.
Step through at --interval seconds. If the slice contains a quote, expand to the full line. Otherwise capture a 5-second clip.
Subtitle gets typeset to your color, size, stroke, and padding. ALL CAPS or italic if you want. Cropped-safe by design.
Iterative re-encode: tweak palette, framerate, and scale until the file lands as close to --maxFilesize as possible.
Filename encodes movie, start, end, and sanitized quote. Sidecar JSON optional. Auto-bucketing into batch_NNN folders.
Subtitle styling, size targeting, batch organization, randomization, and HDR handling all live behind clearly-named flags. Sensible defaults — opinionated where it matters.
| Flag | Default | What it does |
|---|---|---|
| --movie<PATH> | — | Path to the movie file |
| --subtitles<PATH> | — | External .srt subtitle file (optional — embedded tracks auto-detected) |
| --outputFolder<DIR> | — | Where the GIFs land. Relative paths sit next to the movie. |
| --interval<SEC> | 5 | Seconds between non-quote GIFs |
| --startTime<hh:mm:ss> | 00:00:00 | When to start scanning |
| --maxFilesize<SIZE> | — | Target size, e.g. 15mb. Script downsamples until it fits. |
| --quotes<BOOL> | true | Include subtitle quotes burned into GIFs |
| --randomQuote | — | Pick a random quote (or random time if --quotes false) |
| --randomTimes | — | Generate from random start times rather than walking the film |
| --subtitleColor<COLOR> | white | Subtitle text color |
| --subtitleSize<PX> | 16 | Subtitle font size |
| --textBorder<PX> | 2 | Black stroke width around text |
| --textPadding<PX> | 5 | Margin so text never crops |
| --bottomPadding<PX> | — | Distance from bottom of frame |
| --uppercase | — | Force ALL CAPS subtitles |
| --italicize | false | Italicize subtitle text |
| --trailingPeriod<BOOL> | true | Keep trailing periods in quotes |
| --noHDR | — | Convert HDR source to SDR before encoding |
| --boostColors<PCT> | — | Boost saturation/contrast on the whole GIF |
| --boostFrameColors<PCT> | — | Boost colors per-frame before assembly |
| --saveJson | — | Write a sidecar JSON with quote, start, end, filename |
| --outputBatchFolderSize<N> | — | Auto-bucket into batch_001, batch_002… every N gifs |
| --listSubtitleTracks | — | Print embedded subtitle tracks and exit |
| --subtitleTrack<INDEX> | — | Pick which embedded track to burn in |
| --debug | — | Save every iteration of the size-optimization loop |
ffmpeg does the encoding. Python orchestrates. Clone, install, point it at a movie.
# install Homebrew, then: brew install ffmpeg
git clone https://github.com/MartinBarker/Media2Gif cd Media2Gif python3 -m venv venv source venv/bin/activate pip install -r requirements.txt
python make_gifs.py \ --movie "movie.mkv" \ --outputFolder gifs \ --maxFilesize "15mb" \ --uppercase \ --saveJson