# Video Stitching Strategy Skill ## When to Use Apply this skill when assembling multiple video clips into a unified output: sequential narrative assembly, multi-take compilation, AI-generated clip chaining (e.g., LTX-2 produces max ~8s per clip), or spatial compositions like side-by-side comparisons and picture-in-picture commentary. ## Tools | Tool | Role | |------|------| | `video_trimmer` | Cut segments to precise in/out points, concatenate clips (`concat` operation) | | `video_compose` | Full composition with overlays, subtitles, audio mixing, spatial layouts | | `frame_sampler` | Inspect frames at stitch boundaries for visual continuity | | `audio_mixer` | Mix, duck, and crossfade audio tracks across stitch points | | `scene_detect` | Find natural scene boundaries in source footage | ## When to Stitch — Decision Tree ``` Do you have multiple clips that need to become one video? ├── YES: Are they sequential (play one after another)? │ ├── YES: Are they from the same shoot / same scene? │ │ ├── YES → Multi-take assembly (pick best takes, stitch) │ │ └── NO → Sequential narrative (match cuts, handle transitions) │ └── NO: Do clips need to appear simultaneously on screen? │ ├── YES → Spatial composition (side-by-side, PIP, stack) │ └── MIXED → Hybrid (sequential with spatial inserts) ├── AI-generated clips (LTX-2, CogVideo)? │ └── YES → AI clip chaining (handle 8s boundaries, maintain continuity) └── NO → No stitching needed. Use video_trimmer for single-clip edits. ``` ## Stitch Strategies ### 1. Sequential Stitching Clips play one after another in timeline order. This is the most common strategy. **When:** Narrative videos, multi-section explainers, compiled takes. **Process:** 1. Order clips by narrative sequence (not filename) 2. Trim each clip to precise in/out points via `video_trimmer` (operation: `cut`) 3. Select transition type for each junction (see Transition Selection below) 4. Concatenate via `video_trimmer` (operation: `concat`) for hard cuts, or `video_compose` for transitions requiring filters 5. Verify audio continuity across all stitch points **Audio continuity rules:** - Match audio levels across clips before stitching (normalize to -16 LUFS) - If background music spans multiple clips, mix it as a single track via `audio_mixer` and mux post-concat - Never let music cut abruptly at a stitch point — crossfade or duck instead ### 2. Spatial Stitching Multiple clips visible simultaneously on screen. **When:** Reactions, comparisons, commentary, multi-angle coverage. | Layout | FFmpeg Filter | Use Case | |--------|---------------|----------| | Side-by-side (duet) | `hstack` or `xstack` | Reaction videos, before/after | | Vertical stack | `vstack` or `xstack` | Comparison (top vs bottom) | | Picture-in-picture (PIP) | `overlay=x:y` via `video_compose` | Commentary, webcam + screen | | Grid (2x2, 3x3) | `xstack` with layout string | Multi-angle, compilation | **Spatial layout decision tree:** ``` What relationship do the clips have? ├── Reaction / response → Side-by-side (duet), main clip 70% width ├── Before / after → Side-by-side, equal 50/50 split ├── Comparison (A vs B) → Vertical stack or side-by-side depending on aspect ratio ├── Commentary over content → PIP, speaker in corner (20-25% frame size) ├── Multi-angle same event → Grid layout, synced to same timecode └── Screen recording + face → PIP, face cam in bottom-right corner ``` **PIP placement rules:** - Default position: bottom-right with 20px padding - Size: 20-25% of frame width for commentary, 30-35% for equal importance - Always ensure PIP does not cover critical content (subtitles, key visuals) - Add a 2px border or subtle shadow to separate PIP from background ### 3. AI Clip Chaining (LTX-2 / CogVideo) AI video generators produce short clips (LTX-2: ~8 seconds max). Stitching them into longer sequences requires special care to maintain visual continuity. **Process:** 1. Generate clips with overlapping prompts — last frame description of clip N should match first frame description of clip N+1 2. Use `frame_sampler` to extract the last frame of clip N and first frame of clip N+1 3. Visually inspect the pair for continuity breaks (color shift, subject position, background change) 4. If discontinuity is minor → use a 0.5-1.0s crossfade to smooth the junction 5. If discontinuity is major → insert a fade-through-black (0.5s out + 0.5s in) to signal scene transition 6. After stitching, apply a global color grade to unify the visual tone across clips **AI clip chaining pitfalls:** - AI clips may have inconsistent FPS — normalize all clips to the same FPS before stitching - Color temperature often shifts between generations — apply consistent color grade post-stitch - Motion direction may not match — review last/first frames for jarring movement reversals - Audio (if any) will not be continuous — strip AI audio and use a single music/narration track ### 4. Hybrid Stitching Sequential flow with spatial inserts at specific moments. **When:** Explainer that switches to side-by-side for comparisons, tutorial that shows PIP during demonstrations, documentary with occasional split-screen. **Process:** 1. Plan the timeline: mark which segments are sequential and which are spatial 2. Render each spatial segment as a standalone composed clip via `video_compose` (overlay operation) 3. Treat the rendered spatial clips as regular clips in the sequential stitch 4. Concatenate everything in order using the sequential stitching process ## Transition Selection ### Decision Tree ``` What is the relationship between clip N and clip N+1? │ ├── Same scene, continuous action? │ └── HARD CUT (0ms) │ ├── Same topic, different angle or take? │ └── HARD CUT (0ms) — use J-cut or L-cut for audio smoothing │ ├── Topic change or new section? │ └── CROSSFADE (0.5-1.0s) │ ├── Time passage or mood shift? │ └── CROSSFADE (1.0-1.5s) │ ├── Major section break (intro→body, body→outro)? │ └── FADE THROUGH BLACK (0.5-1.0s) │ ├── Dialogue transition between speakers? │ └── L-CUT or J-CUT (audio leads or trails by 0.3-0.5s) │ └── AI clip boundary (LTX-2 chain)? ├── Continuity is good → HARD CUT or short CROSSFADE (0.3-0.5s) └── Continuity is broken → FADE THROUGH BLACK (0.5s) ``` ### Transition Reference | Transition | Duration | Implementation | Best For | |-----------|----------|----------------|----------| | Hard cut | 0ms | `video_trimmer` concat (codec: copy) | Same scene, fast pace, continuation | | Crossfade | 0.5-1.5s | `video_compose` with `xfade` filter | Topic change, time passage, mood shift | | Fade through black | 0.5-1.0s each | `video_compose`: fade out → black → fade in | Major section break, intro/outro | | L-cut | 0.3-0.5s | Audio from clip N continues into clip N+1's video | Smooth dialogue exit, lingering emotion | | J-cut | 0.3-0.5s | Audio from clip N+1 starts under clip N's video | Dialogue anticipation, building tension | ### Transition Duration by Content Pace | Pacing | Crossfade | Fade Through Black | |--------|-----------|-------------------| | Fast (short-form, < 60s) | 0.3-0.5s | 0.3-0.5s | | Medium (1-10 min) | 0.5-1.0s | 0.5-0.8s | | Slow (documentary, > 10 min) | 1.0-1.5s | 0.8-1.0s | ## Audio Coordination ### Audio at Stitch Points ``` What audio exists at the stitch boundary? │ ├── Both clips have narration/dialogue? │ ├── Hard cut → Ensure no audio pop (cut at zero-crossing or apply 5ms fade) │ ├── Crossfade → Duck outgoing audio -6dB during overlap, bring in incoming │ └── L-cut/J-cut → Blend: outgoing audio fades -∞dB over 0.3-0.5s │ ├── Music spans the stitch? │ ├── Same track continues → Do not re-encode audio; use stream copy │ ├── Track changes → Crossfade music 1.0-2.0s centered on the cut point │ └── Music + narration → Duck music -12dB under narration at all times │ ├── One clip has audio, the other is silent? │ └── Add a 0.3s fade-in/fade-out to avoid abrupt silence transitions │ └── No audio on either clip? └── No audio coordination needed. Add music/narration as a single track post-stitch. ``` ### Audio Level Targets | Content Type | Target LUFS | Headroom | |-------------|-------------|----------| | Narration / dialogue | -16 LUFS | -1 dB true peak | | Background music (under narration) | -28 to -24 LUFS | -1 dB true peak | | Music only (no narration) | -14 LUFS | -1 dB true peak | | Sound effects | -20 LUFS | -1 dB true peak | ## Quality Checklist Before declaring a stitch complete, verify every item: - [ ] **Resolution match:** All input clips have the same resolution (or are scaled to match before stitching) - [ ] **FPS match:** All input clips share the same frame rate (or are conformed with `fps` filter) - [ ] **Aspect ratio consistency:** No mixed 16:9 / 9:16 / 4:3 unless intentional spatial layout - [ ] **Color consistency:** No visible color temperature or exposure jumps at stitch boundaries - [ ] **Audio level consistency:** All clips normalized to target LUFS before stitching - [ ] **No audio pops or clicks:** Stitch points have micro-fades or are at zero-crossings - [ ] **Transition appropriateness:** Transition type matches the content relationship (see decision tree) - [ ] **Total duration check:** Final output duration matches expected sum (accounting for transition overlaps) - [ ] **Codec consistency:** All clips use the same codec to allow stream copy; re-encode only if necessary - [ ] **Playback test:** Scrub through every stitch point in the output and confirm smooth playback ## Common Pitfalls ### Codec Mismatch Causing Full Re-encode **Problem:** Mixing clips encoded with different codecs (e.g., H.264 + H.265) or different encoding parameters forces FFmpeg to re-encode everything during concat. **Solution:** Before stitching, probe all clips with `ffprobe`. If codecs differ, re-encode the minority clips to match the majority codec. This is faster than re-encoding everything. ``` Check: ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate -of csv=p=0 input.mp4 ``` ### Audio Drift in Long Stitches **Problem:** When concatenating many short clips (10+), tiny timing mismatches accumulate, causing audio to drift out of sync by the end. **Solution:** 1. Re-encode each clip with constant frame rate before concatenation (`-vsync cfr`) 2. If using a separate audio track, align it to the final video's duration post-stitch 3. For AI clip chains, use `-async 1` to resync audio on concatenation ### Aspect Ratio Mixing **Problem:** Stitching a 16:9 clip with a 9:16 clip creates letterboxing or stretching. **Solution:** Decide on a target aspect ratio up front. Pad non-conforming clips with black bars (`pad` filter) or crop them (`crop` filter) — never stretch. ### Variable Frame Rate (VFR) Sources **Problem:** Screen recordings and phone footage often use VFR, which causes desync and stuttering when stitched with CFR content. **Solution:** Convert VFR sources to CFR before stitching: `ffmpeg -i vfr_input.mp4 -vsync cfr -r 30 cfr_output.mp4` ### Concatenation with Stream Copy Fails **Problem:** `video_trimmer` concat with `codec: copy` fails or produces glitchy output when clips have different GOP structures or encoding parameters. **Solution:** If stream copy fails, fall back to re-encoding with consistent parameters: `-c:v libx264 -crf 18 -preset medium -c:a aac -b:a 192k` Use CRF 18 (near-lossless) to avoid quality loss from the re-encode. ## Stitch Planning Template When planning a stitch, produce this structure as part of `edit_decisions`: ```yaml stitch_plan: strategy: sequential | spatial | hybrid | ai_chain target_resolution: "1920x1080" target_fps: 30 target_codec: libx264 clips: - id: clip_01 source: "assets/intro.mp4" in_seconds: 0.0 out_seconds: 5.0 transition_out: crossfade transition_duration: 0.8 - id: clip_02 source: "assets/section_1.mp4" in_seconds: 0.0 out_seconds: 8.0 transition_out: hard_cut - id: clip_03 source: "assets/section_2.mp4" in_seconds: 0.0 out_seconds: 8.0 transition_out: fade_black transition_duration: 0.5 audio: narration: "assets/narration_full.wav" music: "assets/bg_music.mp3" music_volume: -24 # LUFS ducking: true spatial_inserts: # Only for hybrid strategy - at_clip: clip_02 at_seconds: 3.0 layout: pip overlay_source: "assets/webcam.mp4" position: bottom_right size_percent: 25 ```