mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
fix(render): reject incomplete captured frames (#2293)
This commit is contained in:
@@ -230,7 +230,7 @@ describe("executeDiskCaptureWithAdaptiveRetry — transient Target-closed single
|
|||||||
|
|
||||||
const writeAllFrames = (framesDir: string, totalFrames: number): void => {
|
const writeAllFrames = (framesDir: string, totalFrames: number): void => {
|
||||||
for (let i = 0; i < totalFrames; i++) {
|
for (let i = 0; i < totalFrames; i++) {
|
||||||
writeFileSync(join(framesDir, formatCaptureFrameName(i, "jpg")), "x");
|
writeFileSync(join(framesDir, formatCaptureFrameName(i, "jpg")), "captured-frame");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1432,7 +1432,10 @@ describe("adaptive missing-frame retry helpers", () => {
|
|||||||
it("finds contiguous missing frame ranges from captured disk frames", () => {
|
it("finds contiguous missing frame ranges from captured disk frames", () => {
|
||||||
const framesDir = makeFramesDir();
|
const framesDir = makeFramesDir();
|
||||||
for (const frameIndex of [0, 1, 4]) {
|
for (const frameIndex of [0, 1, 4]) {
|
||||||
writeFileSync(join(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.jpg`), "x");
|
writeFileSync(
|
||||||
|
join(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.jpg`),
|
||||||
|
"captured-frame",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(findMissingFrameRanges(6, framesDir, "jpg")).toEqual([
|
expect(findMissingFrameRanges(6, framesDir, "jpg")).toEqual([
|
||||||
@@ -1441,6 +1444,18 @@ describe("adaptive missing-frame retry helpers", () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("retries a worker placeholder instead of accepting a truncated sequence", () => {
|
||||||
|
const framesDir = makeFramesDir();
|
||||||
|
for (let frameIndex = 0; frameIndex < 4; frameIndex++) {
|
||||||
|
writeFileSync(
|
||||||
|
join(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.jpg`),
|
||||||
|
frameIndex === 2 ? "x" : "captured-frame",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(findMissingFrameRanges(4, framesDir, "jpg")).toEqual([{ startFrame: 2, endFrame: 3 }]);
|
||||||
|
});
|
||||||
|
|
||||||
it("builds retry batches that cap active workers per attempt", () => {
|
it("builds retry batches that cap active workers per attempt", () => {
|
||||||
const batches = buildMissingFrameRetryBatches(
|
const batches = buildMissingFrameRetryBatches(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -603,7 +603,12 @@ export function findMissingFrameRanges(
|
|||||||
|
|
||||||
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
||||||
const framePath = join(framesDir, formatCaptureFrameName(frameIndex, frameExt));
|
const framePath = join(framesDir, formatCaptureFrameName(frameIndex, frameExt));
|
||||||
const missing = !existsSync(framePath);
|
// A capture worker can leave a zero/one-byte placeholder behind when it
|
||||||
|
// exits between creating the destination and writing the image. FFmpeg's
|
||||||
|
// image2 demuxer treats that as end-of-sequence but still exits 0, which
|
||||||
|
// used to let a truncated video be reported as successful. Real JPEG and
|
||||||
|
// PNG captures are necessarily larger than their 8-byte file signatures.
|
||||||
|
const missing = !existsSync(framePath) || statSync(framePath).size <= 8;
|
||||||
if (missing && rangeStart === null) {
|
if (missing && rangeStart === null) {
|
||||||
rangeStart = frameIndex;
|
rangeStart = frameIndex;
|
||||||
} else if (!missing && rangeStart !== null) {
|
} else if (!missing && rangeStart !== null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user