mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 23:03:09 +00:00
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:
co-authored by
Claude Opus 4.8
Xuelong Mu
parent
e812fc8895
commit
36b24acf20
@@ -71,6 +71,7 @@ import { buildDockerRunArgs, resolveDockerPlatform } from "../utils/dockerRunArg
|
||||
import { normalizeErrorMessage } from "../utils/errorMessage.js";
|
||||
import { runEnvironmentChecks } from "../browser/preflight.js";
|
||||
import type { ProducerLogger, RenderJob } from "@hyperframes/producer";
|
||||
import { isVideoFrameFormat, type VideoFrameFormat } from "@hyperframes/engine";
|
||||
import {
|
||||
normalizeResolutionFlag,
|
||||
parseFps,
|
||||
@@ -181,6 +182,14 @@ export default defineCommand({
|
||||
type: "string",
|
||||
description: "GIF loop count, 0 = infinite. Range: 0-65535. Only used with --format gif.",
|
||||
},
|
||||
"video-frame-format": {
|
||||
type: "string",
|
||||
description:
|
||||
"Source video frame extraction format: auto, jpg, png (default: auto). " +
|
||||
"Use png for UI recordings, screen captures, and color-sensitive source videos; " +
|
||||
"alpha-capable sources always extract as PNG.",
|
||||
default: "auto",
|
||||
},
|
||||
workers: {
|
||||
type: "string",
|
||||
alias: "w",
|
||||
@@ -375,6 +384,16 @@ export default defineCommand({
|
||||
}
|
||||
const gifLoop = gifLoopParse.value ?? (format === "gif" ? 0 : undefined);
|
||||
|
||||
const videoFrameFormatRaw = args["video-frame-format"] ?? "auto";
|
||||
if (!isVideoFrameFormat(videoFrameFormatRaw)) {
|
||||
errorBox(
|
||||
"Invalid video-frame-format",
|
||||
`Got "${videoFrameFormatRaw}". Must be auto, jpg, or png.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
const videoFrameFormat = videoFrameFormatRaw;
|
||||
|
||||
// ── Validate resolution ────────────────────────────────────────────────
|
||||
let outputResolution: CanvasResolution | undefined;
|
||||
if (args.resolution !== undefined) {
|
||||
@@ -768,6 +787,7 @@ export default defineCommand({
|
||||
hdrMode: args.sdr ? "force-sdr" : args.hdr ? "force-hdr" : "auto",
|
||||
crf,
|
||||
videoBitrate,
|
||||
videoFrameFormat,
|
||||
quiet,
|
||||
variables,
|
||||
entryFile,
|
||||
@@ -790,6 +810,7 @@ export default defineCommand({
|
||||
hdrMode: args.sdr ? "force-sdr" : args.hdr ? "force-hdr" : "auto",
|
||||
crf,
|
||||
videoBitrate,
|
||||
videoFrameFormat,
|
||||
quiet,
|
||||
browserPath,
|
||||
variables,
|
||||
@@ -825,6 +846,7 @@ interface RenderOptions {
|
||||
hdrMode: "auto" | "force-hdr" | "force-sdr";
|
||||
crf?: number;
|
||||
videoBitrate?: string;
|
||||
videoFrameFormat?: VideoFrameFormat;
|
||||
quiet: boolean;
|
||||
browserPath?: string;
|
||||
variables?: Record<string, unknown>;
|
||||
@@ -1067,6 +1089,7 @@ async function renderDocker(
|
||||
hdrMode: options.hdrMode,
|
||||
crf: options.crf,
|
||||
videoBitrate: options.videoBitrate,
|
||||
videoFrameFormat: options.videoFrameFormat,
|
||||
quiet: options.quiet,
|
||||
variables: options.variables,
|
||||
entryFile: options.entryFile,
|
||||
@@ -1176,6 +1199,7 @@ export async function renderLocal(
|
||||
hdrMode: options.hdrMode,
|
||||
crf: options.crf,
|
||||
videoBitrate: options.videoBitrate,
|
||||
videoFrameFormat: options.videoFrameFormat,
|
||||
variables: options.variables,
|
||||
entryFile: options.entryFile,
|
||||
outputResolution: options.outputResolution,
|
||||
|
||||
Reference in New Issue
Block a user