# Extract 1 frame + audio segment per second (default)
~/skills/extract-video-frames/scripts/extract-frames.sh input.mp4
# Extract 1 frame + audio segment every 2 seconds
~/skills/extract-video-frames/scripts/extract-frames.sh input.mp4 2
# Specify custom output directory
~/skills/extract-video-frames/scripts/extract-frames.sh input.mp4 1 ./my-frames
The script creates:
frames/ directory with PNG files named frame_001.png, frame_002.png, etc.
frames/audio_001.aac, audio_002.aac, etc. (when audio exists, aligned 1:1 with frames)
frames/full_audio.aac (complete audio track, when audio exists)
frames/manifest.json with frame and audio metadata for the reviewing agent
Run extraction script
~/skills/extract-video-frames/scripts/extract-frames.sh <video-path> [interval-seconds] [output-dir]
video-path: Path to GIF, MP4, or MOV file (required)
interval-seconds: Extract one frame every N seconds (default: 1)
output-dir: Where to store frames and audio (default: ./frames)
Review manifest
The manifest.json contains:
{
"source": "recording.mp4",
"source_path": "/path/to/recording.mp4",
"interval_seconds": 5,
"total_frames": 12,
"has_audio": true,
"audio_codec": "aac",
"total_audio_segments": 12,
"full_audio_path": "full_audio.aac",
"output_directory": "./frames",
"frames": [
{
"index": 1,
"timestamp": "00:00:00",
"timestamp_seconds": 0,
"path": "frame_001.png",
"audio_path": "audio_001.aac"
},
{
"index": 2,
"timestamp": "00:00:05",
"timestamp_seconds": 5,
"path": "frame_002.png",
"audio_path": "audio_002.aac"
}
]
}
Hand off to reviewing agent
Pass the output directory path to the reviewing agent. The agent can read manifest.json to understand the frame sequence with audio alignment and use the Read tool to analyze individual frames.
Codec strategy:
- If the source audio is already AAC, segments are stream-copied (no re-encoding) for speed and quality preservation.
- If the source audio is any other codec (e.g., PCM, MP3, Opus), segments are re-encoded to AAC at 128kbps.
Alignment semantics: Each audio_NNN.aac segment covers the same time window as its corresponding frame_NNN.png. For a 5-second interval, audio_001.aac covers 0:00-0:05, audio_002.aac covers 0:05-0:10, etc.
No-audio handling: When the source has no audio stream (GIFs, silent videos), has_audio is false, no audio files are created, and all audio_path fields in the manifest are null. The frame extraction works identically regardless.
Full audio track: full_audio.aac contains the entire audio from the source file as a single continuous track, useful for full transcription or background listening.
- Output directory path: Where frames and audio are stored
- Manifest location:
{output-dir}/manifest.json
- Context: What the reviewing agent should look for
Example prompt for reviewing agent:
Analyze the frames and audio extracted from the screen recording at ./frames.
The manifest at ./frames/manifest.json lists all frames with timestamps and paired audio segments.
The full audio track is at ./frames/full_audio.aac for continuous listening or transcription.
Look for: [specific things to identify or analyze]
Example prompt for audio-focused agent:
Transcribe the audio segments from the recording at ./frames.
Read ./frames/manifest.json to get the list of audio files with timestamps.
For each audio_NNN.aac segment, provide a timestamped transcript.
The full continuous audio is also available at ./frames/full_audio.aac.
1---2name: extract-video-frames3description: <objective>4---56<objective>7Extract frames and aligned audio segments from video files (GIF, MP4, MOV) at specified intervals using ffmpeg. Outputs PNG frames, per-segment AAC audio clips, a full continuous audio track, and a JSON manifest containing timestamps and paths -- ready for handoff to another agent for visual and audio analysis.8</objective>910<quick_start>11Extract frames and audio from a video:1213```bash14# Extract 1 frame + audio segment per second (default)15~/skills/extract-video-frames/scripts/extract-frames.sh input.mp41617# Extract 1 frame + audio segment every 2 seconds18~/skills/extract-video-frames/scripts/extract-frames.sh input.mp4 21920# Specify custom output directory21~/skills/extract-video-frames/scripts/extract-frames.sh input.mp4 1 ./my-frames22```2324The script creates:25- `frames/` directory with PNG files named `frame_001.png`, `frame_002.png`, etc.26- `frames/audio_001.aac`, `audio_002.aac`, etc. (when audio exists, aligned 1:1 with frames)27- `frames/full_audio.aac` (complete audio track, when audio exists)28- `frames/manifest.json` with frame and audio metadata for the reviewing agent29</quick_start>3031<workflow>321. **Verify ffmpeg is available**33 ```bash34 which ffmpeg || echo "ffmpeg not found - install with: brew install ffmpeg"35 ```36372. **Run extraction script**38 ```bash39 ~/skills/extract-video-frames/scripts/extract-frames.sh <video-path> [interval-seconds] [output-dir]40 ```4142 - `video-path`: Path to GIF, MP4, or MOV file (required)43 - `interval-seconds`: Extract one frame every N seconds (default: 1)44 - `output-dir`: Where to store frames and audio (default: `./frames`)45463. **Review manifest**47 The manifest.json contains:48 ```json49 {50 "source": "recording.mp4",51 "source_path": "/path/to/recording.mp4",52 "interval_seconds": 5,53 "total_frames": 12,54 "has_audio": true,55 "audio_codec": "aac",56 "total_audio_segments": 12,57 "full_audio_path": "full_audio.aac",58 "output_directory": "./frames",59 "frames": [60 {61 "index": 1,62 "timestamp": "00:00:00",63 "timestamp_seconds": 0,64 "path": "frame_001.png",65 "audio_path": "audio_001.aac"66 },67 {68 "index": 2,69 "timestamp": "00:00:05",70 "timestamp_seconds": 5,71 "path": "frame_002.png",72 "audio_path": "audio_002.aac"73 }74 ]75 }76 ```77784. **Hand off to reviewing agent**79 Pass the output directory path to the reviewing agent. The agent can read `manifest.json` to understand the frame sequence with audio alignment and use the Read tool to analyze individual frames.80</workflow>8182<supported_formats>83- **GIF**: Animated GIFs (extracts frames; no audio stream, gracefully skipped)84- **MP4**: Standard video format (frames + audio)85- **MOV**: QuickTime format (frames + audio)86- **Other**: Any format ffmpeg supports (AVI, WebM, MKV, etc.)87</supported_formats>8889<output_structure>90```91output-dir/92├── manifest.json # Frame + audio metadata for reviewing agent93├── full_audio.aac # Complete audio track (when audio exists)94├── frame_001.png # First extracted frame95├── frame_002.png # Second extracted frame96├── audio_001.aac # Audio segment for frame 1 (when audio exists)97├── audio_002.aac # Audio segment for frame 298└── ...99```100</output_structure>101102<audio_details>103**Format**: AAC (.aac) -- chosen for universal compatibility, small file size, and broad tooling support.104105**Codec strategy**:106- If the source audio is already AAC, segments are stream-copied (no re-encoding) for speed and quality preservation.107- If the source audio is any other codec (e.g., PCM, MP3, Opus), segments are re-encoded to AAC at 128kbps.108109**Alignment semantics**: Each `audio_NNN.aac` segment covers the same time window as its corresponding `frame_NNN.png`. For a 5-second interval, `audio_001.aac` covers 0:00-0:05, `audio_002.aac` covers 0:05-0:10, etc.110111**No-audio handling**: When the source has no audio stream (GIFs, silent videos), `has_audio` is `false`, no audio files are created, and all `audio_path` fields in the manifest are `null`. The frame extraction works identically regardless.112113**Full audio track**: `full_audio.aac` contains the entire audio from the source file as a single continuous track, useful for full transcription or background listening.114</audio_details>115116<agent_handoff>117When passing frames and audio to another agent, include:1181191. **Output directory path**: Where frames and audio are stored1202. **Manifest location**: `{output-dir}/manifest.json`1213. **Context**: What the reviewing agent should look for122123Example prompt for reviewing agent:124```125Analyze the frames and audio extracted from the screen recording at ./frames.126The manifest at ./frames/manifest.json lists all frames with timestamps and paired audio segments.127The full audio track is at ./frames/full_audio.aac for continuous listening or transcription.128Look for: [specific things to identify or analyze]129```130131Example prompt for audio-focused agent:132```133Transcribe the audio segments from the recording at ./frames.134Read ./frames/manifest.json to get the list of audio files with timestamps.135For each audio_NNN.aac segment, provide a timestamped transcript.136The full continuous audio is also available at ./frames/full_audio.aac.137```138</agent_handoff>139140<success_criteria>141Frame and audio extraction is complete when:142- Output directory contains PNG frames143- `manifest.json` exists with valid frame and audio metadata144- Frame count matches expected based on video duration and interval145- Frames are readable by the Read tool for visual analysis146- When source has audio: audio segments exist (1:1 with frames), `full_audio.aac` exists, `has_audio` is `true`147- When source has no audio: `has_audio` is `false`, `audio_path` values are `null`, no audio files created148</success_criteria>