HLC Clipper โ render tools
Requirements: macOS + Homebrew + ffmpeg-full + Python 3 (Xcode CLT for the optional Swift matte tool) โ full walkthrough in SETUP.md.
The render engines from 19Keys' personal AI video-clipping studio: the Python/ffmpeg scripts that turn a raw talking-head video into styled vertical clips and quote cards, plus the Swift/Vision tool used for masked (person-cutout) color grading.
This is the tools/ layer of a larger private studio (dashboard, job server, deploy pipeline). What's here is everything you need to understand and reuse the actual render logic โ the ffmpeg filter chains, the ASS subtitle generation, the face-tracked auto-reframe, and the Vision-based person matte. What's not here (and why) is in "What's missing" below โ read it before you expect a one-command render.
What this actually does
Every script is a standalone CLI you can run directly against a source video. No server, no database, no queue.
tools/luxury_render.pyโ the signature "luxury" grade: filmic curves, soft bloom, vignette, fine grain, a thin gold frame, and a letter-spaced Didot caption. Two registers baked in ascinematic(rich, moody, A24-ish) andquiet(near- monochrome, extreme restraint). Applies one of three LUTs โcool/warm/naturalโ on top of the procedural grade. Can run masked (subject cut out from a separately-graded background) viapersonmatte.tools/personmatte.swiftโ Apple Vision (VNGeneratePersonSegmentationRequest) person-matte extractor. Streams a video in sequentially, reuses one segmentation request so the matte stays temporally stable, and writes raw grayscale matte frames to stdout for ffmpeg to composite. macOS + Vision only.tools/reframe.pyโ auto-reframe: OpenCV face tracking across a clip, returns the ffmpeg crop that keeps the speaker centered for a target aspect (9:16 by default). Falls back to a centered crop if no face is found โ a render never breaks because a face wasn't detected.tools/quote_cards.py,tools/quotecard_render.pyโ freeze-frame quote cards (1080x1350, IG 4:5) with burned-in quote text and a brand watermark.tools/style_render.py,tools/batch_cards.pyโ the repost/commentary card styles (conversation, quote, X-post/"xpost", editorial, culture) โ HTML template rendered transparent via Playwright, composited over the cut footage with ffmpeg.batch_cards.pyruns a ranked quote bank through this in one pass.tools/quote_reel_overlay.pyโ a transparent overlay PNG (rounded quote box + cursive signature) to lay over a 9:16 video for a quote-reel look.tools/screenplay_prep.pyโ formats a word-level transcript slice into the JSON a "screenplay scroll" motion composition consumes.tools/word_captions.pyโ karaoke / word-by-word ASS captions from a transcript, remapped onto the output timeline after cuts.tools/whisper_to_words.pyโ converts localwhisper-cliJSON output into the same word-timing format the rest of the pipeline expects (no API key needed).tools/motion_render.py,tools/hyperframes_render.pyโ drivers for two external motion-graphics engines (Remotion, HyperFrames) โ not vendored here, these scripts just shell out tonpx/bunxif you have them installed.tools/fonts.pyโ scans your local font folders, resolves each file's real font-family name (not the filename), classifies it, and writesfonts.jsonso render tools can offer your own type as presets.
AGENTS.md and CLAUDE.md are the original operating rules for this studio (session
harness, house render defaults, iron rules learned from real bugs). They reference
pieces of the full studio (dashboard/, ops/, atomizer/, a Mac Mini deployment)
that aren't part of this extract โ read them for the reasoning, not as instructions
you can execute here.
What's missing (read this before you run anything)
This is a scoped extract of tools/, not the whole studio. A few things won't work
out of the box:
tools/luts/{cool,warm,natural}.cubeโ the three LUT filesluxury_render.pyloads are not included. Bring your own.cubeLUTs at those paths, or strip the--gradestep and rely on the procedural curves alone.dashboard/styles/*.htmlโ the actual visual templates for the quote-card and repost-style tools (quote_cards.py,quotecard_render.py,style_render.py,batch_cards.py) live in the dashboard layer, which is out of scope for this repo. These scripts will run but fail to find their template HTML until you supply your own โ the Python here shows you the full render pipeline (ffmpeg composite, ASS captioning, Playwright screenshot) to build templates against.fonts.jsonโ checked in as a working example, but every path in it is absolute to the machine it was generated on (/Users/<user>/Library/Fonts/...). Regenerate it for your own machine withpython3 tools/fonts.py.tools/personmatte(the compiled binary) is intentionally not included โ compile it yourself (one command, see below).
Requirements
- macOS (Vision-based masking and
swiftcare Apple-only; everything else is portable Python/ffmpeg) ffmpeg-full, not the slim Homebrew formula โ subtitle burn-in needslibass, which the slim build doesn't ship.brew install ffmpeg-full(keg-only).- Python 3 with
opencv-python-headless(forreframe.py) andplaywright(for the card-style renderers, if you supply your own templates) - Node 22+ if you want the Remotion/HyperFrames motion-graphics drivers
- An ElevenLabs API key only if you use hosted transcription โ the local-whisper
path (
whisper_to_words.py) needs no key
Quickstart
# 1. ffmpeg-full (subtitle burn-in requires libass; the slim formula lacks it)
brew install ffmpeg-full
# 2. compile the Vision matte tool (macOS + Xcode CLT)
cd tools && swiftc -O -o personmatte personmatte.swift && cd ..
# 3. python deps for face-tracked reframing
python3 -m venv tools/reframe-venv
tools/reframe-venv/bin/pip install "opencv-python-headless<5" numpy
# 4. copy the env template and fill in a key if you're using hosted transcription
# (named env.example, not .env.example, so it doesn't get swept up by dotfile
# secret-scanners in CI โ same idea, just a plain filename)
cp env.example .env
# 5. run a grade directly against a source clip
/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg -version # confirm libass is present
python3 tools/luxury_render.py --video source.mp4 --start 12 --end 20 \
--title "YOUR CAPTION HERE" --out out.mp4
init.sh and setup.sh are the original studio's verification/bootstrap scripts โ
init.sh in particular checks for files outside this extract (dashboard/server.py,
atomizer/) and will fail as shipped. Treat both as reference for what a complete
setup checks, not as a script you can run unmodified against this repo. setup.sh
also references .env.example; this repo ships that same template as env.example
(see the quickstart) โ copy it to .env by hand rather than relying on setup.sh's
auto-copy step.
Making it your own
- Swap
GOLD,CREAM, and the Didot font reference inluxury_render.pyfor your own brand marks and palette. - Build your own
.cubeLUTs (DaVinci Resolve, or any grading tool that exports 3D LUTs) and pointGRADESinluxury_render.pyat them. - Write your own
dashboard/styles/*.htmltemplates forstyle_render.py/quote_cards.pyโ they're plain HTML/CSS rendered headless via Playwright, so any web design skill transfers directly. - Run
tools/fonts.pyagainst your own font folders to build afonts.jsonthat reflects your own type library instead of the shipped example.
License / attribution
This is 19Keys' own tooling, shared with the community to build from. The two
external engines referenced (video-use, hyperframes) are separate open-source
projects โ see setup.sh for their upstream repos and install their own licenses
before vendoring them.