feat: add video frame format render option (#1481)

* feat: add video frame format render option

* refactor: single source of truth for video-frame-format allow-list

Addresses PR review (Via) on #1481: the ["auto","jpg","png"] set was
declared three times — render.ts (VIDEO_FRAME_FORMATS), server.ts
(inline includes), and renderConfigValidation.ts
(ALLOWED_VIDEO_FRAME_FORMATS) — three boundaries to update when a new
extraction format lands.

Hoist the constant + a reusable `isVideoFrameFormat` type guard into
@hyperframes/engine (where VideoFrameFormat is defined) and route all
three call sites through them. Behavior unchanged; also drops two
`as RenderConfig[...]` casts in favor of the guard (narrowing over
assertion, per repo TS conventions).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Xuelong Mu <xuelongmu@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
James Russo
2026-06-15 22:05:20 -07:00
committed by GitHub
co-authored by Claude Opus 4.8 Xuelong Mu
parent e812fc8895
commit 36b24acf20
18 changed files with 392 additions and 17 deletions
@@ -168,6 +168,7 @@ describe("buildDockerRunArgs", () => {
hdrMode: "force-hdr",
crf: 16,
videoBitrate: undefined,
videoFrameFormat: "png",
quiet: true,
entryFile: "compositions/intro.html",
},
@@ -181,6 +182,8 @@ describe("buildDockerRunArgs", () => {
expect(args).toContain("8");
expect(args).toContain("--crf");
expect(args).toContain("16");
expect(args).toContain("--video-frame-format");
expect(args).toContain("png");
expect(args).toContain("--quiet");
expect(args).toContain("--gpu");
expect(args).toContain("--no-browser-gpu");
@@ -224,6 +227,27 @@ describe("buildDockerRunArgs", () => {
expect(args).not.toContain("--crf");
});
it("forwards --video-frame-format to the container when set to png", () => {
const args = buildDockerRunArgs({
...FIXED_INPUT,
options: { ...BASE, videoFrameFormat: "png" },
});
expect(args).toContain("--video-frame-format");
expect(args).toContain("png");
});
it("omits --video-frame-format when it is auto or unset", () => {
expect(buildDockerRunArgs({ ...FIXED_INPUT, options: BASE })).not.toContain(
"--video-frame-format",
);
expect(
buildDockerRunArgs({
...FIXED_INPUT,
options: { ...BASE, videoFrameFormat: "auto" },
}),
).not.toContain("--video-frame-format");
});
it("forwards --variables JSON to the container when set", () => {
const args = buildDockerRunArgs({
...FIXED_INPUT,