agentsclimarketplace

Watch video

Skill anaidenko/claude-video-digest/skills/watch-video

Watch a video — a screen recording, a demo clip, a bug report attachment, any video file or URL — by turning it into a readable contact sheet, frames and a transcript. Use whenever a message, ticket or comment carries a video link or path and the recording would answer a question — "watch this", "check the video", "what does the recording show", "what did they say". Handles phone and tablet captures in either orientation; transcribes only when the audio actually carries speech.From its SKILL.md

Install
npx -y skills add anaidenko/claude-video-digest --skill watch-video

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

6.8 KB, as published. Nobody here has run it

watch-video

Claude cannot play video, but it can read images. This turns a recording into a contact sheet plus individual frames, and transcribes the audio when there is any.

Public share links need no auth — most screen-recording tools (Zight, CloudApp, Loom, Droplr, ...) produce links that are viewable without logging in. Fetch them directly; don't ask the user for screenshots as a first move.

Run it

"${CLAUDE_PLUGIN_ROOT}/scripts/video-digest.sh" <url|file.mp4> [--ticket <id>] [--title <text>]

${CLAUDE_PLUGIN_ROOT} is the plugin's install directory — use it rather than a relative path. The script sits at the plugin root, not inside this skill's own folder, so a relative ./scripts/... resolves to the wrong place and fails with "no such file or directory". Outside a plugin install (a plain clone), ./scripts/video-digest.sh from the repo root is the equivalent.

Pass --ticket and --title when known — they name the output directory, which is how the user navigates a persistent cache later. By default output goes to the OS temp directory; pass --output <dir> for a persistent one.

Useful flags: --max-frames N, --no-dedupe, --transcript never, --force, --sample-fps N (raises the pre-dedupe frame pool — combine with --no-dedupe when a transient frame keeps getting dropped). Full list and current config: --help.

Read it

  1. contact-sheet.jpg first — one image, the whole clip, timestamps burned in. Usually enough on its own.
  2. frames/frame_NNN.jpg only when the sheet leaves something unresolved.
  3. transcript.txt when present. It is grouped by frame: each block gives the words spoken while that frame was on screen, so speech and screen state read together. A — means nobody spoke over that frame. The unbroken transcript follows at the end for a quick "what is this clip about".

The first and last frames are always included — the opening state and the outcome. "Last" is the last frame that survived dedupe, not the end of the file, so it lands on real content instead of a black screen a recorder can leave at the end.

Timestamps on the sheet are approximate (frame ordinal × interval, not true PTS) — fine for navigating, not for quoting exact times.

Cell size adapts to the source, so tablet and phone recordings in either orientation both stay legible. The frames in frames/ are always full resolution — open one when the sheet's downscale hides a detail.

What to watch out for

  • The default frame count is a starting point, not a limit. When the sheet doesn't settle the question, re-run with a higher --max-frames and say what was ambiguous. Do this before handing anything back to the user.
  • A sequence where a count changes (items deleted, created, or reordered) needs dense re-extraction before any conclusion goes into a report. The default budget is tuned for "what is this clip about", not "what exactly happened, in what order". A real triage session read a sparse sheet as "a deleted item reappeared" — re-extracted at a much higher --max-frames, the same clip showed something else entirely (a second, different item was deleted; a transient loading state the sparse sheet had skipped explained the miscount). The wrong conclusion had already been written into a report before the density was raised. Treat any story involving a count as provisional until checked at higher density, not just when the sheet already looks ambiguous.
  • Dedupe can drop the exact frame that explains a discrepancy. It keeps visually distinct frames, but a brief loading/transient state can look similar enough to the frame before or after it to get dropped. If a count or an order doesn't add up, re-run with --no-dedupe in addition to a higher --max-frames.
  • A missing transcript.txt usually means silence, not failure. Screen recorders often write an empty audio track when the mic is off; the tool measures loudness and skips transcription below a threshold. The summary line says which happened.
  • The recording date is not necessarily today, or the date it was shared. meta.json carries recorded and recorded_source — check them before assuming a recording reflects the current state of anything.
  • archived/ (inside a persistent output dir) is the user's. A recording moved there is resolved; the tool refuses to re-process it without --force. Don't move things in or out on the user's behalf.
  • source.url is a double-clickable shortcut to the original, for when frames aren't enough. It exists only for a URL input — a local file has no url to record.
  • Frames answer what happened on screen. They do not prove why — confirm the mechanism elsewhere before reporting a cause.
  • End the answer with where the output landed, one markdown link per line. The script's last lines print the output directory and the paths to contact-sheet.jpg, frames/, transcript.txt, source.url and meta.json — pass those through as [label](file:///abs/path) so the host can render them clickable; a bare path string is inert in most chat UIs. One link per line, not ·-joined on one line — several markdown links crammed together render as a cluttered run-on, each expanding inline. A summary with no paths leaves the user unable to open the sheet, check a frame you described, or reach the original recording, and they have to ask. A short closing list is enough:
<pre> Output: [<run-dir>](file:///path/to/&lt;run-dir&gt;) - [contact-sheet.jpg](file:///path/.../contact-sheet.jpg) - [frames/](file:///path/.../frames/) (N) - [transcript.txt](file:///path/.../transcript.txt) — only when the audio had signal; omit this line entirely when it wasn't written, don't link a file that doesn't exist - [source.url](file:///path/.../source.url) - [meta.json](file:///path/.../meta.json) </pre>

Dependencies

ffmpeg (with libfreetype for timestamps), ffprobe and python3 are required and checked up front. curl is needed only for a URL input, whisper only when the audio carries speech, yt-dlp only for sites the built-in scraper can't resolve — all three degrade gracefully without failing the run. See "${CLAUDE_PLUGIN_ROOT}/scripts/video-digest.sh" doctor for what's currently available.

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.