fix(alerts): wire the frame-rate probe so alert-clip VIDEO paces to real time
The 12:35 live session proved the decoder healthy (frames=240 audioChunks=156 failed=False both clips, alert audio in the mix at peakMix 0.277→0.733) yet the creator still saw 'no video plays / you lost the video'. Root cause: pacing, not decode. AlertClipDecoderFor built the decoder with no frameRateProbe, so RunAsync computed frameDuration = TimeSpan.Zero and RunVideoAsync's pace step was dead code — all 240 frames of the 10s clip dumped through the pipe in the first ~1-2s (130MB as fast as ffmpeg read), then the box froze on the LAST frame while audio chunk-paced its real-time ~7.8s. Reads exactly like a dead decoder on screen. The media path already wired this seam (MainViewModel.cs:308); the alert factory never supplied one. Derivative fix (media/decoder plumbing, cited in broad consensus of players): pass FfmpegFrameRateProbe into the per-play alert decoder exactly like MediaVideoSource does. Good Dog: AlertClipDecoderTests.AlertClipDecoder_PacesVideoFramesToTheProbedFrameRate — real AlertClipDecoder via the fake-process/fake-probe/delay-recorder seam; red on the old factory (zero pacing delays), green with the probe (one ~10ms delay per frame at 100fps). Full suite 321/322, one known-env flake (RealMouseDrag reorder). Docs in this commit: task-47 addendum, MyMistakes.md (a decoder that drops data faster than wall-clock looks identical to a dead one), HANDOFF rewrite.
This commit is contained in:
@@ -109,9 +109,15 @@ public partial class MainViewModel : ViewModelBase
|
||||
|
||||
/// <summary>One decoder per play (the refcounted MediaVideoSourceManager sessions
|
||||
/// can't restart per replay). The clip is full-box in video + 48k stereo audio;
|
||||
/// both steams pace themselves to real time inside the decoder.</summary>
|
||||
/// both steams pace themselves to real time inside the decoder — the frame-rate
|
||||
/// probe is what makes the VIDEO pace (without it every frame dumps in ~1-2s and
|
||||
/// the box freezes on the last frame for the rest of the audio).</summary>
|
||||
private IAlertClipDecoder AlertClipDecoderFor(string path, int width, int height) =>
|
||||
new AlertClipDecoder(path, width, height, new FfmpegLocator(), () => new FfmpegDecodeProcess());
|
||||
new AlertClipDecoder(
|
||||
path, width, height,
|
||||
new FfmpegLocator(),
|
||||
() => new FfmpegDecodeProcess(),
|
||||
frameRateProbe: new FfmpegFrameRateProbe(new FfmpegLocator(), () => new FfmpegDecodeProcess()));
|
||||
|
||||
/// <summary>Stamp the shipped llama placeholder into the Asset table at startup
|
||||
/// (idempotent — hash-keyed UpsertAsset dedupes). Best-effort: if it fails the
|
||||
|
||||
Reference in New Issue
Block a user