Video 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
crv is the claude-real-video pip package (CLI: crv). Check crv --help;
install with pip install claude-real-video if missing.
ffmpeg/ffprobe must 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=1 in 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/.mp4 and a small .wav
sibling — 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.txt in 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.md with 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 focused Wiki/ notes, each linked back to the Raw source in sources
with an accurate source_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.
1---2name: video-ingest3description: 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, frames correlated to what's being said, compiled into Raw source + Wiki notes with screenshots. Use when the user points at a recording, a meeting, a screen capture, or a reference video and wants it watched, transcribed, analyzed, or added to the vault.4---56# Video Ingest (crv → frames ⇄ transcript → LLM Wiki)78Actually *watch* a recording: `crv` extracts deduplicated keyframes + a Whisper9transcript; you then correlate what's SHOWN with what's SAID, and ingest it the10vault's way — full capture in `Raw/Sources/`, reusable knowledge compiled into11`Wiki/`, key screenshots in `assets/`. Follow `AGENTS.md` and the12`llm-wiki-ingest` skill for the compile step.1314## Environment1516- `crv` is the `claude-real-video` pip package (CLI: `crv`). Check `crv --help`;17 install with `pip install claude-real-video` if missing.18- `ffmpeg`/`ffprobe` must be reachable. If not on PATH (common on Windows),19 prepend for the run, e.g. `$env:PATH = "C:\ffmpeg\bin;" + $env:PATH`.20- On Windows PowerShell set `$env:PYTHONUTF8=1` in the same command (avoids a21 cosmetic Unicode crash on the final print; output still lands).22- Whisper on CPU is slow (~0.5–1× real-time). **Run crv in the background** and23 wait for completion; don't poll.2425## Step 0 — Pick the right input2627- **URL?** crv takes URLs directly (YouTube, TikTok, Instagram, ...):28 `crv "https://youtube.com/watch?v=..." -o <OUTDIR> ...`. For login-gated29 sites, `--cookies <netscape-file>` or `--cookies-from-browser <browser>`30 (the user's own account, authorized use only).31- **Audio-only file (.wav/.mp3)?** No frames → no "what's shown". Screen32 recorders (OBS) often save a big `.mkv`/`.mp4` **and** a small `.wav`33 sibling — prefer the video. Confirm streams with:34 `ffprobe -v error -show_entries stream=codec_type,codec_name:format=duration <file>`.3536## Step 1 — Extract (background)3738```powershell39$env:PYTHONUTF8=140crv "<VIDEO-OR-URL>" -o "<SCRATCH-OUTDIR>" --lang en --whisper-model small `41 --adaptive --text-anchors --viewer --max-frames 200 `42 --why "Full examination for the vault: capture everything said and shown."43```4445Use a scratch `<OUTDIR>` outside the vault. Produces `transcript.txt`, `frames/`46(`frame_001.jpg`… chronological), `MANIFEST.txt`, `viewer.html`. Frame selection47is **visual only** (scene change + dedup + a time floor): crv guarantees48*coverage of distinct screens*, not importance. Importance is judged next — by49you, using the transcript.5051## Step 2 — Watch it: correlate frames ⇄ transcript5253This is the step that makes the ingest worth anything.54551. Read `transcript.txt` in full. It has **no timestamps and no speaker56 labels**; Whisper often **hallucinates on trailing silence** — drop the57 nonsense tail. (Known quirk: domain terms get misheard consistently; when a58 word looks wrong everywhere, flag it as an open question instead of59 propagating it.)602. Read the frames **in order**. Don't read all N blindly: do a **strided61 overview pass** (every ~8th frame) to map the arc of the recording, then62 read **densely** through the sections that matter (code, terminals, UIs,63 slides, whiteboards, diagrams).643. **Align said ⇄ shown by chronological position**: frames and transcript both65 run start→end, so a frame ~40% through the frame list pairs with text ~40%66 through the transcript. Anchor pairs at unmistakable moments (a screen67 change that matches a topic change) and interpolate between anchors. Record68 the pairing explicitly in the Walkthrough ("What's said / What's shown").694. **Redact secrets.** Recordings of dev work routinely expose tokens, keys,70 account IDs, URLs with credentials, passwords. Never transcribe secret71 values and **never copy a frame that shows one into the vault**. Transcribe72 other on-screen text/code verbatim where legible.7374## Step 3 — Ingest the vault's way7576- **Raw source** → `Raw/Sources/<date>-<slug>-recording.md` with source77 frontmatter (`Title`, `Author`, `Reference` = the URL or filename,78 `ContentType`, `Created`, `Processed: false`, `tags: [source]`). Body: a79 provenance note (crv flags, whisper model, frame count, redactions,80 transcript quality), a **Summary**, a chronological **Walkthrough**81 (What's said / What's shown pairs), the embedded screenshots, a **Key82 topics** list of `[[wikilinks]]`, and the **full transcript** appended at the83 end for searchability.84- **Screenshots** → copy only the important, secret-free frames into `assets/`85 with descriptive names; embed with `![[name.jpg]]`. Do **not** dump all86 frames or the source video into the vault (`Raw/Files/` is gitignored;87 `assets/` is committed).88- **Compile** → search first89 (`python scripts/wiki_tool.py search-catalog --query "…"`), then create or90 enrich focused `Wiki/` notes, each linked back to the Raw source in `sources`91 with an accurate `source_count`. Prefer enriching existing notes over92 duplicating. Capture ambiguity as **Open Questions**; never invent.9394## Step 4 — Gate + commit9596```bash97python scripts/wiki_tool.py build98python scripts/wiki_tool.py lint99python scripts/wiki_tool.py source-scan --update --accept-covered100python scripts/wiki_tool.py source-lint101python scripts/audit_public.py102```103104Commit the Raw source, `assets/` screenshots, compiled notes, and regenerated105artifacts together. Add a log note for substantial ingests.106107## Notes108109- Reference-video mode (a TikTok/YouTube the user wants studied, not archived):110 same Steps 0–2, then answer their question directly; only ingest to the vault111 if they want it kept.112- Optional crv flags: `--grid` (contact sheets), `--keep-audio`, `--report`,113 `--scene 0.2` (more frames), `--whisper-model medium` (better transcript).114- Big videos stay outside the vault; reference them by URL/filename in the Raw115 source's `Reference`.