video-ingest
Turn a video or audio recording — a local file OR a URL (YouTube, TikTok, Instagram, ...) — into vault knowledge using the crv (claude-real-video) CLI. Scene-aware keyframes + a Whisper transcript, fr
SKILL.md.claude/skills/video-ingest/SKILL.md
GitHubVideo Ingest (crv → frames ⇄ transcript → LLM Wiki)
Actually watch a recording: crv extracts deduplicated keyframes + a Whisper
transcript; you then correlate what's SHOWN with what's SAID, and ingest it the
vault's way — full capture in Raw/Sources/, reusable knowledge compiled into
Wiki/, key screenshots in assets/. Follow AGENTS.md and the
llm-wiki-ingest skill for the compile step.
Environment
crvis theclaude-real-videopip package (CLI:crv). Checkcrv --help; install withpip install claude-real-videoif missing.ffmpeg/ffprobemust be reachable. If not on PATH (common on Windows), prepend for the run, e.g.$env:PATH = "C:\ffmpeg\bin;" + $env:PATH.- On Windows PowerShell set
$env:PYTHONUTF8=1in the same command (avoids a cosmetic Unicode crash on the final print; output still lands). - Whisper on CPU is slow (~0.5–1× real-time). Run crv in the background and wait for completion; don't poll.
Step 0 — Pick the right input
- URL? crv takes URLs directly (YouTube, TikTok, Instagram, ...):
crv "https://youtube.com/watch?v=..." -o <OUTDIR> .... For login-gated sites,--cookies <netscape-file>or--cookies-from-browser <browser>(the user's own account, authorized use only). - Audio-only file (.wav/.mp3)? No frames → no "what's shown". Screen
recorders (OBS) often save a big
.mkv/.mp4and a small.wavsibling — prefer the video. Confirm streams with:ffprobe -v error -show_entries stream=codec_type,codec_name:format=duration <file>.
Step 1 — Extract (background)
$env:PYTHONUTF8=1
crv "<VIDEO-OR-URL>" -o "<SCRATCH-OUTDIR>" --lang en --whisper-model small `
--adaptive --text-anchors --viewer --max-frames 200 `
--why "Full examination for the vault: capture everything said and shown."
Use a scratch <OUTDIR> outside the vault. Produces transcript.txt, frames/
(frame_001.jpg… chronological), MANIFEST.txt, viewer.html. Frame selection
is visual only (scene change + dedup + a time floor): crv guarantees
coverage of distinct screens, not importance. Importance is judged next — by
you, using the transcript.
Step 2 — Watch it: correlate frames ⇄ transcript
This is the step that makes the ingest worth anything.
- Read
transcript.txtin full. It has no timestamps and no speaker labels; Whisper often hallucinates on trailing silence — drop the nonsense tail. (Known quirk: domain terms get misheard consistently; when a word looks wrong everywhere, flag it as an open question instead of propagating it.) - Read the frames in order. Don't read all N blindly: do a strided overview pass (every ~8th frame) to map the arc of the recording, then read densely through the sections that matter (code, terminals, UIs, slides, whiteboards, diagrams).
- Align said ⇄ shown by chronological position: frames and transcript both run start→end, so a frame ~40% through the frame list pairs with text ~40% through the transcript. Anchor pairs at unmistakable moments (a screen change that matches a topic change) and interpolate between anchors. Record the pairing explicitly in the Walkthrough ("What's said / What's shown").
- Redact secrets. Recordings of dev work routinely expose tokens, keys, account IDs, URLs with credentials, passwords. Never transcribe secret values and never copy a frame that shows one into the vault. Transcribe other on-screen text/code verbatim where legible.
Step 3 — Ingest the vault's way
- Raw source →
Raw/Sources/<date>-<slug>-recording.mdwith source frontmatter (Title,Author,Reference= the URL or filename,ContentType,Created,Processed: false,tags: [source]). Body: a provenance note (crv flags, whisper model, frame count, redactions, transcript quality), a Summary, a chronological Walkthrough (What's said / What's shown pairs), the embedded screenshots, a Key topics list of[[wikilinks]], and the full transcript appended at the end for searchability. - Screenshots → copy only the important, secret-free frames into
assets/with descriptive names; embed with![[name.jpg]]. Do not dump all frames or the source video into the vault (Raw/Files/is gitignored;assets/is committed). - Compile → search first
(
python scripts/wiki_tool.py search-catalog --query "…"), then create or enrich focusedWiki/notes, each linked back to the Raw source insourceswith an accuratesource_count. Prefer enriching existing notes over duplicating. Capture ambiguity as Open Questions; never invent.
Step 4 — Gate + commit
python scripts/wiki_tool.py build
python scripts/wiki_tool.py lint
python scripts/wiki_tool.py source-scan --update --accept-covered
python scripts/wiki_tool.py source-lint
python scripts/audit_public.py
Commit the Raw source, assets/ screenshots, compiled notes, and regenerated
artifacts together. Add a log note for substantial ingests.
Notes
- Reference-video mode (a TikTok/YouTube the user wants studied, not archived): same Steps 0–2, then answer their question directly; only ingest to the vault if they want it kept.
- Optional crv flags:
--grid(contact sheets),--keep-audio,--report,--scene 0.2(more frames),--whisper-model medium(better transcript). - Big videos stay outside the vault; reference them by URL/filename in the Raw
source's
Reference.