| name | create-jump-cuts |
| description | remove pauses and dead air from a talking-head clip by detecting silence gaps and deleting them, producing a tighter re-encoded video. Use when you have a raw UGC or talking-head take and want creator-native breath-removal pacing — either from word-timestamp JSON (transcribe-audio-fal output shape) or via automatic ffmpeg silencedetect. |
create-jump-cuts
Purpose
Remove inter-word and inter-sentence pauses from a talking-head clip so the delivery is tight and creator-native. Gaps above a configurable threshold are deleted; a small pad of audio/video is kept around each speech segment to preserve natural sentence starts and endings. The result is a re-encoded single video with all keep-segments concatenated.
This is the jump-cut transition type described in CREATOR_GRAMMAR.md §3 — the standard breath-removal edit for the creator-talking-head archetype.
Inputs
Workflow
- Verify
ffmpeg and ffprobe are on PATH.
- Build speech segments:
--words mode: merge consecutive word timestamps where inter-word gap ≤ gap-threshold into contiguous speech blocks. Apply pad to each block's start/end (clamped to clip bounds).
--auto mode: run ffmpeg -af silencedetect=noise=-35dB:d=<gap-threshold> on the source, parse silence_start / silence_end lines from stderr, invert to get speech segments. Apply pad.
- If no speech segments are found, copy source to output unchanged and write manifest with a warning.
- For each keep-segment: trim with
ffmpeg -ss <start> -i <source> -t <dur> -c:v libx264 -crf <crf> -preset fast -pix_fmt yuv420p -c:a aac -b:a 192k.
- Write an ffmpeg concat list (
concat.txt) and run ffmpeg -f concat -safe 0 -i concat.txt -c copy to join.
- Clean up temporary segment files.
- Write
manifest.json to the same directory as --output listing every removed range and total time removed.
Run:
python3 skills/atoms/editing/create-jump-cuts/scripts/jump_cut.py \
--source /path/to/raw.mp4 \
(--words /path/to/words.json | --auto) \
--output /path/to/tight.mp4 \
[--gap-threshold 0.35] [--pad 0.08] [--crf 18]
Output
<output>.mp4 — re-encoded video with pauses removed.
manifest.json (same directory as output) — includes:
skill_name, run_id, input_path, output_files, provider, model_or_tool, created_at, duration_seconds, status, warnings, errors
removed_ranges — array of {start, end, duration_s} for every deleted gap
total_removed_seconds — sum of all removed gap durations
source_duration_seconds — original clip length
output_duration_seconds — final clip length
Quality Checks
- Output file exists and is non-zero size.
ffprobe confirms output is playable H.264/yuv420p.
- Output duration ≈ source duration minus
total_removed_seconds (±0.3s tolerance for pad/encode rounding).
manifest.json lists all removed ranges and the total savings.
- No speech content is cut — only silence/pause gaps above threshold.
- If
--words is provided, every word boundary is preserved within pad tolerance.
Failure Modes
ffmpeg / ffprobe not installed — install via brew install ffmpeg.
- Source missing or unreadable — script exits with clear error before processing.
- No silence detected (
--auto mode on a clip with no pauses) — output equals source; manifest records warning, status pass.
- Mutually exclusive flags both provided (
--words + --auto) — script exits with argument error.
- Corrupt or empty words JSON — script exits with clear parse error.
- Concat step fails — individual segment files are left in place for debugging; manifest records error.
- Very short source (<1s) — processed normally; output may equal source if no gaps found.