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
.assstyling. --styledinstead renders the real styling via ffmpeg's libasssubtitlesfilter — but that needs an ffmpeg built with libass (the stock Homebrewffmpegis not;brew install homebrew-ffmpeg/ffmpeg/ffmpegis, though it builds from source). For plain.srt(which carries no styling) the two look identical, so--styledonly matters for styled.ass/.ssasubtitles.- Assumes exactly one video and one subtitle file per directory; if there are
several it stops and asks you to pass
--video/--subs.
Metadata
Release files for screencap 0.1.0
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 | Actions |
|---|---|---|---|---|
| screencap-0.1.0.tar.gz | 10.9 kB | Without provenance | Details for screencap-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| screencap-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for screencap-0.1.0-py3-none-any.whl |
Total release size: 22.8 kB
Release files / screencap-0.1.0.tar.gz
| Download URL | screencap-0.1.0.tar.gz |
|---|---|
| Size | 10.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
39bdf884c4d47c774a19356791ec9555b9ccaaa4dc57c21c39fd8ce2481d7d8a
|
|
BLAKE2b-256 checksum How to use checksums |
348a75889c95fbbba4abbea915ed7716d48e60528ad2bbe72c2a337875b9d56b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.25
|
Release files / screencap-0.1.0-py3-none-any.whl
| Download URL | screencap-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e35bf5bbf4a8109b08cab29bd58314273aa947e3b096ec8186cf15bcf493d7da
|
|
BLAKE2b-256 checksum How to use checksums |
0e41bbf3f8a670bfd9cb13bf7d84723b47a85cf46b329d718505c186a6fa46cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.25
|
Security for screencap 0.1.0
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.