Chunking v2: keep clips that span a chunk boundary (overlap + seek)
v1 dropped any overlay video or audio clip whose start fell outside a chunk's window, so a multi-slide background video — or looping background music — silently vanished from every chunk after the one it started in, diverging from a full render. v2 includes any clip that OVERLAPS the window and seeks into clips that began earlier so they resume mid-clip at the seam instead of restarting: - _extract_video_events: overlap test + VideoEvent.skip_override (loop-aware phase); the input -ss also seeks the clip's embedded audio (tvaud). - _extract_audio_events: overlap test + AudioEvent.src_offset (loop phase / linear); renderer honors it in the loop-with-pauses, standard-loop, and one-shot paths. - _chunk_boundary_span_warnings downgraded from "will be dropped" to informational. Full (non-chunked) render is unchanged: time_range=None leaves skip_override/ src_offset at defaults. Slides already used overlap; outros are last-chunk-only. Plan-level checks in tests/test_chunking_v2.py (all green). Remaining gate: render- seam frame/phase validation on the rig; crossfade-loop audio seek deferred. See docs/chunking_v2.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+25
-12
@@ -1,6 +1,9 @@
|
||||
# Chunked Rendering v2 — Design Spec
|
||||
|
||||
Status: **planned** (v1 shipped; v1 boundary limitation is detected + warned, not yet fixed)
|
||||
Status: **implemented on branch `chunking-v2`, pending render-seam validation on the rig.**
|
||||
Plan-level logic is covered by `tests/test_chunking_v2.py` (all green). What remains
|
||||
is confirming the ffmpeg concat seam is frame/phase-accurate on a real render — see
|
||||
"Concat-seam correctness" below.
|
||||
|
||||
## Why chunking exists
|
||||
|
||||
@@ -113,16 +116,26 @@ via `skip_override`. Validation plan:
|
||||
|
||||
## Work items
|
||||
|
||||
- [ ] `_extract_video_events`: overlap test + `skip_override` (loop-aware).
|
||||
- [ ] `_extract_audio_events`: add `end_time`/`skip_override`, overlap + seek.
|
||||
- [ ] `AudioEvent`: `skip_override` field; renderer audio path honors it.
|
||||
- [ ] `OutroEvent`: same treatment.
|
||||
- [ ] Frame/audio seam-diff test (chunked vs full) in the test suite.
|
||||
- [ ] Flip `_chunk_boundary_span_warnings` from "will be dropped" to a debug-only
|
||||
assertion once v2 is the default.
|
||||
- [x] `_extract_video_events`: overlap test + `skip_override` (loop-aware).
|
||||
- [x] `_extract_audio_events`: overlap + `src_offset` seek (loop phase / linear).
|
||||
- [x] `AudioEvent`: `src_offset` field; renderer audio paths (loop-with-pauses,
|
||||
standard loop, one-shot) honor it.
|
||||
- [x] `VideoEvent.skip_override`: renderer video input `-ss` honors it; the clip's
|
||||
embedded audio (`tvaud`) is seeked automatically by the same input seek.
|
||||
- [x] `_chunk_boundary_span_warnings`: downgraded from the "will be dropped" v1
|
||||
warning to an informational note (logged; terminal only under `--verbose`).
|
||||
- [x] Plan-level tests: `tests/test_chunking_v2.py`.
|
||||
- [ ] **Render-seam validation on the rig** (chunked-vs-full frame/audio diff) — the
|
||||
remaining gate before making v2 the trusted default.
|
||||
- [ ] Crossfade-loop audio (`_build_crossfade_loop_filter`) does not yet apply
|
||||
`src_offset` — a crossfaded looping bed restarts phase at the seam. Standard
|
||||
(non-crossfade) loops and one-shots are handled. Low priority.
|
||||
- [ ] `OutroEvent`: not needed — outros are extracted for the last chunk only
|
||||
(`config.outro if is_last_chunk`), so they never split across a seam.
|
||||
|
||||
## Seams already in place (v2 preparations, shipped)
|
||||
## Not affected (verified)
|
||||
|
||||
- `VideoEvent.skip_override` (models.py) — inert; renderer honors it when set.
|
||||
- `cli._chunk_boundary_span_warnings` — detection + warning.
|
||||
- v1-limitation comments at both filter sites in `transformer.py`.
|
||||
- Slides: `_extract_slide_events` already used overlap+clamp — no change.
|
||||
- Full-screen `plan.background`: a separate always-included input.
|
||||
- Full (non-chunked) render: `time_range=None` path leaves `skip_override`/
|
||||
`src_offset` at their defaults, so output is byte-identical to before.
|
||||
|
||||
Reference in New Issue
Block a user