mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +00:00
refactor: dedupe resolution presets and clean up 4k stack
This commit is contained in:
@@ -20,10 +20,10 @@ interface RenderQueueProps {
|
||||
// silently missing dropdown entry. Order is fixed by the array below.
|
||||
const RESOLUTION_LABELS: Record<ResolutionPreset | "auto", { label: string; title: string }> = {
|
||||
auto: { label: "Auto", title: "Render at the composition's authored resolution" },
|
||||
landscape: { label: "1080p", title: "1920×1080 landscape" },
|
||||
landscape: { label: "1080p ↔", title: "1920×1080 landscape" },
|
||||
portrait: { label: "1080p ↕", title: "1080×1920 portrait" },
|
||||
"landscape-4k": {
|
||||
label: "4K",
|
||||
label: "4K ↔",
|
||||
title: "3840×2160 — supersamples a 1080p composition via Chrome DPR. Slower, larger files.",
|
||||
},
|
||||
"portrait-4k": {
|
||||
|
||||
@@ -11,8 +11,20 @@ export interface RenderJob {
|
||||
durationMs?: number;
|
||||
}
|
||||
|
||||
// Mirrors `CanvasResolution` from @hyperframes/core. Kept local because
|
||||
// studio's tsconfig doesn't include node types, and the core barrel
|
||||
// transitively pulls in modules with `node:fs` imports. Drift risk is
|
||||
// low (4 string literals tied to a stable enum).
|
||||
export type ResolutionPreset = "landscape" | "portrait" | "landscape-4k" | "portrait-4k";
|
||||
|
||||
export interface StartRenderOptions {
|
||||
fps?: number;
|
||||
quality?: "draft" | "standard" | "high";
|
||||
format?: "mp4" | "webm" | "mov";
|
||||
/** `"auto"` (default) renders at the composition's authored dimensions. */
|
||||
resolution?: ResolutionPreset | "auto";
|
||||
}
|
||||
|
||||
export function useRenderQueue(projectId: string | null) {
|
||||
const [jobs, setJobs] = useState<RenderJob[]>([]);
|
||||
const eventSourceRef = useRef<EventSource | null>(null);
|
||||
@@ -61,24 +73,24 @@ export function useRenderQueue(projectId: string | null) {
|
||||
|
||||
// Start a render and track progress via SSE
|
||||
const startRender = useCallback(
|
||||
async (
|
||||
fps = 30,
|
||||
quality: "draft" | "standard" | "high" = "standard",
|
||||
format: "mp4" | "webm" | "mov" = "mp4",
|
||||
resolution: ResolutionPreset | "auto" = "auto",
|
||||
) => {
|
||||
async (opts: StartRenderOptions = {}) => {
|
||||
if (!projectId) return;
|
||||
|
||||
const fps = opts.fps ?? 30;
|
||||
const quality = opts.quality ?? "standard";
|
||||
const format = opts.format ?? "mp4";
|
||||
const resolution = opts.resolution;
|
||||
|
||||
const startTime = Date.now();
|
||||
// "auto" means "render at the composition's authored size" — omit the
|
||||
// field entirely so the producer's resolveDeviceScaleFactor returns 1.
|
||||
// Sending the string "auto" would fail the route's validation set.
|
||||
// "auto" / undefined means "render at the composition's authored size".
|
||||
// Omit the field entirely — sending "auto" would trip the route's
|
||||
// enum validation set.
|
||||
const body: { fps: number; quality: string; format: string; resolution?: string } = {
|
||||
fps,
|
||||
quality,
|
||||
format,
|
||||
};
|
||||
if (resolution !== "auto") body.resolution = resolution;
|
||||
if (resolution && resolution !== "auto") body.resolution = resolution;
|
||||
let res: Response;
|
||||
try {
|
||||
res = await fetch(`/api/projects/${projectId}/render`, {
|
||||
|
||||
Reference in New Issue
Block a user