mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(studio-server): the render route passes a MOV ProRes profile to the render (#6644)
* fix(studio-server): the render route passes a MOV ProRes profile to the render * fix(studio-server): drop the added comment line so the comment share does not rise
This commit is contained in:
@@ -41,6 +41,15 @@ describe("parseEncoderOptions", () => {
|
||||
expect(parseEncoderOptions({ hdrMode: "on" }, "mp4").ok).toBe(false);
|
||||
});
|
||||
|
||||
it("takes a ProRes profile for mov only, and rejects an unknown one", () => {
|
||||
expect(parseEncoderOptions({ proresProfile: "hq" }, "mov")).toEqual({
|
||||
ok: true,
|
||||
options: { proresProfile: "hq" },
|
||||
});
|
||||
expect(parseEncoderOptions({ proresProfile: "hq" }, "mp4")).toEqual({ ok: true, options: {} });
|
||||
expect(parseEncoderOptions({ proresProfile: "422hq" }, "mov").ok).toBe(false);
|
||||
});
|
||||
|
||||
it("accepts a keyframe interval and a rate cap for mp4", () => {
|
||||
expect(
|
||||
parseEncoderOptions(
|
||||
|
||||
@@ -2,6 +2,7 @@ const CRF_MAX_BY_FORMAT: Record<string, number> = { mp4: 51, webm: 63 };
|
||||
const VIDEO_BITRATE = /^\d+(\.\d+)?[kKmMgG]?$/;
|
||||
const VIDEO_FRAME_FORMATS = ["auto", "jpg", "png"] as const;
|
||||
const HDR_MODES = ["auto", "force-hdr", "force-sdr"] as const;
|
||||
const PRORES_PROFILES = ["4444", "hq", "422", "lt", "proxy"] as const;
|
||||
|
||||
interface EncoderOptions {
|
||||
gifLoop?: number;
|
||||
@@ -9,6 +10,7 @@ interface EncoderOptions {
|
||||
videoBitrate?: string;
|
||||
videoFrameFormat?: (typeof VIDEO_FRAME_FORMATS)[number];
|
||||
hdrMode?: (typeof HDR_MODES)[number];
|
||||
proresProfile?: (typeof PRORES_PROFILES)[number];
|
||||
keyframeIntervalSeconds?: number;
|
||||
maxBitrate?: string;
|
||||
bufferSize?: string;
|
||||
@@ -20,6 +22,7 @@ export interface EncoderOptionsBody {
|
||||
videoBitrate?: unknown;
|
||||
videoFrameFormat?: unknown;
|
||||
hdrMode?: unknown;
|
||||
proresProfile?: unknown;
|
||||
keyframeIntervalSeconds?: unknown;
|
||||
maxBitrate?: unknown;
|
||||
bufferSize?: unknown;
|
||||
@@ -96,13 +99,23 @@ function parseDelivery(body: EncoderOptionsBody, format: string): Parsed {
|
||||
return { ok: true, options };
|
||||
}
|
||||
|
||||
function parseProres(value: unknown, format: string): Parsed {
|
||||
if (!isSet(value)) return { ok: true, options: {} };
|
||||
if (!oneOf(value, PRORES_PROFILES)) {
|
||||
return { ok: false, error: `proresProfile must be one of ${PRORES_PROFILES.join(", ")}` };
|
||||
}
|
||||
return { ok: true, options: format === "mov" ? { proresProfile: value } : {} };
|
||||
}
|
||||
|
||||
/** Explicit encoder overrides from a render request. MOV (ProRes) takes no rate control. */
|
||||
export function parseEncoderOptions(body: EncoderOptionsBody, format: string): Parsed {
|
||||
const rate = parseRateControl(body, format);
|
||||
if (!rate.ok) return rate;
|
||||
const delivery = parseDelivery(body, format);
|
||||
if (!delivery.ok) return delivery;
|
||||
const options: EncoderOptions = { ...rate.options, ...delivery.options };
|
||||
const prores = parseProres(body.proresProfile, format);
|
||||
if (!prores.ok) return prores;
|
||||
const options: EncoderOptions = { ...rate.options, ...delivery.options, ...prores.options };
|
||||
if (isSet(body.gifLoop)) {
|
||||
if (
|
||||
typeof body.gifLoop !== "number" ||
|
||||
|
||||
@@ -374,6 +374,13 @@ describe("POST /projects/:id/render — crf", () => {
|
||||
expect(both.opts).toBeUndefined();
|
||||
});
|
||||
|
||||
it("forwards a ProRes profile for mov to the render adapter and refuses an unknown one", async () => {
|
||||
expect((await post({ format: "mov", proresProfile: "hq" })).opts.proresProfile).toBe("hq");
|
||||
const unknown = await post({ format: "mov", proresProfile: "422hq" });
|
||||
expect(unknown.res.status).toBe(400);
|
||||
expect(unknown.opts).toBeUndefined();
|
||||
});
|
||||
|
||||
it("forwards the keyframe interval and the rate cap to the render adapter", async () => {
|
||||
const { res, opts } = await post({
|
||||
format: "mp4",
|
||||
|
||||
@@ -183,6 +183,7 @@ export interface StudioApiAdapter {
|
||||
bufferSize?: string;
|
||||
videoFrameFormat?: "auto" | "jpg" | "png";
|
||||
hdrMode?: "auto" | "force-hdr" | "force-sdr";
|
||||
proresProfile?: "4444" | "hq" | "422" | "lt" | "proxy";
|
||||
jobId: string;
|
||||
/**
|
||||
* The triggering browser profile has telemetry disabled (localStorage
|
||||
|
||||
Reference in New Issue
Block a user