Why Claude Video Shows "No Frames Extracted": 6 Root Causes and Fixes

Claude Video displays "No frames extracted." when the processing pipeline skips frame extraction due to transcript-only mode, audio-only downloads, zero-duration metadata, aggressive deduplication, out-of-range timestamps, or missing FFmpeg binaries.

When using the bradautomates/claude-video open-source tool to analyze video content, the final report occasionally contains a "No frames extracted." placeholder in the Frames section. This output originates from skills/watch/scripts/watch.py when the frame extraction logic is bypassed or produces empty results. Understanding the specific conditions that trigger this state is essential for debugging video processing workflows and ensuring you receive visual analysis when needed.

How Frame Extraction Works in Claude Video

The processing pipeline in bradautomates/claude-video follows a conditional path: first downloading the source media via download.py, then checking the detail parameter to determine whether visual analysis is required. Only when detail is set to "balanced" or "high" (and not "transcript") does the system proceed to skills/watch/scripts/frames.py to extract candidate frames. After extraction, frames pass through dedupe_perceptual() for deduplication before final inclusion in the report. If any step in this chain fails or is intentionally skipped, the script reaches line 52 of watch.py and prints the default placeholder.

Six Reasons You See "No Frames Extracted"

1. Transcript-Only Detail Mode

The most explicit cause occurs when you request transcript-only output. In skills/watch/scripts/watch.py lines 38–40, the code checks if detail == "transcript" and skips the entire frame extraction block. This is the default behavior when using the --detail transcript flag or when the configuration in config.py specifies transcript mode.

python -m skills.watch.scripts.watch \
    "https://www.youtube.com/watch?v=example" \
    --detail transcript

Result: The report shows "No frames extracted." because the pipeline bypasses visual processing entirely.

2. Audio-Only Downloads Without Timestamps

When detail is set to "transcript" and you provide no cue timestamps, the script sets audio_only = True in skills/watch/scripts/watch.py lines 11–13. This prevents the download of video streams, leaving video_path as None. Without a valid video file path, subsequent calls to frame extraction functions are bypassed automatically.

To force a full video download in transcript mode, add explicit timestamps:

python -m skills.watch.scripts.watch \
    "https://www.youtube.com/watch?v=example" \
    --detail transcript \
    --timestamps "00:10,00:20"

3. Zero-Duration or Unreadable Metadata

If FFprobe cannot determine the video duration, duration_seconds becomes 0. In skills/watch/scripts/frames.py lines 22–26, the auto_fps function calculates a target of 1 frame, but the subsequent extraction receives a max_frames value of 0 (calculated as fps multiplied by 0 seconds). This results in an empty frame list before deduplication even occurs.

4. Complete Removal by Deduplication (Static Videos)

For static screen recordings or slide decks, the perceptual deduplication step may remove every extracted frame. In skills/watch/scripts/watch.py lines 48–49, the function dedupe_perceptual() compares mean-pixel differences between frames. If the video content is essentially unchanged throughout, all candidates fall below the similarity threshold and are discarded, leaving no frames for the final report.

python -m skills.watch.scripts.watch \
    "path/to/static-screen-recording.mp4" \
    --detail balanced \
    --no-dedup   # omit this to see frames disappear

Without the --no-dedup flag, the static video produces zero frames after deduplication.

5. Timestamps Outside the Focus Window

Supplying cue timestamps that fall outside your裁剪 window causes silent frame drops. When you specify --start and --end parameters alongside --timestamps, skills/watch/scripts/watch.py lines 88–94 invoke extract_at_timestamps(). This function drops cues outside the specified window, populating cue_meta["dropped_out_of_window"]. If all requested timestamps lie outside the range, the cue list empties and no frames are generated.

python -m skills.watch.scripts.watch \
    "https://www.youtube.com/watch?v=example" \
    --start 01:00 --end 01:30 \
    --timestamps "00:10,00:20"

Result: Both timestamps precede the 1-minute start window, so extraction produces no output.

6. Missing FFmpeg or FFprobe Binaries

If FFmpeg or FFprobe is not installed or not in your system PATH, the helper scripts abort with a SystemExit before writing any frames. skills/watch/scripts/frames.py lines 86–89 contain binary validation guards that raise errors immediately if these dependencies are missing, halting execution before frame extraction begins.

Practical Examples Reproducing the Issue

The following commands demonstrate specific scenarios that trigger the "No frames extracted." message:

Transcript-only mode (intentional skip):

python -m skills.watch.scripts.watch \
    "https://www.youtube.com/watch?v=example" \
    --detail transcript

Audio-only with forced video download via timestamps:

python -m skills.watch.scripts.watch \
    "https://www.youtube.com/watch?v=example" \
    --detail transcript \
    --timestamps "00:10,00:20"

Static content losing frames to deduplication:

python -m skills.watch.scripts.watch \
    "path/to/static-screen-recording.mp4" \
    --detail balanced

Out-of-range timestamp filtering:

python -m skills.watch.scripts.watch \
    "https://www.youtube.com/watch?v=example" \
    --start 01:00 --end 01:30 \
    --timestamps "00:10,00:20"

How to Fix "No Frames Extracted" Issues

Resolve the empty frame state by addressing the specific trigger:

  • Use --detail balanced or --detail high instead of transcript when you need visual analysis.
  • Add --timestamps when using transcript mode to force full video downloads.
  • Verify video metadata with ffprobe before processing; re-encode files with corrupted headers if necessary.
  • Append --no-dedup for screen recordings or slide presentations to prevent aggressive frame removal.
  • Align timestamps with your --start and --end window, or omit the window parameters to process the entire video.
  • Install FFmpeg and FFprobe and ensure they are accessible in your system PATH.

Summary

  • Transcript mode bypasses frames: The --detail transcript flag explicitly skips extraction in watch.py.
  • Audio-only downloads lack video files: Without timestamps in transcript mode, video_path remains None.
  • Zero duration yields zero frames: Failed duration detection in frames.py results in max_frames = 0.
  • Deduplication eliminates static content: dedupe_perceptual() removes frames from unchanged video segments.
  • Window constraints filter timestamps: Out-of-range cues are dropped, potentially emptying the extraction list.
  • Missing dependencies halt execution: Absent FFmpeg/FFprobe binaries trigger early exits in frames.py.

Frequently Asked Questions

Why does Claude Video say "No frames extracted" when I only want a transcript?

This is expected behavior. When you specify --detail transcript, the code in skills/watch/scripts/watch.py lines 38–40 explicitly bypasses the frame extraction logic to optimize processing time and bandwidth. To receive both transcripts and frames, use --detail balanced or --detail high.

Can I extract frames from a static screen recording?

Yes, but you must disable deduplication. Static videos trigger dedupe_perceptual() in watch.py lines 48–49 to remove near-duplicate frames, which often results in all frames being discarded. Add the --no-dedup flag to preserve frames from screen recordings and slide decks.

How do I force frame extraction when using transcript detail mode?

Supply explicit timestamps using the --timestamps flag. In skills/watch/scripts/download.py, providing timestamps forces audio_only to False, ensuring the video file downloads and becomes available for frame extraction even when detail is set to transcript.

What happens if FFprobe cannot read the video duration?

The auto_fps function in skills/watch/scripts/frames.py lines 22–26 calculates a target frame count based on duration_seconds. If this value is 0 or unreadable, the multiplication of fps by duration yields 0 frames requested, resulting in no extraction and the "No frames extracted." message in the final report.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →