diff --git a/packages/engine/src/services/videoFrameExtractor.test.ts b/packages/engine/src/services/videoFrameExtractor.test.ts index 513dee00a1..7e5dbf0e25 100644 --- a/packages/engine/src/services/videoFrameExtractor.test.ts +++ b/packages/engine/src/services/videoFrameExtractor.test.ts @@ -2238,6 +2238,30 @@ describe.skipIf(!HAS_FFMPEG)("extractAllVideoFrames on a VFR source", () => { ).toBe(false); }, 60_000); + it("keeps a finite SDR past-EOF slot in a mixed HDR timeline", async () => { + const SDR_SHORT = await synthCfrClip("sdr-past-eof.mp4", 1); + const HDR_SHORT = await synthHdrTaggedClip("hdr-past-eof-peer.mp4", 1); + const outputDir = join(FIXTURE_DIR, "out-hdr-past-eof"); + mkdirSync(outputDir, { recursive: true }); + + const result = await extractAllVideoFrames( + [ + cfrClipElement("sdr-past-eof", SDR_SHORT, 4, 5), + { ...cfrClipElement("hdr-peer", HDR_SHORT, 1), start: 1, end: 2 }, + ], + FIXTURE_DIR, + { fps: 30, outputDir }, + ); + + // The SDR slot must survive the mixed-HDR preflight and use the held-tail + // path. Reverting its guard to `mediaStart >= playableDuration` records an + // out-of-range error here and drops the slot before extraction. + expect(result.errors).toEqual([]); + expect(result.phaseBreakdown.hdrPreflightCount).toBe(1); + expect(extractedFor(result, "sdr-past-eof").totalFrames).toBe(1); + expect(extractedFor(result, "hdr-peer").totalFrames).toBeGreaterThan(0); + }, 60_000); + it("keeps SDR→HDR cache entries distinct from plain SDR entries", async () => { const CACHE_DIR = mkdtempSync(join(tmpdir(), "hf-extract-hdr-cache-test-")); const SDR = await synthCfrClip("cache-hdr-sdr.mp4", 1); diff --git a/packages/lint/src/project.test.ts b/packages/lint/src/project.test.ts index 8a2ec42468..7c7159cb1b 100644 --- a/packages/lint/src/project.test.ts +++ b/packages/lint/src/project.test.ts @@ -655,10 +655,9 @@ describe("video_media_start_at_or_past_eof", () => { `); - mockExecFile.mockImplementation((_file, _args, _options, callback) => { - callback(new Error("ffprobe failed"), Buffer.alloc(0), Buffer.alloc(0)); - return new ChildProcess(); - }); + // Every locally addressable source receives a successful duration probe; + // each listed attribute/path boundary, not a probe failure, must exclude it. + mockDurationProbe(2); expect(await mediaStartFindings(project)).toEqual([]); });