Goal: a video component's soundtrack reaches the output mix — today only frames are extracted and the audio is silently lost (its volume field is parsed and never read).
Design: during the audio phase, enumerate video components across scenes, compute each one's absolute placement on the output timeline (cumulative scene durations minus incoming transition overlaps, plus start_at), extract audio via ffmpeg (-vn, honoring trim_start/trim_end and playback_rate via -ss/-to/atempo), and feed the result through the existing multi-track mixer (volume, fades). No ffmpeg → skip with a warning (matches the encode fallback philosophy).
Invariants: scenarios without video audio produce byte-identical mixes; the muted case (volume: 0) skips extraction.
Acceptance: a scenario embedding a video with a known tone outputs that tone at the right offset (test with a generated fixture); timeline math unit-tested against transition overlaps.
Verify: cargo test --workspace
Goal: a
videocomponent's soundtrack reaches the output mix — today only frames are extracted and the audio is silently lost (itsvolumefield is parsed and never read).Design: during the audio phase, enumerate video components across scenes, compute each one's absolute placement on the output timeline (cumulative scene durations minus incoming transition overlaps, plus start_at), extract audio via ffmpeg (
-vn, honoring trim_start/trim_end and playback_rate via -ss/-to/atempo), and feed the result through the existing multi-track mixer (volume, fades). No ffmpeg → skip with a warning (matches the encode fallback philosophy).Invariants: scenarios without video audio produce byte-identical mixes; the muted case (
volume: 0) skips extraction.Acceptance: a scenario embedding a video with a known tone outputs that tone at the right offset (test with a generated fixture); timeline math unit-tested against transition overlaps.
Verify: cargo test --workspace