Skip to content

@remotion/renderer: Render selected frames and ranges - #9888

Merged
JonnyBurger merged 6 commits into
mainfrom
codex/render-selected-frames
Jul 29, 2026
Merged

@remotion/renderer: Render selected frames and ranges#9888
JonnyBurger merged 6 commits into
mainfrom
codex/render-selected-frames

Conversation

@JonnyBurger

@JonnyBurger JonnyBurger commented Jul 29, 2026

Copy link
Copy Markdown
Member

Summary

  • support a unified local --frames selection syntax:
    • --frames=0,30,60 renders the specified frames as an image sequence
    • --frames=0-99,150-199 concatenates the selected ranges into one video
    • adding --sequence renders selected ranges as an image sequence with source-frame filenames
    • mixed selections such as --frames=0,30-59 render a video unless --sequence is set
  • extend local renderFrames() and renderMedia() calls to accept multiple ordered, non-overlapping frame ranges
  • remove skipped video and audio sections from the packed local output timeline
  • keep Lambda, Cloud Run, and distributed combineChunks() rendering single-range so their existing chunking and seamless-AAC behavior is unchanged
  • reject comma-separated selections before invoking Lambda or Cloud Run

Testing

  • bun run build
  • bun run stylecheck
  • focused renderer, CLI, serverless, and serverless-client unit tests
  • public Lambda and Cloud Run rejection tests
  • CLI integration tests for stitched video and source-numbered image sequences
  • local renderMedia() multiple-range integration test
  • red/green verification of the Lambda rejection boundary

Closes #9874
Closes #3158

Preview

@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bugs Ready Ready Preview, Comment Jul 29, 2026 3:09pm
remotion Ready Ready Preview, Comment Jul 29, 2026 3:09pm

Request Review

@JonnyBurger JonnyBurger changed the title @remotion/renderer: Render selected frames @remotion/renderer: npx remotion render --frames supports individual frames Jul 29, 2026

@pullfrog pullfrog Bot 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 changes — adds a frames option to renderFrames() and the CLI for rendering arbitrary comma-separated frame selections as image sequences.

  • Add frames option to renderFrames() — accepts number[], validates/sorts, renders as image sequence with source frame numbers preserved in filenames
  • New FrameSelection type — extends FrameRange with {type: 'frames'; frames: number[]} to represent comma-separated selections
  • CLI --frames comma-parsing--frames=0,42,69 parses to a FrameSelection shape, disables video output, and is gated out of benchmark
  • ValidationvalidateSelectedFrames() enforces array-of-numbers, non-empty, finite, integer, non-negative, in-range, and no duplicates; plugs into both CLI option parsing and the renderer
  • Tests — unit tests for validateSelectedFrames, CLI option parsing updates, integration test for CLI render path, and a renderFrames() integration test
  • Docscli/render.mdx and renderer/render-frames.mdx updated with frames option documentation

Important

The renderFrames() mutual-exclusion check for everyNthFrame will throw when called from the CLI with --frames=... and default --every-nth-frame=1, breaking the CLI render path. This needs a fix before merging.

🚨 renderFrames() throws on everyNthFrame !== undefined even for the default value 1, blocking the CLI render path

The CLI's renderVideoFlow always passes everyNthFrame as a number (typed as everyNthFrame: number in the function signature). In renderFrames(), the mutual-exclusion check at render-frames.ts:767 throws when everyNthFrame !== undefined — but everyNthFrame is never undefined from the CLI because it defaults to 1 before reaching renderVideoFlow.

The CLI check in render.tsx only blocks everyNthFrame !== 1, so the default value 1 passes through. The CLI then calls renderFrames({ frames: selectedFrames, everyNthFrame: 1, ... }), and renderFrames throws because everyNthFrame !== undefined is true.

The CLI integration test (rendering.test.ts:253-298 in the diff) would fail as written because the --frames=8,2,5 invocation would exit non-zero from the renderFrames throw.

Technical details
## Affected sites

- `packages/cli/src/render-flows/render.ts:627` — passes `everyNthFrame,` unconditionally to `renderFrames()`
- `packages/cli/src/render-flows/render.ts:170``everyNthFrame: number` type guarantees it is never `undefined`
- `packages/renderer/src/render-frames.ts:767-771` — throws when `everyNthFrame !== undefined`, treating even the default `1` as conflicting
- `packages/cli/src/render.tsx:137-141` — only blocks `everyNthFrame !== 1`, allowing the default through

## Required outcome

- The CLI render path must not throw when `--frames=0,5` is used without `--every-nth-frame`
- The `renderFrames()` API should still reject explicit `everyNthFrame` values that meaningfully conflict with `frames`

## Suggested approach

In `render-flows/render.ts`, omit `everyNthFrame` from the `renderFrames` call when `selectedFrames` is set:

```typescript
everyNthFrame: selectedFrames !== null ? undefined : everyNthFrame,
```

This avoids the renderer-level check entirely for the CLI path. The renderer's check can remain as-is for direct API callers, since API callers won't normally pass `everyNthFrame: 1` alongside `frames`.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Claude Opus not used — the program covers this model; add its provider key to run your pick) | 𝕏

@JonnyBurger JonnyBurger changed the title @remotion/renderer: npx remotion render --frames supports individual frames @remotion/renderer: Render selected frames and ranges Jul 29, 2026
@JonnyBurger
JonnyBurger merged commit a28333f into main Jul 29, 2026
18 checks passed
@JonnyBurger
JonnyBurger deleted the codex/render-selected-frames branch July 29, 2026 15:09
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.

Agents are running multiple npx remotion still commands in parallel, we should support doing it all at once Rendering with multiple frame ranges

1 participant