Skip to content

@remotion/renderer: Add NVENC hardware encoding for H.264/H.265 on Linux/Windows#7733

Open
willy-scr wants to merge 5 commits into
remotion-dev:mainfrom
willy-scr:nvenc-hardware-encoding
Open

@remotion/renderer: Add NVENC hardware encoding for H.264/H.265 on Linux/Windows#7733
willy-scr wants to merge 5 commits into
remotion-dev:mainfrom
willy-scr:nvenc-hardware-encoding

Conversation

@willy-scr
Copy link
Copy Markdown

@willy-scr willy-scr commented May 28, 2026

Summary

Add NVENC (NVIDIA hardware encoding) support for H.264 and H.265 codecs on Linux and Windows, including FFmpeg encoder availability probing for automatic fallback.

✅ End-to-end verified with NVENC (RTX 4060, Linux)

resolveHardwareAcceleration({codec: 'h264', hardwareAcceleration: 'if-possible'})
  → probes FFmpeg → detects h264_nvenc → returns 'if-possible'
getCodecName({codec: 'h264', hardwareAcceleration: 'if-possible'})
  → selects h264_nvenc
ffmpeg -c:v h264_nvenc -b:v 8M ...
  → valid H.264 video (30 frames) encoded by NVIDIA NVENC ✅

Changes

Core implementation

  • packages/renderer/src/get-codec-name.ts — Added NVENC encoder selection for Linux/Windows
  • packages/renderer/src/probe-encoder.ts — NEW: Encoder availability probing
    • probeEncoderAvailability() — Probes FFmpeg binary for specific encoder
    • resolveHardwareAcceleration() — Resolves effective hw accel setting
  • packages/renderer/src/stitch-frames-to-video.ts — Probes before generating FFmpeg args
  • packages/renderer/src/prespawn-ffmpeg.ts — Same probe for pre-spawn path
  • packages/renderer/src/test/get-codec-name.test.ts — 22 test cases
  • packages/docs/docs/hardware-acceleration.mdx — Updated platforms + prerequisites
  • packages/docs/docs/encoding.mdx — Updated codec tables

Usage

# Graceful: uses NVENC if available, falls back to software if not
npx remotion render MyComp --codec h264 --hardware-acceleration if-possible

# With custom NVENC-capable FFmpeg
npx remotion render MyComp --codec h264 --hardware-acceleration if-possible --binaries-directory /path/to/nvenc-ffmpeg

# Strict: throws clear error if NVENC not available
npx remotion render MyComp --codec h264 --hardware-acceleration required

How it works

  1. Before each render, the renderer probes FFmpeg (ffmpeg -encoders) to check if the selected hw encoder exists
  2. if-possible mode: if encoder missing → silently falls back to software encoding
  3. required mode: if encoder missing → throws clear error
  4. disable mode: no probing, always software

Prerequisites for NVENC

  • NVIDIA GPU (GeForce, Quadro, or Tesla)
  • NVIDIA drivers (525+)
  • FFmpeg compiled with NVENC support (provide via binariesDirectory)

Note: The Remotion-bundled FFmpeg does not include NVENC. With if-possible, the renderer auto-detects this and falls back to software. To use NVENC, provide an NVENC-capable FFmpeg via binariesDirectory. To add NVENC to the bundled FFmpeg, the remotion-dev/rust-ffmpeg-splitter repo needs --enable-nvenc added to its FFmpeg configure flags.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 28, 2026

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

Project Deployment Actions Updated (UTC)
bugs Ready Ready Preview, Comment May 31, 2026 6:50pm
remotion Ready Ready Preview, Comment May 31, 2026 6:50pm

Request Review

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

Important

The docs update introduces a broken markdown code block that will render the rest of the article incorrectly. Please fix before merging.

Reviewed changes — Added NVENC hardware encoding support for H.264/H.265 on Linux/Windows, following the existing VideoToolbox pattern.

  • Add NVENC encoder selection in get-codec-name.ts for h264 and h265 on linux/win32
  • Add 22 test cases in get-codec-name.test.ts covering macOS regression, NVENC on Linux/Windows, unsupported codecs, software fallback, and audio codecs
  • Update docs in hardware-acceleration.mdx and encoding.mdx to reflect NVENC support

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Kimi K2𝕏

```
Encoder: prores_videotoolbox, hardware accelerated: true
```
Encoder: h264_nvenc, hardware accelerated: true
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.

