Repository navigation
feat(studio-server): accept crf, videoBitrate, videoFrameFormat and hdrMode on the render route - #5549
Merged
Conversation
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]>
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]>
This was referenced Oct 13, 2026
Contributor
Edit accuracy: accurate 2061 (base branch 2061), smooth 1534 of thoseThe gate passes. Quarantined, measured but not gated (0) Unstable (3)
|
jerrai-bot-heygen
approved these changes
Oct 13, 2026
jerrai-bot-heygen
left a comment
Contributor
There was a problem hiding this comment.
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
3 of 4 tasks
3 of 4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The Studio render route (
POST /projects/:id/render) now accepts the encoder optionshyperframes renderalready has, and both Studio adapters (the CLI'sstudioServer.tsandstudio/vite.adapter.ts) pass them to the render job:crf--crfvideoBitrate--video-bitrate"10M","2500k","8000000"videoFrameFormat--video-frame-formatauto,jpg,pnghdrMode--hdr/--sdrauto,force-hdr,force-sdrWhy
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
helpers/encoderOptions.ts. The route stays lenient aboutquality,fpsandresolutionas before, but an invalid encoder option returns 400, like a malformedvariablespayload, because dropping a value the user chose would render something they did not ask for.crfandvideoBitrateare either/or, matching the CLI's guard; sending both is a 400.crf,videoBitrate) is ignored for mov: ProRes has neither, and the CLI does not apply them.png-sequenceandgifare left out on purpose.png-sequencewrites a directory, and the route's list, serve and delete paths assume one file per render.gifneeds 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/studiochange is three lines invite.adapter.tsthat pass the options to the render job. Studio's UI sends none of them yet, so nothing on screen changes.Test plan
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.tscovers forwarding through the route and 400s that start no render. 63 pass.hyperframes previewfrom this branch on a fixture project and posted renders to the route.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 tohyperframes render --video-bitrate 400kon the same project. The CLI at 50k gave 28,873 bytes.videoBitratewithvideoFrameFormat: "png"andhdrMode: "force-sdr": rendered.crfwithvideoBitrate: 400.hdrMode: "on": 400.tsc --noEmit. fallow audit is clean on the changed files.🤖 Generated with Claude Code