Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/packages/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -496,13 +496,15 @@ This is suppressed in CI environments, non-TTY shells, and when `HYPERFRAMES_NO_
| `--format` | mp4, webm, mov | mp4 | Output format (WebM/MOV render with transparency) |
| `--fps` | 24, 30, 60 | 30 | Frames per second |
| `--quality` | draft, standard, high | standard | Encoding quality preset (drives CRF/bitrate) |
| `--crf` | 0-51 | — | Override encoder CRF (lower = higher quality). Mutually exclusive with `--video-bitrate` |
| `--video-bitrate` | e.g. `10M`, `5000k` | — | Target video bitrate. Mutually exclusive with `--crf` |
| `--hdr` | — | off | Detect HDR sources and output HDR10 (H.265 10-bit, BT.2020 PQ/HLG). MP4 only. SDR-only compositions are unaffected. See [HDR Rendering](/guides/hdr) |
| `--workers` | 1-8 | 4 | Parallel render workers |
| `--gpu` | — | off | GPU encoding (NVENC, VideoToolbox, VAAPI) |
| `--docker` | — | off | Use Docker for [deterministic rendering](/concepts/determinism) |
| `--quiet` | — | off | Suppress verbose output |

CRF and target bitrate are now driven by `--quality`. For programmatic renders, `RenderConfig.crf` and `RenderConfig.videoBitrate` still accept overrides.
CRF and target bitrate default to the `--quality` preset. Use `--crf` or `--video-bitrate` for fine-grained overrides; `RenderConfig.crf` and `RenderConfig.videoBitrate` accept the same overrides programmatically.

#### WebM with Transparency

Expand Down
29 changes: 26 additions & 3 deletions packages/producer/src/services/renderOrchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,26 @@ export async function executeRenderJob(
const encoderHdr = hasHdrContent ? effectiveHdr : undefined;
const preset = getEncoderPreset(job.config.quality, outputFormat, encoderHdr);

// CLI overrides (--crf, --video-bitrate) flow through job.config and must
// win over the preset-derived defaults. The CLI enforces mutual exclusivity
// upstream, but we still resolve them defensively. Without this, the flags
// are silently ignored at the encoder spawn sites below — see PR #268 which
// dropped the prior baseEncoderOpts wiring.
//
// Programmatic callers can construct RenderConfig directly and bypass the
// CLI's mutual-exclusivity guard. If both are set we honor crf (matches the
// CLI semantics where --crf is the explicit override) and warn loudly so
// the caller doesn't get a quietly-different bitrate than they passed in.
if (job.config.crf != null && job.config.videoBitrate) {
log.warn(
`[Render] Both crf=${job.config.crf} and videoBitrate=${job.config.videoBitrate} were set. ` +
`These are mutually exclusive; honoring crf and ignoring videoBitrate. ` +
`Set only one to silence this warning.`,
);
}
const effectiveQuality = job.config.crf ?? preset.quality;
const effectiveBitrate = job.config.crf != null ? undefined : job.config.videoBitrate;

job.framesRendered = 0;

// ── HDR z-ordered multi-layer compositing ──────────────────────────────
Expand Down Expand Up @@ -1316,7 +1336,8 @@ export async function executeRenderJob(
height,
codec: preset.codec,
preset: preset.preset,
quality: preset.quality,
quality: effectiveQuality,
bitrate: effectiveBitrate,
pixelFormat: preset.pixelFormat,
hdr: preset.hdr,
rawInputFormat: "rgb48le",
Expand Down Expand Up @@ -2033,7 +2054,8 @@ export async function executeRenderJob(
height,
codec: preset.codec,
preset: preset.preset,
quality: preset.quality,
quality: effectiveQuality,
bitrate: effectiveBitrate,
pixelFormat: preset.pixelFormat,
useGpu: job.config.useGpu,
imageFormat: captureOptions.format || "jpeg",
Expand Down Expand Up @@ -2259,7 +2281,8 @@ export async function executeRenderJob(
height,
codec: preset.codec,
preset: preset.preset,
quality: preset.quality,
quality: effectiveQuality,
bitrate: effectiveBitrate,
pixelFormat: preset.pixelFormat,
useGpu: job.config.useGpu,
hdr: preset.hdr,
Expand Down
Loading