Skip to content

feat(studio-server): accept crf, videoBitrate, videoFrameFormat and hdrMode on the render route - #5549

Merged
jrusso1020 merged 3 commits into
mainfrom
feat/studio-render-crf
Oct 13, 2026
Merged

jrusso1020 merged 3 commits into
mainfrom
feat/studio-render-crf

Conversation

@jrusso1020

@jrusso1020 jrusso1020 commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

What

The Studio render route (POST /projects/:id/render) now accepts the encoder options hyperframes render already has, and both Studio adapters (the CLI's studioServer.ts and studio/vite.adapter.ts) pass them to the render job:

Body field CLI equivalent Values
crf --crf integer, 0 to 51 for mp4, 0 to 63 for webm
videoBitrate --video-bitrate "10M", "2500k", "8000000"
videoFrameFormat --video-frame-format auto, jpg, png
hdrMode --hdr / --sdr auto, force-hdr, force-sdr

Why

The route only forwarded draft / standard / high, so a Studio or desktop export could not ask for what the CLI can. The prompt was film grain: a finish pass needs CRF 12 to keep its grain. On a 10 s 1080p clip with grain, CRF 16 kept about 55% of it and CRF 12 about 95%, at about 12x the file size. So every option is an opt-in override, never a new default.

Related work

The internal desktop app's Export gets a CRF field on top of this route. No Studio UI change here.

How

  • Parsing lives in helpers/encoderOptions.ts. The route stays lenient about quality, fps and resolution as before, but an invalid encoder option returns 400, like a malformed variables payload, because dropping a value the user chose would render something they did not ask for.
  • crf and videoBitrate are either/or, matching the CLI's guard; sending both is a 400.
  • Rate control (crf, videoBitrate) is ignored for mov: ProRes has neither, and the CLI does not apply them.
  • png-sequence and gif are left out on purpose. png-sequence writes a directory, and the route's list, serve and delete paths assume one file per render. gif needs the extension and MIME handling widened at about ten sites across the route and both adapters. Both are better as their own change.

No visible change

The packages/studio change is three lines in vite.adapter.ts that pass the options to the render job. Studio's UI sends none of them yet, so nothing on screen changes.

Test plan

  • Unit tests: encoderOptions.test.ts (empty request, bitrate per format, mov ignore, crf with bitrate rejected, bad bitrates, frame format and HDR pass-through, unknown values rejected). render.test.ts covers forwarding through the route and 400s that start no render. 63 pass.
  • Manual testing performed: ran hyperframes preview from this branch on a fixture project and posted renders to the route.
    • No crf: 98.8 KB. crf: 12: 166.9 KB. crf: 30: 40.9 KB. crf: 99: 400.
    • videoBitrate: "400k" through the route gave 97,790 bytes, byte-identical to hyperframes render --video-bitrate 400k on the same project. The CLI at 50k gave 28,873 bytes.
    • videoBitrate with videoFrameFormat: "png" and hdrMode: "force-sdr": rendered.
    • crf with videoBitrate: 400. hdrMode: "on": 400.
  • Typecheck: studio-server, cli and studio pass tsc --noEmit. fallow audit is clean on the changed files.
  • Comments follow CONTRIBUTING.md "Comments".

🤖 Generated with Claude Code

jrusso1020 and others added 3 commits October 13, 2026 18:54
The Studio render route only forwarded draft/standard/high, so a Studio or
desktop export could not ask for a specific CRF the way `hyperframes render
--crf` can. Film-grain finishing passes need CRF 12 to keep the grain.

The route now takes an optional integer `crf` (0-51 for mp4, 0-63 for webm),
rejects an out-of-range value with 400 instead of dropping it, ignores it for
mov, and both Studio adapters pass it to the render job.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…e on the render route

Same options `hyperframes render` already takes (--video-bitrate,
--video-frame-format, --sdr/--hdr), so Studio callers are not limited to
the quality presets. crf and videoBitrate are an either/or, matching the CLI;
an invalid value is a 400. Parsing moves to helpers/encoderOptions.ts.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@jrusso1020 jrusso1020 changed the title feat(studio-server): accept a crf override on the render route feat(studio-server): accept crf, videoBitrate, videoFrameFormat and hdrMode on the render route Oct 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 2061 (base branch 2061), smooth 1534 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

Unstable (3)

  • nudge-idle-px-r30-root-z50: tracking 0.01, pressJump -, drop 0, reload 0.07, render 0.03, renderKey -, undo false, teleport true / tracking 0.01, pressJump -, drop 0, reload 0.07, render 0.03, renderKey -, undo true, teleport true / tracking 0.01, pressJump -, drop 0, reload 0.07, render 0.03, renderKey -, undo true, teleport true
  • nudge-keys-px-r0-nested-z100-mid: tracking 3.99, pressJump -, drop 4.02, reload 4.02, render 0.03, renderKey 0.03, undo false, teleport true / tracking 0.01, pressJump -, drop 0, reload 0, render 0.03, renderKey 0.03, undo true, teleport true / tracking 0.01, pressJump -, drop 0, reload 0, render 0.03, renderKey 0.03, undo true, teleport true
  • crop-none-px-r0-nested-z200: tracking 0.02, pressJump 0, drop 40.03, reload 40.05, render 40.03, renderKey -, undo true, teleport true / tracking 0.02, pressJump 0, drop 0.04, reload 0.06, render 0.03, renderKey -, undo true, teleport true / tracking 0.02, pressJump 0, drop 0.04, reload 0.06, render 0.03, renderKey -, undo true, teleport true

@jerrai-bot-heygen jerrai-bot-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact ae2af4be: the Studio route validates the new explicit encoder overrides before job creation, returns 400 for malformed accepted-format options, and both adapters forward parsed values. MOV rate controls are deliberately ignored by this route (the CLI rejects them), so do not describe that as CLI-identical validation. Producer/Studio/unit/Windows checks and preflight executed green at review; no actual film-grain comparison was independently reproduced. — Jerrai

@jrusso1020
jrusso1020 added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit ab8a4da Oct 13, 2026
90 of 103 checks passed
@jrusso1020
jrusso1020 deleted the feat/studio-render-crf branch October 13, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants