Skip to main content

screencap

Fuzzy-find a subtitle line and grab the sharpest frame for it, with the subtitle burned in.

Point it at a directory holding one video and one subtitle file. A fzf typeahead opens; fuzzy-match the line you want; screencap finds the least-blurry frame within that line's time window, draws the subtitle onto it, and writes a PNG next to the source.

screencap ~/Movies/some-film

Why it's not blurry

Within the matched subtitle's time window it samples every frame, scores each by variance of the Laplacian (a standard focus metric — higher = sharper), and picks the sharpest one. So you get a crisp frame instead of whatever happened to be under the playhead.

Usage

screencap [DIR]                 # interactive fzf picker (default DIR: .)
screencap DIR --query "text"    # non-interactive: best-matching line
screencap DIR --index 42        # non-interactive: the Nth cue (1-based)

Options:
  --clip           make a short mp4 clip (audio + burned-in captions)
  --to N           clip mode: end cue index (1-based); default = start cue
  --to-query TEXT  clip mode: end cue by best text match
  --video PATH     explicit video file (skip auto-discovery)
  --subs PATH      explicit subtitle file (skip auto-discovery)
  --pad SECONDS    lead-in/out (clip) or search-window widening (default 0.15)
  --no-subs        don't burn the subtitle in
  --styled         screenshot only: authentic styling via ffmpeg's libass
                   filter (needs a libass-enabled ffmpeg; see below)
  --font PATH      .ttf/.ttc for the Pillow caption (default: Arial/Helvetica)
  -o, --out PATH   output file (default: <timestamp>_<slug>.png/.mp4 in DIR)
  -v, --verbose    show what it's doing

In the picker: type to fuzzy-match, arrow keys to move (the preview pane shows surrounding lines + the timecode), Enter to grab the frame.

Clips

--clip produces a short .mp4 (h264 + aac) with the audio and the subtitles burned in — the captions change over the clip, each line appearing for its own window:

screencap DIR --clip                                   # Tab-mark first & last line, Enter
screencap DIR --clip --query "you dig a"                # single-line clip
screencap DIR --clip --query "you dig a" --to-query "but you dig 12"   # a span

Interactively, Tab-mark the first and last line of the exchange (or just one line for a single-line clip), then Enter. Every subtitle line inside the span is burned in, and --pad adds a little lead-in/out. Captions are composited with ffmpeg's overlay filter, so clips work on any ffmpeg — no libass required.

Requirements

  • uv — runs the script and manages its Python deps (Pillow, numpy) automatically via the inline script header.
  • ffmpeg / ffprobe — frame extraction. No libass/freetype build required: the caption is drawn in Python, so any ffmpeg works.
  • fzf — the fuzzy picker (only for interactive mode).

Supported subtitles: .srt, .vtt, .ass/.ssa.

Install

uvx --from git+https://github.com/omarish/screencap screencap

Needs uv, plus ffmpeg / ffprobe and fzf (interactive mode only).

To put it on your PATH:

uv tool install git+https://github.com/omarish/screencap

Notes / limitations

  • By default the caption is drawn by Pillow: a clean centered white-with-black-outline caption, using the exact text of the matched line (no subtitle-timing guesswork). It does not reproduce .ass styling.
  • --styled instead renders the real styling via ffmpeg's libass subtitles filter — but that needs an ffmpeg built with libass (the stock Homebrew ffmpeg is not; brew install homebrew-ffmpeg/ffmpeg/ffmpeg is, though it builds from source). For plain .srt (which carries no styling) the two look identical, so --styled only matters for styled .ass/.ssa subtitles.
  • Assumes exactly one video and one subtitle file per directory; if there are several it stops and asks you to pass --video / --subs.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

screencap-0.1.0.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

screencap-0.1.0-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

Details for the file screencap-0.1.0.tar.gz.

File metadata

  • Download URL: screencap-0.1.0.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.25

File hashes

Hashes for screencap-0.1.0.tar.gz
Algorithm Hash digest
SHA256 39bdf884c4d47c774a19356791ec9555b9ccaaa4dc57c21c39fd8ce2481d7d8a
MD5 c36362a9bd470657738ae7ee5e5e1a31
BLAKE2b-256 348a75889c95fbbba4abbea915ed7716d48e60528ad2bbe72c2a337875b9d56b

See more details on using hashes here.

File details

Details for the file screencap-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: screencap-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.25

File hashes

Hashes for screencap-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e35bf5bbf4a8109b08cab29bd58314273aa947e3b096ec8186cf15bcf493d7da
MD5 bf176c06b1557c30fbdffa10c63e0d24
BLAKE2b-256 0e41bbf3f8a670bfd9cb13bf7d84723b47a85cf46b329d718505c186a6fa46cd

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

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