feat(record): fragment the MP4 so a crash cannot destroy the whole take
TASK 32·4. A plain MP4 keeps its index (moov) at the end, so a power cut or a killed process left the entire recording unreadable even though every video byte was on disk. The record block now carries `-movflags +frag_keyframe+empty_moov+default_base_moof`: index first, a playable fragment flushed at every keyframe, so an interrupted take plays to the last fragment. Record block only — the FLV stream output has no index and never gets the flags. Rename-on-stop is untouched. Test: `Args_RecordBlock_IsFragmentedMp4_SoACrashKeepsTheFile` asserts the flags on the record block and their absence from the streaming block. Not yet proven on a real interrupted take (kill ffmpeg mid-recording, play the result); the args test is by construction. Docs: task-32 slice 4 ticked with that caveat, TASKS row, output.md record note, HANDOFF. verify.sh: 550 passed (mouse-injection test excluded, desktop in use), 0 warnings.
This commit is contained in:
+4
-1
@@ -249,7 +249,10 @@ devices, no timers).
|
||||
(Before this wiring the seams defaulted to unity and the controls were decorative.) `StopStream` →
|
||||
`StopLive()` (closes the pipe → ffmpeg audio EOF) **BEFORE** stopping the frame pump (video EOF) —
|
||||
the reverse order stalls on pipe backpressure. `FfmpegEncoder` itself is untouched; the VM owns the
|
||||
pipe lifecycle.
|
||||
pipe lifecycle. **Recordings are fragmented MP4 (TASK 32·4, 2026-11-05):** the record block carries
|
||||
`-movflags +frag_keyframe+empty_moov+default_base_moof`, so the index is written first and a playable
|
||||
fragment is flushed at every keyframe. A plain MP4 puts its index at the end, which is why a power cut
|
||||
or a killed process previously left the whole take unreadable. The FLV stream block never gets it.
|
||||
**Two clip-audio rings join that mix (2026-11-05):** `EnqueueAlertAudio` (TASK 47) is pre-scaled by the
|
||||
alert layer and mixed at **unity, never ducked** — an alert must be heard over the mic.
|
||||
`EnqueueDesktopMediaAudio` (TASK 21's audio slice) is the opposite on purpose: a video layer's
|
||||
|
||||
Reference in New Issue
Block a user