--- name: Video Clipper description: Create video clips from chapter timestamps using ffmpeg. Use when given a video file and timestamps/chapters to split into separate clips. version: 1.0.0 dependencies: ffmpeg allowed-tools: [Bash, Read] --- # Video Clipper ## Overview This Skill uses ffmpeg to create video clips from a source video file. It supports two modes: 1. **Multi-chapter mode**: Split a video into multiple clips based on chapter timestamps 2. **Single snippet mode**: Extract one clip from a time range (e.g., "55s to 2m35s") Supports multiple video formats (MP4, MOV, AVI, MKV) and offers both fast stream copy mode and re-encode mode for consistent quality. ## When to Apply Use this Skill when: - User has a video file and wants to split it into clips - User provides chapter markers or timestamps with topic names - User wants to extract a specific segment with a time range (e.g., "55s to 2m35s", "1:30 to 5:45") - User wants to create a single clip snippet from a time range - User has completed Video Transcript Analyzer skill and now wants to create clips from those timestamps - User asks to "split video by chapters", "create clips from timestamps", "extract video segments", or "create a clip from X to Y" Do NOT use this Skill for: - Video editing (adding effects, transitions, etc.) - Audio-only files (use audio processing tools instead) - Combining/merging multiple videos - Format conversion only (use ffmpeg directly) ## Inputs **For Multi-Chapter Mode:** 1. **Video file path** - Full path to source video (MP4, MOV, AVI, MKV, etc.) 2. **Chapter list with timestamps** - One of these formats: - `00:00:00 - Chapter Name` - `00:05:30 - Another Chapter` - `HH:MM:SS - Chapter Name` - `MM:SS - Chapter Name` (for videos under 1 hour) 3. **Output directory** (optional) - Where to save clips 4. **Encoding preference** (optional) - "copy" or "encode" **For Single Snippet Mode:** 1. **Video file path** - Full path to source video 2. **Time range** - Natural language or standard formats: - `55s to 2m35s` (natural language) - `1:30 to 5:45` (MM:SS format) - `00:01:30 to 00:05:45` (HH:MM:SS format) - Start and end time in any mix of formats 3. **Output filename** (optional) - Name for the clip file 4. **Encoding preference** (optional) - "copy" or "encode" ## Outputs **For Multi-Chapter Mode:** - Individual video clip file for each chapter with sanitized filename - Format: `01-Chapter_Name.mp4` (numbered, spaces replaced with underscores) - Summary report with all clips, durations, sizes, and commands used **For Single Snippet Mode:** - One video clip file with specified or auto-generated name - Format: `[video_name]_[start]-[end].mp4` or custom filename - Brief report with clip duration, size, and command used ## Instructions for Claude ### Step 1: Validate Prerequisites First, check if ffmpeg is installed: ```bash which ffmpeg && ffmpeg -version ``` If not installed, provide installation instructions: - **macOS**: `brew install ffmpeg` - **Linux (Ubuntu/Debian)**: `sudo apt-get install ffmpeg` - **Linux (RHEL/CentOS)**: `sudo yum install ffmpeg` Ask user to install ffmpeg before proceeding if missing. ### Step 2: Detect Mode (Single Snippet vs Multi-Chapter) Check the user's request to determine which mode to use: **Single Snippet Mode indicators:** - User provides a time range: "55s to 2m35s", "from 1:30 to 5:45", "extract 0:55 to 2:35" - User says: "create a clip from X to Y", "extract segment", "get the part between X and Y" - User provides start and end times without chapter names - Only ONE time range is mentioned **Multi-Chapter Mode indicators:** - User provides multiple timestamps with names/descriptions - User says: "split into chapters", "create clips from these timestamps" - User has a list of timestamps with chapter names - Multiple time ranges or chapter markers **If Single Snippet Mode detected**, skip to **Step 2a: Single Snippet Workflow** below. **If Multi-Chapter Mode detected**, continue to **Step 2b: Multi-Chapter Workflow** below. **If unclear**, ask user: "Would you like to create (1) a single clip from a time range, or (2) multiple clips from chapter timestamps?" ### Step 2a: Single Snippet Workflow For creating one clip from a time range: 1. **Get video file path**: - If not provided, ask: "Please provide the full path to your video file" - Validate file exists: `ls -lh [filepath]` - Show file size and duration 2. **Parse time range**: - Look for patterns like: - `55s to 2m35s` → convert to seconds: 55 to 155 - `1:30 to 5:45` → convert to seconds: 90 to 345 - `00:01:30 to 00:05:45` → already in HH:MM:SS format - Support formats: - `Xs` (seconds): 55s = 55 seconds - `Xm` or `XmYs` (minutes): 2m35s = 155 seconds, 5m = 300 seconds - `XhYm` or `XhYmZs` (hours): 1h30m = 5400 seconds - `MM:SS`: 1:30 = 90 seconds - `HH:MM:SS`: 00:01:30 = 90 seconds - If time range not clear, ask: "What time range would you like to extract? (e.g., '55s to 2m35s' or '1:30 to 5:45')" 3. **Get output filename**: - If not provided, generate: `[video_name]_[start]-[end].mp4` - Example: `customer-call_00-55_02-35.mp4` - Ask: "What would you like to name this clip? (Press Enter for: [suggested_name])" 4. **Get encoding preference**: - Ask: "Encoding mode: 'copy' (fast) or 'encode' (precise)? Default: copy" 5. **Convert times to HH:MM:SS format** for ffmpeg: ```python def seconds_to_timestamp(seconds): h = seconds // 3600 m = (seconds % 3600) // 60 s = seconds % 60 return f"{h:02d}:{m:02d}:{s:02d}" ``` 6. **Generate ffmpeg command**: - Copy mode: `ffmpeg -i [video] -ss [start] -to [end] -c copy -avoid_negative_ts 1 "[output]"` - Encode mode: `ffmpeg -i [video] -ss [start] -to [end] -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k "[output]"` 7. **Execute command**: - Show command to user - Execute and capture output - Verify clip was created 8. **Report results**: ```markdown # Video Clip Created **Source:** [video_path] **Time Range:** [start] to [end] ([duration]) **Output:** [output_path] **Size:** [file_size] **Encoding:** [copy/encode] **Command used:** ```bash [ffmpeg command] ``` ``` 9. **Skip to Step 9 (Quality Checks)** ### Step 2b: Multi-Chapter Workflow For creating multiple clips from chapter timestamps: (Continue with existing workflow below...) ### Step 3: Gather Required Information (Multi-Chapter Mode) Check what information is provided. If missing, prompt for: 1. **Video file path**: - Ask: "Please provide the full path to your video file (e.g., /Users/name/video.mp4)" - Validate file exists using `ls -lh [filepath]` - Show file size and confirm with user 2. **Chapter timestamps**: - Ask: "Please provide your chapter list with timestamps in this format: ``` 00:00:00 - Introduction 00:05:30 - Main Topic 00:15:45 - Q&A ``` (Tip: If you have a video transcript, try the Video Transcript Analyzer skill first to generate timestamps)" - Wait for user to provide timestamps 3. **Output directory**: - Ask: "Where would you like to save the clips? (Press Enter for default: same folder as source video with '_clips' suffix)" - Default: `[video_directory]/[video_name]_clips/` 4. **Encoding mode**: - Ask: "Choose encoding mode: - 'copy' (fast, no re-encode, may have keyframe issues at boundaries) - 'encode' (slower, consistent quality, precise cuts) Default: copy" ### Step 4: Parse and Validate Timestamps (Multi-Chapter Mode) 1. **Parse timestamp format**: ```python import re from datetime import datetime, timedelta def parse_timestamp(ts_str): """Convert HH:MM:SS or MM:SS to seconds""" parts = ts_str.strip().split(':') if len(parts) == 3: # HH:MM:SS h, m, s = map(int, parts) return h * 3600 + m * 60 + s elif len(parts) == 2: # MM:SS m, s = map(int, parts) return m * 60 + s else: raise ValueError(f"Invalid timestamp format: {ts_str}") def parse_chapter_line(line): """Parse '00:05:30 - Chapter Name' format""" match = re.match(r'(\d{1,2}:\d{2}:\d{2}|\d{1,2}:\d{2})\s*-\s*(.+)', line.strip()) if match: timestamp, name = match.groups() return parse_timestamp(timestamp), name.strip() return None ``` 2. **Validate timestamps**: - Check all timestamps are in ascending order - Warn if any timestamps are out of order - Check for duplicate timestamps - Ensure first timestamp is 00:00:00 or close to start 3. **Get video duration**: ```bash ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 [video_file] ``` 4. **Calculate end times**: - For each chapter, end time = next chapter's start time - For last chapter, end time = video duration - Validate no chapter extends beyond video duration ### Step 5: Sanitize Filenames (Multi-Chapter Mode) Create safe filenames from chapter names: ```python import re def sanitize_filename(name): """Convert chapter name to safe filename""" # Remove or replace special characters name = re.sub(r'[<>:"/\\|?*]', '', name) # Replace spaces with underscores name = name.replace(' ', '_') # Replace multiple underscores with single name = re.sub(r'_+', '_', name) # Remove leading/trailing underscores name = name.strip('_') # Limit length to 100 chars if len(name) > 100: name = name[:100] return name ``` Generate filenames: - Format: `{number:02d}-{sanitized_name}.{extension}` - Example: `01-Introduction.mp4`, `02-Main_Topic.mp4` - Number chapters sequentially starting from 01 ### Step 6: Create Output Directory (Multi-Chapter Mode) ```bash mkdir -p [output_directory] ``` Show user where clips will be saved. ### Step 7: Generate ffmpeg Commands (Multi-Chapter Mode) **For "copy" mode (fast, no re-encode):** ```bash ffmpeg -i [input_video] -ss [start_time] -to [end_time] -c copy -avoid_negative_ts 1 "[output_file]" ``` **For "encode" mode (slower, precise):** ```bash ffmpeg -i [input_video] -ss [start_time] -to [end_time] -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k "[output_file]" ``` **Key parameters:** - `-ss [start_time]`: Start time in HH:MM:SS format - `-to [end_time]`: End time in HH:MM:SS format - `-c copy`: Stream copy (no re-encode) - `-c:v libx264`: Video codec for encoding - `-preset medium`: Encoding speed/quality balance - `-crf 23`: Quality level (18-28, lower is better) - `-c:a aac`: Audio codec - `-avoid_negative_ts 1`: Fix timestamp issues in copy mode ### Step 8: Execute Clipping Commands (Multi-Chapter Mode) 1. **Show execution plan**: ``` Creating [N] clips from [video_name]: 1. [00:00:00 - 00:05:30] → 01-Introduction.mp4 2. [00:05:30 - 00:15:45] → 02-Main_Topic.mp4 ... ``` 2. **Execute commands sequentially**: - Run one ffmpeg command at a time - Show progress: "Creating clip 1 of N..." - Capture any errors or warnings - Validate each output file was created and has size > 0 3. **For parallel execution** (optional, if user wants speed): - Can run multiple ffmpeg commands in background - Monitor all processes - Wait for all to complete before reporting - Only use if system has multiple cores and user approves ### Step 9: Verify and Report Results (Both Modes) 1. **Check each output file**: ```bash ls -lh [output_directory]/*.mp4 ``` 2. **Get clip durations**: ```bash for file in [output_directory]/*.mp4; do ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file" done ``` 3. **Generate summary report**: ```markdown # Video Clipping Complete ## Source Video - File: [path] - Duration: [HH:MM:SS] - Size: [size] ## Created Clips | # | Clip Name | Duration | Size | Time Range | |---|-----------|----------|------|------------| | 1 | 01-Introduction.mp4 | 05:30 | 15.2 MB | 00:00:00 - 00:05:30 | | 2 | 02-Main_Topic.mp4 | 10:15 | 28.4 MB | 00:05:30 - 00:15:45 | ## Summary - Total clips created: [N] - Total size: [total_size] - Output location: [directory] - Encoding mode: [copy/encode] ## Warnings/Errors [List any issues encountered] ## Commands Used ```bash [Show all ffmpeg commands for reference] ``` ``` ### Step 10: Quality Checks (Both Modes) Before finalizing: - [ ] All expected clip files exist - [ ] Each file has size > 0 bytes - [ ] Clip durations match expected ranges (within 1-2 seconds) - [ ] Filenames are properly sanitized (no special characters) [Multi-chapter only] - [ ] No ffmpeg errors in output - [ ] Summary report shows all clips If using "copy" mode, warn user: > Note: Copy mode may result in clips that don't start exactly at the specified timestamp due to keyframe positions. If precise cuts are needed, re-run with "encode" mode. ### Error Handling **Common errors and solutions:** 1. **ffmpeg not found**: - Error: `command not found: ffmpeg` - Solution: Provide installation instructions 2. **Invalid timestamp**: - Error: Timestamp parsing fails - Solution: Show expected format, ask user to correct 3. **Timestamp beyond video duration**: - Error: End time > video length - Solution: Adjust last chapter to end at video duration 4. **File not found**: - Error: Input video doesn't exist - Solution: Ask user to verify path, suggest using tab completion 5. **Permission denied**: - Error: Cannot write to output directory - Solution: Check directory permissions, suggest alternative location 6. **Codec errors in copy mode**: - Error: "Non-monotonous DTS in output stream" - Solution: Re-run with encode mode or add `-avoid_negative_ts 1` 7. **Overlapping timestamps**: - Error: Timestamps out of order - Solution: Sort timestamps, ask user to confirm order ## Examples ### Example 1: Single Snippet from Time Range **User says:** "Create a clip from 55s to 2m35s" **User provides:** `/Users/alice/videos/customer-call.mp4` **Workflow:** 1. Validate ffmpeg installed ✓ 2. Detect Single Snippet Mode (time range provided) 3. Parse time range: 55s = 55 seconds, 2m35s = 155 seconds 4. Convert to HH:MM:SS: 00:00:55 to 00:02:35 5. Suggest filename: `customer-call_00-55_02-35.mp4` 6. User accepts default filename 7. Ask encoding preference: user chooses "copy" 8. Generate ffmpeg command: ```bash ffmpeg -i /Users/alice/videos/customer-call.mp4 -ss 00:00:55 -to 00:02:35 -c copy -avoid_negative_ts 1 "customer-call_00-55_02-35.mp4" ``` 9. Execute command 10. Report results: ``` # Video Clip Created **Source:** /Users/alice/videos/customer-call.mp4 **Time Range:** 00:00:55 to 00:02:35 (1m 40s) **Output:** /Users/alice/videos/customer-call_00-55_02-35.mp4 **Size:** 8.2 MB **Encoding:** copy ``` **Output file:** ``` /Users/alice/videos/customer-call_00-55_02-35.mp4 (8.2 MB, 1m 40s) ``` ### Example 2: Basic Usage with SRT Timestamps (Multi-Chapter) **User provides:** ``` Video: /Users/alice/videos/customer-call.mp4 Chapters: 00:00:00 - Introduction 00:02:57 - Memberships & Registration 00:09:41 - Lists vs Views 00:15:30 - API Limitations ``` **Workflow:** 1. Validate ffmpeg installed 2. Check video file exists (352 MB, 18:45 duration) 3. Parse 4 chapters with timestamps 4. Ask for encoding preference (user chooses "copy") 5. Create output directory: `/Users/alice/videos/customer-call_clips/` 6. Generate 4 ffmpeg commands 7. Execute sequentially 8. Verify all 4 clips created **Output files:** ``` /Users/alice/videos/customer-call_clips/ 01-Introduction.mp4 (15.2 MB, 02:57) 02-Memberships_Registration.mp4 (28.4 MB, 06:44) 03-Lists_vs_Views.mp4 (24.1 MB, 05:49) 04-API_Limitations.mp4 (12.8 MB, 03:15) ``` ### Example 3: From Video Transcript Analyzer Output (Multi-Chapter) **User says:** "I just ran Video Transcript Analyzer on my interview. Can you create clips from those chapters?" **Workflow:** 1. Ask user: "Please share the video file path and the chapter timestamps from the analysis" 2. User provides video path and copies the "Topical Breakdown" section timestamps 3. Parse timestamps: ``` 00:02:57 - Memberships & Registration Management 00:09:41 - Lists vs Views Disconnect 00:15:30 - API Limitations 00:20:15 - Workflow Automation Issues ``` 4. Get video duration: 25:42 5. Calculate last chapter ends at 25:42 6. Ask encoding preference (user chooses "encode" for precise cuts) 7. Create clips with re-encoding 8. Report: 4 clips created, 156 MB total ### Example 4: Simple Timestamps - MM:SS format (Multi-Chapter) **User provides:** ``` Video: /home/user/videos/tutorial.mp4 Chapters: 0:00 - Intro 5:30 - Setup 12:45 - Demo 18:20 - Q&A ``` **Workflow:** 1. Parse MM:SS format timestamps (convert to seconds) 2. Validate video is 22:15 long 3. Calculate end times: - Intro: 0:00 - 5:30 - Setup: 5:30 - 12:45 - Demo: 12:45 - 18:20 - Q&A: 18:20 - 22:15 4. Create 4 clips in encode mode (user requested precise cuts) 5. Success: All clips created ## Testing Checklist - [ ] ffmpeg detection works correctly - [ ] Handles both HH:MM:SS and MM:SS timestamp formats - [ ] Validates timestamps are in ascending order - [ ] Correctly calculates end times from next chapter start - [ ] Last chapter uses video duration as end time - [ ] Sanitizes filenames (removes special chars, replaces spaces) - [ ] Creates output directory if it doesn't exist - [ ] Both "copy" and "encode" modes work - [ ] Generates proper ffmpeg commands - [ ] Verifies all output files created - [ ] Reports file sizes and durations accurately - [ ] Handles errors gracefully (missing video, invalid timestamps) - [ ] Warns about copy mode keyframe limitations - [ ] Provides summary report with all details ## Security and Privacy **File Access:** - Only reads user-specified video file - Only writes to user-specified output directory - Does not modify source video file - Validates all paths before execution **Command Execution:** - All ffmpeg commands shown to user before execution - No arbitrary command injection - Filenames sanitized to prevent shell injection - Uses absolute paths to prevent directory traversal **Privacy:** - Video content never sent to external services - All processing done locally with ffmpeg - Chapter names may contain sensitive info - handle appropriately - Output files remain in user's filesystem ## Resources See `resources/` folder for: - **EXAMPLES.md**: Detailed examples with full input/output - **REFERENCE.md**: ffmpeg command reference, timestamp formats, troubleshooting guide - **README.md**: User-facing documentation ## Related Skills (Workflow Chain) This skill is part of the **video processing workflow**: ``` ┌─────────────────────┐ │ wistia-uploader │ → Upload video, get transcript └──────────┬──────────┘ │ ▼ ┌─────────────────────────────┐ │ video-transcript-analyzer │ → Analyze transcript, get timestamps └──────────┬──────────────────┘ │ ▼ ┌─────────────────────┐ │ video-clipper │ ← YOU ARE HERE │ (create clips) │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ wistia-uploader │ → (Optional) Upload clips to Wistia └─────────────────────┘ ``` **Preceding skill:** `video-transcript-analyzer` - Use this first to generate chapter timestamps from a transcript **Following skill:** `wistia-uploader` - Optionally upload the created clips to Wistia for hosting