video-viewerSAFE
[Demo] Claude Code skill that lets Claude watch videos: frames, transcript, and frame-to-frame change detection. Early and rough.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
⚠️ This is an early demo. It works, but it's rough and has known problems (see Known issues). Expect bugs, and feel free to open an issue or suggest fixes.
A Claude Code skill that lets Claude watch videos.
Claude can't play video, but it can look at images and read text. This skill turns a video into:
- frames: 2 per second by default (Claude asks you first and shows how many images each rate gives)
- a transcript: speech-to-text with timestamps, done locally and for free with faster-whisper
- a change timeline: every frame is scored by how much it changed from the one before, so Claude can find
cuts, motion and small changes such as on-screen text or a cursor
Claude then looks at the frames in order, asking what changed? each time, and describes the video as a sequence of events with timestamps instead of a pile of separate pictures.
Install
- Copy this folder into your skills directory:
git clone https://github.com/allebasl/video-viewer ~/.claude/skills/video-viewer
- Install the Python dependencies (Python 3.9+):
python -m pip install -r ~/.claude/skills/video-viewer/requirements.txt
imageio-ffmpeg includes its own copy of ffmpeg, so you don't need to install ffmpeg separately. The first transcription downloads a speech model (~150 MB).
Use
Paste a video path into Claude Code:
watch "C:\Users\me\Videos\clip.mp4" and tell me what happens
or run /video-viewer . Claude checks the video, asks how many frames per second to use (reply default for 2/sec), extracts everything, and reports a summary, a timeline, what was said, and any details that are easy to miss.
The script on its own
python scripts/extract.py VIDEO --probe # duration, audio, frame-count estimates python scripts/extract.py VIDEO --fps 2
ba78ac4ab305OBSERVED · 2026-10-13Install
Commands as the repository documents them. They are shown, not run.
git clone https://github.com/allebasl/video-viewer ~/.claude/skills/video-viewer
Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned | |
| cursor | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: video-viewer
description: Lets Claude actually watch a video. It breaks the video into frames (2 per second by default, after asking the user), transcribes the audio with faster-whisper, and analyzes what CHANGES from frame to frame so Claude understands motion, events and timing, not just still images. Use this whenever the user sends, attaches, drops or points to a video file (.mp4, .mov, .webm, .mkv, .avi, .m4v, screen recordings, clips), or asks Claude to watch, view, summarize, describe, transcribe or answer questions about a video, even if they don't say "frames" or name this skill.
---
# Video Viewer
Claude can't play video, but it can look at images and read text. This skill turns a video into
**a timed sequence of frames + a transcript + a change score for each frame**, so you can understand it
*as a video*: what happens, in what order, what moves, appears or disappears, and what is said while it happens.
The main idea: **a video is the changes between frames.** A single frame shows a scene. The difference
between frame N and frame N+1 shows the action. Look at the frames in order and keep asking what
changed since the last one.
## Workflow
### 1. Find the video and probe it
Get the path to the video file (from the user's message, an attachment path, or by asking). Then run:
```bash
python ~/.claude/skills/video-viewer/scripts/extract.py "<video>" --probe
```
This prints the duration, the resolution, whether there's audio, and the frame count at several rates.
### 2. Ask the user for the frame rate (default 2 per second)
Ask before extracting, and show the numbers so the user can choose, e.g.:
> This video is 0:45 long and has audio. How many images per second should I take?
> Default is **2/sec (≈91 images)**. Use 1/sec (≈46) for a quicker look, or 4–5/sec for fast action.
If the user already gave a rate in their message ("use 5 fps"), or says "default"/"just do it",
don't ask again; use what they said (2 if nothing). Higher rates catch fast motion but cost more
images to view. The script caps output at 150 frames by default and says so if it lowers the rate.
Pass `--max-frames N` if the user really wants more.
### 3. Extract
```bash
python ~/.claude/skills/video-viewer/scripts/extract.py "<video>" --fps <rate>
```
Useful flags: `--no-audio` (skip transcription), `--model small` (more accurate speech, slower; the default is `base`),
`--out <dir>`. The first transcription downloads a speech model (~150MB), so tell the user if it takes a while.
If a dependency is missing, the script prints the `pip install` command to run.
The script prints the output folder. It contains:
- `timeline.md`: **read this first.** It has one row per frame with the timestamp, **change %** (overall difference
from the previous frame, which flags cuts and big motion), **area %** (how much of the image changed, which catches small
changes like on-screen text, a cursor or a counter), a label (START / static / minor / change / BIG CHANGE) and the speech
during that frame.
- `transcript.txt`: the full timestamped speech.
- `frames/frame_00001.jpg ...`: the images.
### 4. Watch the video
1. Read `timeline.md` and `transcript.txt` to get the shape of the video: where the cuts and busy stretches are,
where it's static, and what's said when.
2. View the frames **in chronological order** with the Read tool. Read several images per message
(batches of about 10–20 in parallel) so you see neighboring frames together.
- With ~60 frames or fewer, look at all of them.
- With more, look at every frame labeled BIG CHANGE or change, the frame just **before** each one (so you
can see the before/after), and a sample of the static/minor runs (about one per 2–3 seconds). Long static
stretches really are the same picture, and the change score already tells you so.
3. For each step, note **what changed**: objects or people entering/leaving, movement direction, camera moves
(pan/zoom/cut), text or UI appearing on screen, expressions and gestures, and on-screen text changing.
Link the changes to the speech at the same timestamp, since what's said often explains what's shown.
4. Treat the change % as a hint, not the truth. Camera shake gives high scores with no real event, and a small
but important change (a cursor click, a number updating) can score low. Your eyes decide.
### 5. Report
Unless the user asked a specific question (then answer it directly, citing timestamps as evidence), give:
```
## Summary
2–4 sentences: what the video is and what happens.
## Timeline
- 00:00 – 00:04 Opening: ... (the scene)
- 00:04 CUT → ... (what changed)
- 00:07 – 00:15 ... moves/does ...; speaker says "..."
...
## Audio / Speech
Short summary of what's said (or "no speech" / "music only"). Quote key lines with timestamps.
## Notable details
Anything easy to miss: on-screen text, small changes, things that contradict the audio, etc.
```
Write it as a description of motion and events over time ("the person picks up the cup at 0:06 and walks
out of frame by 0:09"), not as a list of separate still images. That's what makes it watching a video
rather than looking at a slideshow.
Be honest about the limits of sampling: anything faster than the frame interval (0.5s at 2/sec) may be
missed. If something important seems to happen between two frames, say so, and offer to re-extract that
section at a higher rate.
### Follow-ups
The frames stay in the output folder, so you can answer follow-up questions by re-reading specific frames
instead of extracting again. To zoom in on a short section at a higher rate, cut it with the bundled ffmpeg:
```bash
python -c "import imageio_ffmpeg;print(imageio_ffmpeg.get_ffmpeg_exe())"
"<ffmpeg>" -ss 00:00:12 -to 00:00:16 -i "<video>" -c copy clip.mp4
```
Then run extract.py on `clip.mp4` with a higher `--fps` and a separate `--out`.Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- declared (1 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (2)
return __import__(mod)
imageio-ffmpeg, faster-whisper, numpy, pillow
Gates applied: no_behavioural_pass.
ba78ac4ab305full audit observations/trust-audit/skill/allebasl__video-viewer.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-13 | ba78ac4ab305 | SAFE | B | 89 | first audit |
Questions
What does the video-viewer skill do?
[Demo] Claude Code skill that lets Claude watch videos: frames, transcript, and frame-to-frame change detection. Early and rough.
Is video-viewer safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can video-viewer access on my machine?
The audit observed that it runs shell commands. Each of those is consistent with what it says it does. Secrets in the source: none found.
Which assistants does video-viewer work with?
Its documentation mentions claude-code and cursor. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (ba78ac4ab305), read on 2026-10-13. The repository is watched, and a new audit runs when it changes — this is the first audit.