| name | video-cleaning |
| description | Clean spoken videos by transcribing them, detecting pauses and filler words, and generating edited outputs with a conservative Korean-focused workflow. |
Video Cleaning Skill
Automated video transcription and editing workflow that removes pauses and filler words from Korean videos using OpenAI Whisper API and MoviePy for frame-accurate cuts.
When to Use This Skill
Use this skill when you need to:
- Clean up recorded presentations or talks
- Remove awkward pauses and "uh/um" sounds from videos
- Reduce video length by removing dead air
- Create polished videos from raw recordings
- Process Korean language videos with natural speech patterns
Perfect for: Presentation recordings, lecture videos, podcast recordings, interview footage, or any speaking video that needs cleaning.
Example Results
See the before/after comparison:
Requirements
System Requirements
- FFmpeg: Video processing tool (must be installed)
- macOS:
brew install ffmpeg
- Linux:
sudo apt install ffmpeg
- Windows: Download from ffmpeg.org
Python Requirements
- OpenAI Python SDK:
pip install openai
- MoviePy:
pip install moviepy (video editing with frame accuracy)
- OpenAI API Key: Set environment variable
OPENAI_API_KEY
- Get your API key from platform.openai.com
- Cost: ~$0.15 per 25-minute video (Whisper transcription)
Python Version
How It Works
This skill uses a two-step workflow:
Step 1: Transcription (transcribe_video.py)
- Extracts audio from video using FFmpeg
- Sends audio to OpenAI Whisper API for transcription
- Receives word-level timestamps (precise timing for each word)
- Generates three output files:
{video_name} - transcript.json (complete API response)
{video_name} - transcript.md (formatted markdown)
{video_name} - word_timings.txt (simple text reference)
Step 2: Video Editing (edit_video_remove_pauses.py)
- Loads word-level transcript from Step 1
- Identifies long pauses between words (> 1.0 seconds by default)
- Identifies Korean filler words (์ด, ์, ์, ์ด, ์ค, ์ )
- Calculates which video segments to keep
- Uses MoviePy for frame-accurate cutting and reassembly
- Generates edited video and detailed report
Conservative Editing Philosophy
This skill uses conservative editing to ensure safe, predictable results:
What Gets Removed
- โ
Long pauses (>1.0 seconds of silence between words)
- โ
Clear filler words: ์ด, ์, ์, ์ด, ์ค, ์ (Korean equivalents of "uh", "um", "ah", etc.)
What Gets Kept
- โ
Context-dependent words: ์ด์ , ๋ญ, ๊ทธ, ์ข, ๋ค, ์ฝ๊ฐ
- These words can be legitimate in Korean speech
- Removing them risks cutting meaningful content
- โ
Short pauses (< 1.0 seconds)
- Natural breathing and thinking pauses
- Important for speech rhythm
Expected Results
- Time saved: 5-10% typically (1-2 minutes per 25-minute video)
- Video segments: 50-100 cuts (manageable, smooth transitions)
- Safety: Very low risk of removing important content
- Quality: Natural-sounding edited video
Usage Guide
Basic Workflow
python transcribe_video.py "my_presentation.mp4"
python edit_video_remove_pauses.py "my_presentation.mp4" --preview
python edit_video_remove_pauses.py "my_presentation.mp4"
Step 1: Transcription Options
python transcribe_video.py "video.mp4"
python transcribe_video.py "video.mp4" --output-dir "transcripts"
python transcribe_video.py "video.mp4" --keep-audio
python transcribe_video.py "video_en.mp4" --language "en"
Transcription outputs (auto-generated in same directory as video):
video - transcript.json (464 KB for 25-min video, ~2,800 words)
video - transcript.md (formatted with timestamps)
video - word_timings.txt (simple reference)
Step 2: Video Editing Options
python edit_video_remove_pauses.py "video.mp4" --preview
python edit_video_remove_pauses.py "video.mp4"
python edit_video_remove_pauses.py "video.mp4" --pause-threshold 0.8
python edit_video_remove_pauses.py "video.mp4" --output "cleaned_video.mp4"
python edit_video_remove_pauses.py "video.mp4" --padding 0.15
python edit_video_remove_pauses.py "video.mp4" --transcript "path/to/transcript.json"
python edit_video_remove_pauses.py "video.mp4" --no-fillers
python edit_video_remove_pauses.py "video.mp4" --output-pauses "video - pauses.json"
Editing outputs:
video - edited.mov (cleaned video)
video - edited_edit_report.txt (detailed report)
Understanding the Edit Report
After editing, you'll receive a detailed report showing exactly what was removed:
============================================================
VIDEO EDIT REPORT (Conservative Mode)
============================================================
SUMMARY
------------------------------------------------------------
Original Duration: 00:25:21.000
Edited Duration: 00:23:16.690
Time Saved: 00:02:04.310 (8.2%)
Segments Kept: 67
PAUSES REMOVED
------------------------------------------------------------
Total Pauses: 43
Total Pause Time: 87.81 seconds
Top 10 Longest Pauses:
1. 5.64s at 00:07:51.500
2. 5.52s at 00:09:21.020
3. 3.54s at 00:00:11.520
...
FILLER WORDS REMOVED (Clear Fillers Only)
------------------------------------------------------------
Total Fillers: 28
Breakdown:
์ด : 25 occurrences
์ : 3 occurrences
SAMPLE EDITS (First 5)
------------------------------------------------------------
1. Pause (3.54s) at 00:00:11.520
2. Pause (1.50s) at 00:00:29.400
3. Filler '์ด' (0.84s) at 00:05:32.140
...
Advanced Usage
Custom Pause Thresholds
Adjust based on your content:
python edit_video_remove_pauses.py "video.mp4" --pause-threshold 0.8
python edit_video_remove_pauses.py "video.mp4" --pause-threshold 2.0
Guidelines:
- 0.5-0.8s: Aggressive, removes more pauses but may feel rushed
- 1.0s (default): Balanced, removes awkward pauses while keeping natural rhythm
- 1.5-2.0s: Very conservative, only removes obvious dead air
Batch Processing Multiple Videos
for video in *.mp4; do
echo "Processing: $video"
python transcribe_video.py "$video"
python edit_video_remove_pauses.py "$video"
done
Preview Before Editing
Always preview first when working with important content:
python transcribe_video.py "important_presentation.mp4"
python edit_video_remove_pauses.py "important_presentation.mp4" --preview
python edit_video_remove_pauses.py "important_presentation.mp4"
File Naming Conventions
The scripts follow consistent naming patterns:
Input:
presentation.mp4 (your original video)
Transcription outputs:
presentation - transcript.json (complete data)
presentation - transcript.md (formatted markdown)
presentation - word_timings.txt (simple reference)
Editing outputs:
presentation - edited.mov (cleaned video)
presentation - edited_edit_report.txt (detailed report)
Technical Details
MoviePy Processing
The editing script uses MoviePy for frame-accurate cutting:
- โ
Precise: Cuts at exact timestamps, not keyframe boundaries
- โ
Accurate: No ยฑ1-2 second drift from keyframe limitations
- โ
Quality: Re-encodes with libx264/AAC for consistent output
- โ ๏ธ Slower: Re-encoding takes more time than codec copy (worth it for accuracy)
Minimum Segment Duration
Segments shorter than 0.1 seconds are automatically filtered out:
- Prevents FFmpeg errors
- Avoids meaningless micro-cuts
- Ensures smooth playback
Word-Level Timestamp Precision
Whisper API provides timestamps accurate to ~0.01 seconds:
- Precise enough for clean cuts between words
- Allows surgical removal of specific words
- Enables accurate pause detection
Cut Parameters: padding & tail_buffer
๋ ํ๋ผ๋ฏธํฐ๋ ์ปท ์ง์ ์ ์ ํ๋๋ฅผ ์กฐ์ ํฉ๋๋ค. Whisper ํ์์คํฌํ๊ฐ ์๋ฒฝํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฒํผ๊ฐ ํ์ํฉ๋๋ค.
gantt
title ์๋ณธ ์ค๋์ค ํ์๋ผ์ธ
dateFormat X
axisFormat %s
section ์๋ณธ
๋จ์ด A :a, 0, 2
ํด์ง (์นจ๋ฌต) :crit, pause, 2, 5
๋จ์ด B :b, 5, 8
flowchart LR
subgraph ์๋ณธ["์๋ณธ ์ค๋์ค"]
direction LR
A["๐ฃ๏ธ ๋จ์ด A<br/>0-2์ด"]
P["๐ ํด์ง<br/>2-5์ด"]
B["๐ฃ๏ธ ๋จ์ด B<br/>5-8์ด"]
A --> P --> B
end
flowchart TB
subgraph params["ํ๋ผ๋ฏธํฐ ์๋ ์๋ฆฌ"]
direction TB
subgraph timeline["ํ์๋ผ์ธ (์ด)"]
direction LR
t0["0"] ~~~ t2["2"] ~~~ t5["5"] ~~~ t8["8"]
end
subgraph original["์๋ณธ"]
direction LR
wordA["๋จ์ด A<br/>0~2์ด"]
pause["ํด์ง<br/>2~5์ด"]
wordB["๋จ์ด B<br/>5~8์ด"]
wordA --> pause --> wordB
end
subgraph cuts["์ปท ํฌ์ธํธ"]
direction LR
tail["โโโ tail_buffer<br/>ํด์ง ์์์ ์<br/>0.15์ด ๋ค๋ก ์ฐ์ฅ"]
pad["padding โโโถ<br/>ํด์ง ๋์ ์์<br/>0.1์ด ๊ฑด๋๋"]
end
subgraph result["ํธ์ง ๊ฒฐ๊ณผ"]
direction LR
keepA["โ
์ ์ง: 0 ~ 2.15์ด<br/>(๋จ์ดA + tail_buffer)"]
remove["โ ์ ๊ฑฐ: 2.15 ~ 5.1์ด"]
keepB["โ
์ ์ง: 5.1 ~ 8์ด<br/>(padding ํ ๋จ์ดB)"]
keepA --> remove --> keepB
end
end
style pause fill:#ffcccc
style remove fill:#ffcccc
style keepA fill:#ccffcc
style keepB fill:#ccffcc
ํ๋ผ๋ฏธํฐ ์์ฝ:
| ํ๋ผ๋ฏธํฐ | ๊ธฐ๋ณธ๊ฐ | ์ญํ | ๊ฐ์ ๋๋ฆฌ๋ฉด |
|---|
--tail-buffer | 0.15์ด | ํด์ง ์์ ์ ์์ฑ ๋ณด์กด | ๋จ์ด ๋๋ถ๋ถ ๋ ๋ณด์กด |
--padding | 0.10์ด | ํด์ง ๋๋ ํ ๊ฑด๋๋ | ๋ ๋ง์ด ์๋ฆผ |
์์ฑ์ด ์๋ฆฌ๋ ๊ฒฝ์ฐ:
- ๋จ์ด ๋์ด ์๋ฆผ โ
--tail-buffer ์ฆ๊ฐ (์: 0.25)
- ๋จ์ด ์์์ด ์๋ฆผ โ
--padding ๊ฐ์ (์: 0.05)
Troubleshooting
"Transcript not found" Error
Error: Transcript not found: video - transcript.json
Solution: Run transcription first or specify transcript location:
python transcribe_video.py "video.mp4"
python edit_video_remove_pauses.py "video.mp4" --transcript "path/to/transcript.json"
"No word-level data found" Error
Solution: Transcript JSON is incomplete or corrupted. Re-run transcription:
python transcribe_video.py "video.mp4"
FFmpeg Not Found
Error: ffmpeg not found
Solution: Install FFmpeg:
- macOS:
brew install ffmpeg
- Linux:
sudo apt install ffmpeg
- Windows: Download from ffmpeg.org
OpenAI API Key Missing
Error: OPENAI_API_KEY environment variable not set
Solution: Set your API key:
export OPENAI_API_KEY="sk-..."
Edited Video Duration Mismatch
With MoviePy frame-accurate editing:
- Duration should match calculated time very closely
- If significantly different, check transcript timestamps
- Re-run transcription if timestamps seem off
Video Quality Issues
If you notice quality degradation:
- Verify original video quality is good
- MoviePy uses libx264/AAC encoding with
preset=fast
- For higher quality, modify script to use
preset=slow
Performance Characteristics
Transcription (Step 1)
- Speed: ~1-2 minutes for 25-minute video
- Cost: ~$0.15 per 25 minutes (OpenAI Whisper pricing)
- Output size: ~500 KB JSON for 25-minute video
Editing (Step 2)
- Speed: ~5-10 minutes for 25-minute video (re-encoding)
- CPU usage: High during encoding (uses 4 threads by default)
- Disk space: ~1.5x original video size during processing
- Output quality: High (libx264 + AAC encoding)
Expected Time Savings
Based on typical Korean presentation videos:
- Conservative mode: 5-10% reduction (1-2 minutes per 25-minute video)
- Longer pauses: Can save 10-15% if speaker has many long pauses
- Professional speakers: May save less (3-5%) due to fewer pauses
Example Workflow
Here's a complete example from start to finish:
ls
python transcribe_video.py "presentation.mp4"
python edit_video_remove_pauses.py "presentation.mp4" --preview
python edit_video_remove_pauses.py "presentation.mp4"
ls
Best Practices
1. Always Preview First
python edit_video_remove_pauses.py "video.mp4" --preview
Review the report before committing to editing.
2. Keep Original Files
Never delete your original video until you've verified the edited version.
3. Test Threshold Settings
Try different --pause-threshold values on a test video to find what works best for your content.
4. Check Audio Quality
Ensure audio is clear before transcription. Whisper works best with:
- Clear speech (not too fast or mumbled)
- Minimal background noise
- Good microphone quality
5. Batch Process Wisely
For multiple videos, process one completely first to verify settings, then batch the rest.
Limitations
What This Skill Cannot Do
- โ Remove background noise or improve audio quality
- โ Fix video quality issues
- โ Remove visual distractions or objects
- โ Auto-detect and remove specific speakers
- โ Add subtitles or captions (use transcript for this separately)
Language Support
- โ
Optimized for Korean: Filler word detection is Korean-specific
- โ ๏ธ English: Works for pauses, but filler words need adjustment
- โ ๏ธ Other languages: Transcription works, but filler detection needs customization
Video Format Compatibility
- โ
Tested: MP4, MOV, AVI, MKV
- โ
Output: MOV format (universally compatible)
- โ ๏ธ Codecs: Best with H.264/AAC, may have issues with exotic codecs
Cost Breakdown
OpenAI Whisper API Costs
- Pricing: $0.006 per minute of audio
- Examples:
- 25-minute video: $0.15
- 1-hour video: $0.36
- 10 videos (25 min each): $1.50
Computing Costs
- Transcription: Minimal (API call only)
- Editing: Minimal (local FFmpeg processing)
- Storage: ~500 KB per 25-minute video (transcript JSON)
Total cost per video: Primarily OpenAI API fees (~$0.006/minute)
Integration with video-add-chapters
This skill can be combined with video-add-chapters for a complete video processing workflow. Use the video-full-process skill for an automated pipeline:
python process_video.py "video.mp4" --language ko
The --output-pauses flag exports pause data in JSON format for chapter timestamp remapping:
{
"pauses": [
{"start": 45.2, "end": 48.5, "duration": 3.3},
{"start": 120.1, "end": 125.8, "duration": 5.7}
],
"total_pause_time": 87.5
}
This data enables accurate chapter remapping after pauses are removed.
Support & Updates
Getting Help
- Check error messages in the edit report
- Review troubleshooting section above
- Verify FFmpeg installation:
ffmpeg -version
- Verify OpenAI API key:
echo $OPENAI_API_KEY
Skill Location
_Settings_/Skills/video-cleaning/
โโโ SKILL.md # This documentation
โโโ README.md # Quick reference
โโโ transcribe_video.py # Step 1: Transcription
โโโ edit_video_remove_pauses.py # Step 2: Editing
Version History
- v2.0 (2026-01): MoviePy migration for frame accuracy
- Replaced FFmpeg codec-copy with MoviePy re-encoding
- Frame-accurate cuts (no keyframe limitations)
- Extended filler words: ์ด, ์, ์, ์ด, ์ค, ์
- Added
--no-fillers option
- Smart tail_buffer for word endings preservation
- v1.0 (2024): Initial conservative mode release
- Removed aggressive and smart clustering modes
- Focused on reliable, predictable editing
- Korean filler word support (์ด, ์, ์)
Quick Reference Card
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ VIDEO CLEANING WORKFLOW - QUICK REFERENCE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ STEP 1: TRANSCRIBE โ
โ python transcribe_video.py "video.mp4" โ
โ โ Creates: video - transcript.json โ
โ โ
โ STEP 2: PREVIEW โ
โ python edit_video_remove_pauses.py "video.mp4" \ โ
โ --preview โ
โ โ Shows: What will be removed โ
โ โ
โ STEP 3: EDIT โ
โ python edit_video_remove_pauses.py "video.mp4" โ
โ โ Creates: video - edited.mov โ
โ โ
โ COMMON OPTIONS: โ
โ --pause-threshold 0.8 Remove pauses > 0.8s โ
โ --padding 0.15 Add 0.15s padding at cuts โ
โ --output "clean.mp4" Custom output path โ
โ --no-fillers Skip filler word removal โ
โ โ
โ WHAT GETS REMOVED: โ
โ โ Pauses > 1.0 seconds โ
โ โ Filler words: ์ด, ์, ์, ์ด, ์ค, ์ โ
โ โ
โ EXPECTED RESULTS: โ
โ โข 5-10% time reduction โ
โ โข 50-100 video segments โ
โ โข Natural-sounding output โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Ready to clean your videos? Start with the basic workflow and adjust settings as needed. Remember: always preview first, and keep your originals safe!