| name | create-clips-from-podcast |
| description | extract and re-edit short-form vertical clips from a podcast recording. applies the multicam-podcast-clip archetype — karaoke captions, angle-change cuts on gestural/question beats, cold open mid-sentence. supports two assembly paths: a simple trim-and-caption path for single-camera source, and an EDL-driven cut-rhythm path (generate-edit-decision-list → render-edl) for multi-camera source. |
create-clips-from-podcast
Purpose
Extract high-value moments from a podcast recording and re-edit them into creator-native
short-form vertical clips (IG Reels / TikTok). The archetype is multicam-podcast-clip
(CREATOR_GRAMMAR.md §8): speech-only audio, karaoke-pop captions, and angle-change cuts
placed on gestural emphasis, questions, and punchline beats.
Two assembly paths are supported:
Path A — Simple (single-camera source, default):
Identify the best clip window from the transcript, trim it, resize to 9:16, and add captions.
Fast, no EDL required. Use when only one camera angle is available.
Path B — EDL cut-rhythm (multi-camera source, optional):
Use generate-edit-decision-list in conform mode to plan a cut rhythm that places
angle-change cuts on question/punchline/gestural beats across multiple camera angles, then
assemble with render-edl. Use when two or more locked camera setups exist.
Inputs
| Input | Required | Notes |
|---|
source_video | yes | path to the podcast recording (primary camera / main .mp4). For multi-cam Path B, also provide source_video_b (second angle). |
source_video_b | Path B only | path to the second camera angle recording (same session, different angle) |
target_duration_s | yes | desired clip length in seconds (typical: 25–90 s) |
brand_brief | yes | brand/show name, topic, target audience, platform |
clip_window | no | approximate {start_s, end_s} in the source recording to focus on; omit to let the transcript drive selection |
assembly_path | no | "simple" (default) or "edl". If omitted, auto-selected: "edl" when source_video_b is provided, "simple" otherwise. |
caption_preset | no | preset ID from caption-style-presets.json (default platform-default) |
output_dir | yes | directory for all outputs and the run manifest |
Composed Atoms
skills/atoms/voiceover/transcribe-audio-fal — generate word-timestamps from the recording (required for both paths)
skills/atoms/editing/trim-video-clips — extract the clip window from the source recording (Path A primary; Path B uses EDL trim instead)
skills/atoms/editing/resize-video-aspect-ratio — reframe to 9:16 (both paths, pre-render for Path A; handled by render-edl normalisation for Path B)
skills/atoms/planning/generate-edit-decision-list — produce edl.json in conform mode for the multicam-podcast-clip archetype (Path B only)
skills/atoms/assembly/render-edl — execute the EDL into master.mp4 with angle-change cut rhythm (Path B only)
skills/atoms/captions/add-captions-klap — add karaoke captions to the final clip (both paths)
Workflow
Phase 1 — Prepare inputs
- Confirm
source_video exists on disk. Stop and report if missing.
- Confirm
ffmpeg and ffprobe are installed.
- Create
output_dir/working/ and output_dir/finals/.
- Determine
assembly_path:
- If
assembly_path is explicitly set, use it.
- Otherwise: use
"edl" if source_video_b is provided, "simple" if not.
Phase 2 — Transcribe
Run transcribe-audio-fal on source_video to produce working/words.json. Both paths need
the word-timestamps for clip selection, caption cues, and (in Path B) beat placement.
If transcription fails, stop — word-timestamps are required.
Phase 3 — Select the clip window
Using the word-timestamps (and optionally the provided clip_window), identify a contiguous
segment of up to target_duration_s that contains a complete thought arc: an opening claim or
question, development, and a punchline or payoff. Prioritise segments that open mid-sentence
(cold-open rule, CREATOR_GRAMMAR.md §1).
Record the selected {start_s, end_s} in working/clip-selection.json.
Path A — Simple (single-camera)
Phase 4A — Trim and resize
Run trim-video-clips to extract working/clip-raw.mp4 from the selected window.
Run resize-video-aspect-ratio to produce working/clip-9x16.mp4 (9:16, 1080×1920).
Phase 5A — Captions
Run add-captions-klap on working/clip-9x16.mp4 to produce finals/master.mp4 with
animated karaoke captions. Pass caption_preset (default platform-default).
Proceed to Phase 6 (QC).
Path B — EDL cut-rhythm (multi-camera)
Phase 4B — Generate the EDL (conform mode)
Run generate-edit-decision-list in conform mode with the multicam-podcast-clip archetype.
Pass:
source_files: [source_video, source_video_b]
words_json: working/words.json
target_duration: target_duration_s
source_mode: "conform"
Key behaviors the EDL generator applies for this archetype:
- Angle-change cuts (
transition_in: "angle-change") — placed on question/punchline beats
and gestural emphasis points identified from the transcript and word-timestamp pauses.
The archetype's transition_default is angle-change; every cut to camera B uses this type.
- Cut density target —
cuts_per_10s: {hook: 3, body: 3, tail: 2} per archetypes.json.
Cuts are planned, not automatic: each angle-change cut must fall on a meaningful beat.
- Cold open — the first clip starts mid-sentence (no intro card, no logo bumper).
- Payoff-hold — mark the punchline or most quotable moment as
role: "payoff-hold" (~2×
mean shot length), even though payoff_hold.required: false for this archetype.
- Karaoke captions — per-word cues from word-timestamps, using
caption_preset.
python3 skills/atoms/planning/generate-edit-decision-list/scripts/edl_pacing.py \
--archetype multicam-podcast-clip \
--target-duration <target_duration_s>
Validate: run edl_validate.py on working/edl.json. All nine rules must pass before render.
Phase 5B — Render
Run render-edl:
python3 skills/atoms/assembly/render-edl/scripts/render_edl.py \
--edl <output_dir>/working/edl.json \
--output <output_dir>/finals/master.mp4 \
--crf 18
render-edl normalises to 9:16 (1080×1920) and burns ASS karaoke captions. Skip
add-captions-klap when render-edl's built-in captions suffice.
Proceed to Phase 6 (QC).
Phase 6 — Self-QC and human review (both paths)
- Run
/watch:watch on finals/master.mp4. Do not declare done from a still frame.
- Confirm:
- Opens mid-sentence (cold open, no intro card).
- For Path B: angle-change cuts land on question/punchline/gestural beats, not mid-word.
- Karaoke captions are accurate and readable.
- Duration is within ±0.5 s of
target_duration_s.
- No caption/text collision.
- Write
verification.md to output_dir.
- Write
finals/manifest.json with skill_name, run_id, assembly_path, status, warnings, errors.
Decision Rules
| Decision | Rule |
|---|
| Path selection | Single-camera source → Path A (simple). Multi-camera source (two+ locked angles from the same session) → Path B (EDL). Do not use Path B for single-camera — the angle-change cuts have no second angle to cut to. |
| Angle-change cut placement | Path B: cuts are deliberate, placed on gestural emphasis, question marks, and punchline beats — never on random intervals or mid-sentence. Aim for 3 cuts per 10 s in body (per archetype parameters); do not over-cut. |
| EDL conform vs. generative | Always conform mode for podcast clips; both source video files are existing recordings. |
| Captions | Always add karaoke captions — speech-only clips are built sound-off-first. Path A uses add-captions-klap. Path B uses render-edl's built-in ASS captions by default; switch to add-captions-klap only if the brand's ads demonstrably use Klap-style captions. |
| Payoff-hold | Even though payoff_hold.required: false for this archetype, identify the most quotable moment and mark it as payoff-hold. The pacing curve needs an anchor. |
| Cold open | The first frame must be mid-speech, not a title card or silence. If the selected window starts on a pause, trim forward to the first word. |
| When Path B is not worth it | If the two camera angles are barely distinguishable (same framing, same shot size), fall back to Path A — a planned angle-change cut requires a meaningfully different angle to pay off. |
Output
Path A:
output_dir/finals/master.mp4 — trimmed, 9:16, karaoke-captioned clip.
output_dir/finals/manifest.json — run metadata.
output_dir/working/clip-selection.json — selected window.
output_dir/verification.md — self-QC result.
Path B (all of the above, plus):
output_dir/working/edl.json — validated Edit Decision List.
output_dir/finals/manifest.json — includes pacing_curve, clips_rendered, transitions_logged.
Quality Checks
master.mp4 exists, is non-zero, and ffprobe reports both video and audio streams.
- Duration of
master.mp4 is within ±0.5 s of target_duration_s.
- Resolution is 1080×1920 (9:16).
- Clip opens mid-sentence (no intro card or blank frame at the start).
- Karaoke captions are present and cover every spoken word.
- For Path B:
edl.json passes edl_validate.py (exits 0); at least one clip has
transition_in: "angle-change"; exactly one clip has role: "payoff-hold".
manifest.json exists with status: pass and all required fields.
verification.md documents the watch-through result.
Failure Modes
- Source video missing — stop immediately; report the path.
source_video_b missing for Path B — fall back to Path A and log a warning in the manifest.
- Transcription fails — no word-timestamps means no caption cues or EDL beat placement. Check credentials; do not proceed without
words.json.
- No suitable clip window found — report in
verification.md that no segment met the
target duration with a complete thought arc; ask for a different clip_window hint.
- EDL validator exits non-zero (Path B) — fix all reported errors before rendering. Common issues: non-contiguous timeline, angle-change clips referencing a non-existent second source file, missing payoff-hold.
- Two camera angles indistinguishable — fall back to Path A; document the reason in
manifest.json.
ffmpeg not installed — install via brew install ffmpeg.
- Caption preset not found — falls back to
platform-default with a warning in the manifest.
- Klap API failure — if
add-captions-klap fails (Path A), fall back to burning captions locally using the ASS method and note the fallback in the manifest.