CommunityCodierung & Entwicklunggithub.com

akimov121-hub/watch

| Watches any video by URL (YouTube, Loom, a Zoom recording, a direct mp4) — not just the transcript, but what's actually SHOWN on screen. Frames are pulled by scene change (ffmpeg scene detection), not on a timer, so it doesn't miss graphics, demos, edits or b-roll. Audio: subtitles via yt-dlp first, Whisper as a fallback. Use this when the user writes /watch <url> or asks to "watch this video", "go through this recording/call/ lecture", "what's shown on screen". Triggers: /watch, watch this vi

Was ist watch?

watch is a Claude Code agent skill that | Watches any video by URL (YouTube, Loom, a Zoom recording, a direct mp4) — not just the transcript, but what's actually SHOWN on screen. Frames are pulled by scene change (ffmpeg scene detection), not on a timer, so it doesn't miss graphics, demos, edits or b-roll. Audio: subtitles via yt-dlp first, Whisper as a fallback. Use this when the user writes /watch <url> or asks to "watch this video", "go through this recording/call/ lecture", "what's shown on screen". Triggers: /watch, watch this vi.

Funktioniert mitClaude CodeCodex CLI~Cursor
npx skills add https://github.com/akimov121-hub/watch/tree/main

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

watch — Claude watches a video end to end

Splits a video into what Claude reads natively: frame images (seen with the Read tool) + a transcript (text). The result is understanding not just the words, but what's happening on screen.

Bilingual. This is the English version. A full Russian mirror is SKILL.ru.md. Work in whatever language the user uses; the workflow and commands are identical.

Dependencies (installed once via install.sh)

Check with: command -v yt-dlp ffmpeg whisper node.

  • yt-dlp~/.local/bin/yt-dlp (under Python 3.12 in ~/.local/python312 — the system Python is usually too old; recent yt-dlp releases need 3.10+);
  • ffmpeg → from imageio-ffmpeg, symlinked to ~/.local/bin/ffmpeg;
  • whisperopenai-whisper (under the system Python; the model downloads on first use);
  • node~/.local/node (v24) — needed to get past YouTube's defenses.

For YouTube specifically, install.sh also sets up:

  • a PO-token provider (bgutil), built in script mode under ~/.local/bgutil-pot/server/build/;
  • a Node.js runtime + an EJS component, to solve YouTube's n-challenge;
  • cookies from a logged-in YouTube account, at ~/.config/watch/cookies.txt.

If cookies go stale (YouTube starts asking to "confirm you're not a bot" again), ask the user to re-export cookies.txt with a browser extension like "Get cookies.txt LOCALLY" and drop it at ~/.config/watch/cookies.txt.

Always download through the wrapper bash ~/.claude/skills/watch/yt.sh … — it adds the right YouTube flags automatically. For direct mp4/Loom/Zoom URLs the extra flags are harmless.

Workflow

1. Setup

  • Make a working folder: mkdir -p /tmp/watch/<slug> (slug = a short name from the URL/topic).
  • Parse the URL (YouTube / Loom / a Zoom share link / a direct video file). A local file skips the download steps — work with it directly.

2. Transcript — subtitles first (free, when available)

bash ~/.claude/skills/watch/yt.sh --write-subs --write-auto-subs --sub-langs "en,ru" \
  --skip-download --convert-subs srt -o "/tmp/watch/<slug>/subs.%(ext)s" "<URL>"

If a .srt shows up, that's a ready transcript with timestamps — use it.

3. Download the video (needed both for frames and as a Whisper fallback)

bash ~/.claude/skills/watch/yt.sh -f "bv*[height<=480]+ba/b[height<=480]/18/best" \
  -o "/tmp/watch/<slug>/video.%(ext)s" "<URL>"

You'll get a .mp4 or .webm — use the real filename from here on (video.*). If there were no subtitles, transcribe the audio with Whisper (model small; base is faster for a quick test):

whisper "/tmp/watch/<slug>/video.webm" --model small --language en \
  --output_format srt --output_dir "/tmp/watch/<slug>/"

The first run downloads the model (~460 MB for small) — that's normal, one-time. Drop --language en for non-English audio, or set the right language code. Whisper is slow: a 34-minute clip takes several minutes — run it in the background.

4. Frames BY SCENE CHANGE (the key step — not on a timer)

ffmpeg -i "/tmp/watch/<slug>/video.webm" -vf "select='gt(scene,0.3)',showinfo" \
  -vsync vfr "/tmp/watch/<slug>/frames/frame_%04d.png" 2> "/tmp/watch/<slug>/scenes.log"
  • Threshold 0.3 — tune 0.2–0.4 for scene density (a lower threshold = more frames).
  • Get each frame's timestamp from the showinfo log (pts_time) in scenes.log.
  • If there are too many frames (a long video), keep around 60–150 of the most informative ones, thinning out frames that are close together in time. Decoding a long video takes a while — run it in the background.

FALLBACK — if there are too few scenes (0–2 frames). Smooth, uncut footage (one continuous shot, a drone, a talking head) produces few scene changes. In that case, sample at a fixed interval instead:

ffmpeg -i "/tmp/watch/<slug>/video.webm" -vf "fps=1/5,scale=960:-1,showinfo" \
  -vsync vfr "/tmp/watch/<slug>/frames/frame_%04d.png" 2> "/tmp/watch/<slug>/scenes.log"

Adjust the interval (1/5 = one frame every 5s) to the video's length so you stay around ~150 frames. The i-th frame's timestamp = i × interval.

4a. YouTube: why everything goes through yt.sh

YouTube (2025+) requires all three of these at once, or you get HTTP 403 / "not a bot" / "only images":

  1. cookies from a logged-in account (~/.config/watch/cookies.txt);
  2. a PO-token (proof-of-origin) — generated locally by bgutil (script mode, Node);
  3. solving the n-challenge — a Node runtime + an EJS component (--remote-components ejs:github). All of this is already built into yt.sh — just call it. Direct mp4/Loom/Zoom sources don't have these defenses. If it asks to "confirm you're not a bot" again, the cookies went stale — ask for a fresh cookies.txt.

5. Analysis

  • Read the transcript (.srt).
  • Look at the extracted frames (vision, via the Read tool): slides, code, demos, graphics.
  • Tie the visuals to the transcript using timestamps.

6. Report

Deliver:

  • a TL;DR (3–5 lines);
  • key concepts with timestamps;
  • what's shown ON SCREEN that isn't in the text (charts, UIs, demos);
  • notable moments / quotes with timestamps.

7. Saving to a knowledge base (ask first)

Ask: "Save this breakdown to your knowledge base (Obsidian)?" If yes, write a markdown note into the right folder with links to related notes. Don't save without confirmation.

Rules

  • Working files go into a temp folder /tmp/watch/<slug> — don't clutter the project.
  • Don't publish or send anything externally without an explicit request.
  • Don't bypass a login-gated private video — tell the user instead.

Verwandte Skills