mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 16:42:27 +00:00
feat(producer): optional targetChunkFrames to bound per-chunk frames (#1332)
* feat(producer): optional targetChunkFrames to bound per-chunk frames * feat(cli): expose --target-chunk-frames on lambda + cloudrun render; document it
This commit is contained in:
@@ -162,6 +162,81 @@ describe("resolveChunkPlan", () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ── targetChunkFrames (optional per-chunk frame ceiling) ──
|
||||
|
||||
it("targetChunkFrames omitted is a no-op: identical to the 3-arg auto-sized result", () => {
|
||||
// The default path must be byte-identical whether the 4th arg is absent or
|
||||
// explicitly undefined.
|
||||
for (const totalFrames of [50, 660, 1466, 54000]) {
|
||||
for (const maxParallel of [8, 16, 64]) {
|
||||
const base = resolveChunkPlan(totalFrames, undefined, maxParallel);
|
||||
const withUndef = resolveChunkPlan(totalFrames, undefined, maxParallel, undefined);
|
||||
expect(withUndef).toEqual(base);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("targetChunkFrames collapses a short video to fewer chunks than the parallelism cap", () => {
|
||||
// 1466 frames, target 300, cap 16: ceil(1466/300)=5 chunks (not 16), each
|
||||
// ~293 frames. Fewer chunks → less per-chunk fixed overhead.
|
||||
const result = resolveChunkPlan(1466, undefined, 16, 300);
|
||||
expect(result.chunkCount).toBe(5);
|
||||
expect(result.effectiveChunkSize).toBeLessThanOrEqual(300);
|
||||
});
|
||||
|
||||
it("targetChunkFrames bounds a long video's per-chunk frames, adding chunks up to the cap", () => {
|
||||
// 54000 frames (30 min @30fps), target 1600, cap 64: ceil(54000/1600)=34
|
||||
// chunks, each <= 1600 frames so per-chunk render time stays under budget.
|
||||
const result = resolveChunkPlan(54000, undefined, 64, 1600);
|
||||
expect(result.chunkCount).toBe(34);
|
||||
expect(result.effectiveChunkSize).toBeLessThanOrEqual(1600);
|
||||
});
|
||||
|
||||
it("targetChunkFrames is clamped by maxParallelChunks: an extreme length stays at the cap (still over budget)", () => {
|
||||
// 216000 frames (2 h), target 1600, cap 64: needs 135 chunks but clamps to
|
||||
// 64; per-chunk frames then exceed the target — the genuine tier ceiling.
|
||||
const result = resolveChunkPlan(216000, undefined, 64, 1600);
|
||||
expect(result.chunkCount).toBe(64);
|
||||
expect(result.effectiveChunkSize).toBeGreaterThan(1600);
|
||||
});
|
||||
|
||||
it("explicit chunkSize wins over targetChunkFrames (targetChunkFrames is a no-op)", () => {
|
||||
const withTarget = resolveChunkPlan(54000, 240, 64, 1600);
|
||||
const chunkSizeOnly = resolveChunkPlan(54000, 240, 64);
|
||||
expect(withTarget).toEqual(chunkSizeOnly);
|
||||
});
|
||||
|
||||
it("rejects a non-positive or non-integer targetChunkFrames", () => {
|
||||
expect(() => resolveChunkPlan(1466, undefined, 16, 0)).toThrow(/positive integer/);
|
||||
expect(() => resolveChunkPlan(1466, undefined, 16, -100)).toThrow(/positive integer/);
|
||||
expect(() => resolveChunkPlan(1466, undefined, 16, 300.5)).toThrow(/positive integer/);
|
||||
});
|
||||
|
||||
it("never emits an empty or inverted slice across a grid of targetChunkFrames", () => {
|
||||
for (const totalFrames of [37, 660, 1466, 12793, 54000]) {
|
||||
for (const maxParallel of [8, 16, 64]) {
|
||||
for (const target of [100, 300, 1600]) {
|
||||
const { chunkCount, effectiveChunkSize } = resolveChunkPlan(
|
||||
totalFrames,
|
||||
undefined,
|
||||
maxParallel,
|
||||
target,
|
||||
);
|
||||
expect(chunkCount).toBeGreaterThanOrEqual(1);
|
||||
expect(chunkCount).toBeLessThanOrEqual(maxParallel);
|
||||
const slices = buildChunkSlices(totalFrames, chunkCount, effectiveChunkSize);
|
||||
let cursor = 0;
|
||||
for (const s of slices) {
|
||||
expect(s.startFrame).toBe(cursor);
|
||||
expect(s.endFrame).toBeGreaterThan(s.startFrame);
|
||||
cursor = s.endFrame;
|
||||
}
|
||||
expect(cursor).toBe(totalFrames);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildChunkSlices", () => {
|
||||
|
||||
Reference in New Issue
Block a user