← ClaudeAtlas

fill-verticallisted

Reframe a horizontal (16:9) clip to 9:16 (1080x1920) by punching in to FILL the frame — never letterbox, no blur bars. Detects scene cuts and computes ONE static crop box per shot. Clusters face signatures across all shots to find the dominant speaker (storyteller); on multi-face shots it picks the speaker by lip-activity biased toward that identity. A non-speaking reaction/listener shot is framed LOOSER so the short never dwells hero-framed on the wrong person. When FaceLandmarker finds no face it falls to a PERSON tier (MediaPipe Pose) — an action/establishing shot with a human is framed on that person (head on the upper third, punched in) instead of stranding them in dead space; only genuinely person-free footage falls through to the OpenCV-saliency cover crop. Faces are framed ~45% of frame height with the eyeline on the upper third, capped at ~2x upscale. Replaces fit-vertical in the canonical chain.
jperrello/C0BALT_CUT · ★ 2 · Web & Frontend · score 65
Install: claude install-skill jperrello/C0BALT_CUT
# fill-vertical Punch-in 9:16 reframe. Fills 1080x1920 on every shot — the "content" look, not the blurred-letterbox "webinar" look. Runs after `tighten-pace`, before `chunk-captions`/`burn-subtitles`. ## Usage ```bash .claude/skills/fill-vertical/fill-vertical.sh <input> <out> \ [target=1080x1920] [face_frac=0.45] [max_zoom=2.0] [scene_thresh=0.4] [samples=5] ``` - **input** — cut/trimmed/tightened clip (any aspect; designed for 16:9). - **out** — written 1080x1920 mp4, audio stream-copied, duration unchanged, `+faststart`. ## Contract - **In:** one video file. - **Out:** one 1080x1920 mp4. Audio copied from input. Duration preserved. Side artifact `<out>.fillplan.json` records per-shot crop boxes. - **Idempotent:** if `out` is newer than `input`, exits as a cache hit. ## How it works 1. `ffprobe` for source w/h/fps/duration. 2. Scene-cut detect via ffmpeg `select=gt(scene,thresh)` on a downscaled decode → shot list. 3. Per shot: sample `samples` frames, run MediaPipe **FaceLandmarker** (full lip mesh). - Link faces across frames by center proximity → tracks. - **Speaker = track with max mouth-openness variance.** No measurable lip motion → biggest + most-central face. Single face → trivial. - Crop box: chosen face ~`face_frac` of frame height, eyeline on the upper third, centered on the face, clamped to source bounds, capped at `max_zoom`. - **No face → PERSON tier:** run MediaPipe **Pose** (`pose_landmarker.task`, created lazily — onl