Turn a YouTube URL or local video into one digest.md — the full
timestamped transcript with every real on-screen visual (slide, screenshot, UI,
diagram, whiteboard) captured inline: OCR'd, described, de-duplicated, with
talking-head/filler frames filtered out.
Runs fully local against any OpenAI-compatible vision endpoint — no cloud keys. Fits a 16 GB GPU (or runs on CPU with ~24 GB RAM).
Example: an excerpt of the digest for a coding video (rendered):
[10:45] and also just to verify like it can [10:46] actually do the upload second I wanted
On-screen text: Arduino Board Setup /home/ladyada/Arduino/libraries/Adafruit_TestBed/examples/I2C_Scan … Now let's compile and upload the I2C_Scan example …
A terminal window displaying Arduino CLI commands for compiling, uploading, and checking serial output for an I2C_Scan example, with a Bash command prompt at the bottom asking for user input.
Frame from “Fully automating Arduino development” by Adafruit Industries, licensed CC BY.
ffmpegandyt-dlpon PATH.- A local vision model on an OpenAI-compatible endpoint. Easiest is
LM Studio: install → search & download
minicpm-v-45(a ~6 GB vision model) → Developer → Start Server. That's the whole backend. (Ollama orllama.cpp'sllama-serverwork too — anything that serves/v1/chat/completionswith a vision model.)
# 1. get the skill (until it's on a plugin marketplace)
git clone https://github.com/ollo12-prog/video-digest ~/video-digest
ln -s ~/video-digest ~/.claude/skills/video-digest # or copy the folder there
# 2. one-time preflight — checks ffmpeg, yt-dlp, and your endpoint
python3 ~/video-digest/scripts/setup.pysetup.py prints the exact fix for anything missing and lists the model ids your
endpoint serves (set CLASSIFY_MODEL / DESCRIBE_MODEL if yours differ from the
minicpm-v-45-q4-32k-vision default).
In Claude Code (or any skill host):
/video-digest https://www.youtube.com/watch?v=…
Or directly:
python3 scripts/digest.py "https://www.youtube.com/watch?v=…" out/
# → out/digest.md
# just the transcript: captions only, no video download, no vision model needed
python3 scripts/digest.py "https://youtu.be/…" out/ --transcript-only
# only part of a video
python3 scripts/digest.py "https://youtu.be/…" out/ --start 12:30 --end 18:00Config (all optional, sensible defaults) is env-based — VLM_ENDPOINT,
CLASSIFY_MODEL, DESCRIBE_MODEL, VD_RES; see SKILL.md.
- Captions first, Whisper only as fallback. Most YouTube has captions (free, timestamped); caption-less videos use local whisper.cpp (optional, see notes).
- Interval keyframes, not scene cuts. It samples on a time grid and keeps a frame when it's visually new and persists — so it captures gradual change (a whiteboard drawn over 15 minutes) that scene-cut detection misses entirely, while dropping transient flickers and re-shows.
- One small vision model does both jobs (keep/drop + OCR/describe), so it fits
16 GB and never swaps.
minicpm-v-45was picked because it's the only model tested that reliably separates verbatim OCR from a summary on dense terminal/code frames (larger models garbled or hallucinated there). - Talking-head filler is filtered — a presenter on camera is not a "visual."
Caption-less videos fall back to local whisper.cpp; see docs/WHISPER.md.
Inspired by bradautomates/claude-video
(the /watch skill) — its clean skill packaging and "captions-first, Whisper-
fallback" approach shaped this project. This tool goes a different direction on the
video track: local vision-model OCR/description of de-duplicated keyframes instead
of raw frame sampling.
MIT — see LICENSE.
