docmontage: end-tag overlay default + Chirp 3 HD as default TTS voice

End-tag now composited over final body footage (ProRes 4444 with alpha)
instead of concatenated as a black card. Updated idea-director,
edit-director, compose-director, and pipeline manifest with overlay-first
instructions. Default Google TTS voice changed from Neural2-D to
Chirp3-HD-Orus across tool code and docs.
This commit is contained in:
calesthio
2026-04-11 21:38:36 -07:00
parent a8d1ebdf6f
commit cf3527fbbe
8 changed files with 171 additions and 30 deletions
@@ -142,13 +142,12 @@ and L-cut sfx layers. Your job is to execute them faithfully:
Do NOT add ambient noise "to fill the gap".
### 4b. Render The End-Tag Via Remotion, Concatenate After Body
### 4b. Render The End-Tag Via Remotion
The end-tag is rendered **separately** from the FFmpeg body and
concatenated at the tail. This is deliberate — it sidesteps the
`video_compose.render` scene-adapter mismatch and keeps the two
render engines (FFmpeg for footage, Remotion for typography) cleanly
separated.
The end-tag is rendered **separately** from the FFmpeg body via
Remotion. This keeps the two render engines (FFmpeg for footage,
Remotion for typography) cleanly separated. The compositing method
depends on `brief.metadata.end_tag_plan.mode`.
Read `brief.metadata.end_tag_plan`:
@@ -158,19 +157,79 @@ Read `brief.metadata.end_tag_plan`:
"palette": "warm_ivory_on_black",
"duration_seconds": 5.5,
"render_engine": "remotion",
"component": "EndTag"
"component": "EndTag",
"mode": "overlay"
}
```
Execution path:
#### Path A — Overlay Mode (default)
The tag fades in over the final scenes of the body footage. This is
the default and produces a more cinematic result — the typography
appears on top of live footage rather than cutting to a black card.
**Execution:**
1. Compose the body via FFmpeg (cuts + LUT + music + silence window).
Save as `projects/<name>/renders/body.mp4`.
2. Render the end-tag via Remotion CLI with component-specific props:
`npx remotion render EndTag --props='{"text":"...", "palette":"...","durationInFrames":132}' projects/<name>/renders/end_tag.mp4`
Save as `projects/<name>/renders/body.mp4`. Note the body fps.
2. Compute `durationInFrames = round(duration_seconds × body_fps)`.
3. Render the end-tag with alpha via Remotion CLI:
```bash
npx remotion render src/index.tsx EndTagOverlay \
projects/<name>/renders/end_tag_overlay.mov \
--codec=prores --prores-profile=4444 \
--pixel-format=yuva444p10le --image-format=png \
--props='{"text":"...","palette":"...","overlay":true,
"fadeInSeconds":1.0,"holdSeconds":3.0,"fadeOutSeconds":1.5}'
```
Use the `EndTagOverlay` composition with `overlay: true`. This
produces a ProRes 4444 MOV with a real alpha channel
(pix_fmt=yuva444p12le). Canvas must match body canvas.
4. Compute the overlay offset:
- Read `edit_decisions.end_tag.offset_seconds` if present.
- Otherwise auto-compute: `offset = body_duration - tag_duration`.
The tag's fade-out should align with the body's closing fade-out.
5. Composite via FFmpeg overlay with `-itsoffset`:
```bash
ffmpeg -y \
-i body.mp4 \
-itsoffset {offset} -i end_tag_overlay.mov \
-filter_complex "[0:v][1:v]overlay=0:0:format=auto:eof_action=pass[v]" \
-map "[v]" -map "0:a" \
-c:v libx264 -preset medium -crf 18 -pix_fmt yuv420p \
-c:a aac -b:a 192k \
projects/<name>/renders/final.mp4
```
`eof_action=pass` means the body video continues after the overlay
ends. The overlay's own alpha handles the fade-in/hold/fade-out.
**Verification:** Extract a frame from the overlay region (e.g.
`offset + 2s`) and confirm text is visible over footage, not over
black. If the frame shows a black background behind the text, the
alpha channel was lost — re-render with `--image-format=png`.
#### Path B — Concat Mode
Classic tail-card: opaque black card appended after the body. Use
this only when `end_tag_plan.mode == "concat"`.
**Execution:**
1. Compose the body as above.
2. Render the end-tag as opaque MP4:
```bash
npx remotion render src/index.tsx EndTag \
projects/<name>/renders/end_tag.mp4 \
--props='{"text":"...","palette":"...","durationInFrames":132}'
```
(5.5s at 24fps = 132 frames). Canvas must match body canvas.
3. Concat body + end_tag with `ffmpeg -f concat -safe 0 -i list.txt -c copy final.mp4`
or, if encoders don't match, re-encode with the documentary spec.
3. Concat body + end_tag:
```bash
ffmpeg -f concat -safe 0 -i list.txt -c copy final.mp4
```
Or re-encode if codecs don't match.
#### Common Rules (Both Modes)
**End-tag is MANDATORY.** The ONLY way to skip it is an explicit user
opt-out recorded as `end_tag_plan: null` with an `end_tag_opt_out_reason`.
@@ -179,7 +238,9 @@ a contract violation. Stop and surface before finalizing.
Record in `render_report`:
- `end_tag_rendered: true | false`
- `end_tag_path: "projects/<name>/renders/end_tag.mp4"`
- `end_tag_mode: "overlay" | "concat"`
- `end_tag_path: "projects/<name>/renders/end_tag_overlay.mov"` (or `.mp4` for concat)
- `end_tag_offset_seconds: <number>` (overlay mode only)
- `end_tag_text: "..."` (for audit trail)
If the brief says "no music" and the edit correctly has no music
@@ -225,6 +225,32 @@ by layering the outgoing clip's audio as an SFX entry in
Documentary montages with L-cuts feel 50% more coherent than ones
without. Use them on the 3-4 hardest transitions in the piece.
### 8b. Place The End-Tag Overlay
If `brief.metadata.end_tag_plan.mode == "overlay"` (the default), the
end-tag will be composited on top of the final body footage at compose
time. The edit director's job is to decide **when** the tag appears.
Compute the offset: `offset_seconds = body_duration - tag_duration`.
This makes the tag's fade-out align with the body's closing fade-out
(the last cut's `transition_out: fade_out`). If the final cut's hold
is shorter than the tag duration, start the tag earlier so it overlaps
the second-to-last cut as well — this is fine and often looks better.
Record in `edit_decisions.end_tag`:
```json
{
"end_tag": {
"offset_seconds": 84.5,
"notes": "Tag starts at body_duration - tag_duration. Aligns tag fade-out with final cut fade-out."
}
}
```
If `mode == "concat"`, omit this section — the compose-director will
append the tag after the body without needing a timing offset.
### 9. Emit The Edit Decisions
Canonical shape for this pipeline:
@@ -266,6 +292,10 @@ Canonical shape for this pipeline:
"ducking": false
}
},
"end_tag": {
"offset_seconds": 84.5,
"notes": "Tag starts at body_duration - tag_duration. Aligns tag fade-out with final cut fade-out."
},
"metadata": {
"pipeline": "documentary-montage",
"tone": "elegiac",
@@ -95,7 +95,14 @@ defer this — it becomes an expensive surprise at the asset stage.
Every documentary-montage film closes on a philosophical end-tag — one
short, abstract line that gives the whole thing meaning. It is rendered
as a Remotion end-card ("shining underlined tag" register — bold weight,
letter-spaced, animated underline) and concatenated after the last clip.
letter-spaced, animated underline).
**Default mode is `"overlay"`** — the tag fades in over the final scenes
of the body footage, so it feels like part of the film rather than a
separate card tacked on at the end. The alternative is `"concat"` which
appends a standalone black-card after the body. Use concat only when the
user explicitly asks for a separated title card, or when the final
footage is too visually busy for legible text overlay.
**End-tag is MANDATORY.** The ONLY way out is an explicit user opt-out
recorded as `end_tag_plan: null` with an `end_tag_opt_out_reason` field.
@@ -110,12 +117,26 @@ Expected shape:
"palette": "warm_ivory_on_black",
"duration_seconds": 5.5,
"render_engine": "remotion",
"component": "EndTag"
"component": "EndTag",
"mode": "overlay"
}
}
```
Keep the copy to 3-9 words. It must be a thesis, not a summary.
Fields:
- `text` — 3-9 words. A thesis, not a summary.
- `palette``"cool_offwhite_on_black"` or `"warm_ivory_on_black"`.
- `duration_seconds` — total tag screen time (fade-in + hold + fade-out).
5-8s is the sweet spot.
- `render_engine` — always `"remotion"`.
- `component` — always `"EndTag"`.
- `mode``"overlay"` (default) or `"concat"`.
- **overlay**: tag rendered as ProRes 4444 with alpha → composited on
final body footage via FFmpeg overlay filter. Tag fades appear over
the last N seconds of live footage. The body's own fade-out and the
tag's fade-out should align.
- **concat**: tag rendered as opaque MP4 → appended after body via
FFmpeg concat. Total output duration = body + tag.
### 6. Note Narration Intent (OPTIONAL)