⚠️ The closing code fence (```) was removed here, so the code block is never closed. Everything from this line to the end of the article (including the "See also" section) will be rendered as a code block. Restore the closing fence on its own line after this example.


test('h264 + linux + hwaccel:if-possible + crf=20 falls back to software', () => {
setPlatform('linux');
expect(
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.

ℹ️ The (NEW - will fail) label in the describe block name is a development note that should be removed now that the implementation is in place and these tests pass.

});
});

describe('getCodecName - No hardware acceleration for unsupported codecs', () => {
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.

ℹ️ Same as above — remove the (NEW - will fail) label from the describe block name.

@JonnyBurger
Copy link
Copy Markdown
Member

Quick question about the NVENC setup: When you tested this, did you specify a custom FFmpeg binary via --binaries-directory / binariesDirectory?\n\nI checked the current Remotion-bundled FFmpeg build script and it enables libx264 / libx265, but not h264_nvenc or hevc_nvenc, so I want to confirm whether the successful NVENC path depended on a custom binary.

@willy-scr
Copy link
Copy Markdown
Author

@JonnyBurger Yes, you're correct — the successful NVENC render test used a custom binariesDirectory pointing to the system FFmpeg (which has NVENC). The bundled FFmpeg does not have NVENC yet.

That's exactly why I also opened remotion-dev/rust-ffmpeg-splitter#16 — it adds nv-codec-headers + --enable-encoder=h264_nvenc / --enable-encoder=hevc_nvenc to the FFmpeg build for Linux targets, following the same pattern as VideoToolbox for macOS.

The two PRs work together:

  • This PR — Remotion-side NVENC encoder selection, probing, and graceful fallback
  • rust-ffmpeg-splitter#16 — Bundled FFmpeg build with NVENC support

Once both are merged, NVENC will work out-of-the-box on Linux machines with NVIDIA GPUs. The probing logic (probe-encoder.ts) ensures graceful fallback to libx264 when NVENC isn't available (no GPU, old driver, etc.).

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 31, 2026

Deployment failed with the following error:

The provided GitHub repository does not contain the requested branch or commit reference. Please ensure the repository is not empty.

@JonnyBurger
Copy link
Copy Markdown
Member

@willy-scr I rebuilt the compositor binaries for all platforms with the updated rust-ffmpeg. Could you test this again now without overriding Remotion with a custom FFmpeg binary?

@willy-scr
Copy link
Copy Markdown
Author

@JonnyBurger I tried to test with the bundled FFmpeg, but the current @remotion/compositor-linux-x64-gnu (v4.0.469) doesn't include NVENC encoders — ffmpeg -encoders | grep nvenc returns nothing. The build config shows only --enable-encoder=libx264 etc., no h264_nvenc/hevc_npenc.

Also, the monorepo build is currently broken on main (@remotion/media has Symbol.dispose errors, @remotion/studio-server has missing exports), so I can't run the full CLI to test end-to-end even with a custom FFmpeg.

I verified NVENC works on my RTX 4060 using the system FFmpeg:

ffmpeg -f lavfi -i testsrc=duration=2:size=640x360:rate=30 -c:v h264_nvenc -preset fast test.mp4
→ h264_nvenc ✅ 5.61x realtime
→ hevc_nvenc ✅ 7.12x realtime

Could you confirm: was the new binary with NVENC published to npm? Or does it need a version bump to pull the update?

@JonnyBurger
Copy link
Copy Markdown
Member

No, we're not pushing to npm yet, the idea would be that you check out the PR in it's current state..

If you are getting a build error, it might be a cache issue, try running the clean script and be precise in following the instructions: https://www.remotion.dev/docs/contributing#setup

@willy-scr
Copy link
Copy Markdown
Author

@JonnyBurger I did a clean build (bun run cleanbun installbun run build) but the compositor binary is still v4.0.469 (FFmpeg n7.1) without NVENC encoders.

I also checked the alpha channel (@remotion/compositor-linux-x64-gnu@4.1.0-alpha12) — that one has FFmpeg n6.0, also without NVENC.

The monorepo build errors I'm seeing (@remotion/media Symbol.dispose, @remotion/studio-server missing exports) happen on a clean checkout of this PR branch too, even before my changes. These seem like pre-existing issues on main.

Could you point me to the right binary/version? Or should I wait for the rust-ffmpeg-splitter merge to propagate?

@willy-scr
Copy link
Copy Markdown
Author

@JonnyBurger I did a full clean (bun run cleanrm -rf node_modulesbun install) following the contributing guide exactly.

The compositor binary at packages/compositor-linux-x64-gnu/ is FFmpeg n7.1 but still has no NVENC encoders:

LD_LIBRARY_PATH=packages/compositor-linux-x64-gnu/ packages/compositor-linux-x64-gnu/ffmpeg -encoders | grep nvenc
→ (empty - no nvenc encoders)

The binary's BuildID is 47594a35f1a3d9ec2cc27afab67efca6f493c7f1 — is this the latest one? Could the NVENC rebuild not have been pushed to this branch yet?

@JonnyBurger
Copy link
Copy Markdown
Member

JonnyBurger commented May 31, 2026

@willy-scr the rebuilt binaries are now on this PR branch again at the latest head commit. They are not published to npm, and checking @remotion/compositor-linux-x64-gnu@4.0.469 or the alpha package will not test this change.

Please check out this PR branch itself and test the bundled binary from the workspace, for example:

gh pr checkout 7733
LD_LIBRARY_PATH=packages/compositor-linux-x64-gnu packages/compositor-linux-x64-gnu/ffmpeg -encoders | grep nvenc

Then run your Remotion test without binariesDirectory / custom FFmpeg so we can verify this PR works with the bundled FFmpeg.

a and others added 5 commits June 1, 2026 07:35
…Linux/Windows

- h264 + linux/win32 + hwaccel -> h264_nvenc
- h265 + linux/win32 + hwaccel -> hevc_nvenc
- Follows same pattern as existing macOS VideoToolbox support
- Users need NVIDIA GPU + drivers; FFmpeg fails naturally if unavailable
- Use --video-bitrate for quality control (CRF not supported with hw accel)
- Updated hardware-acceleration and encoding docs
- Added 22 tests covering all encoder selection paths
…eleration

Probe FFmpeg binary for encoder availability before selecting NVENC.
If encoder not available in FFmpeg build:
- 'if-possible' mode: gracefully falls back to software encoding
- 'required' mode: throws clear error message

This handles the case where bundled FFmpeg lacks NVENC support.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@willy-scr willy-scr force-pushed the nvenc-hardware-encoding branch from 6c0f783 to 47a8b9d Compare May 31, 2026 23:36
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