From f7d6d348ddfa6de2aebe89b0ae911a0569a43396 Mon Sep 17 00:00:00 2001 From: willy-scr Date: Thu, 28 May 2026 13:29:47 +0800 Subject: [PATCH 1/4] Add NVENC (h264_nvenc, hevc_nvenc) encoder support for Linux builds --- compile-ffmpeg.mjs | 8 ++++++++ compile-nvenc.mjs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 compile-nvenc.mjs diff --git a/compile-ffmpeg.mjs b/compile-ffmpeg.mjs index 3e5b8e6..9745c6d 100644 --- a/compile-ffmpeg.mjs +++ b/compile-ffmpeg.mjs @@ -12,6 +12,7 @@ import { enableAv1 } from "./compile-av1.mjs"; import { enableFdkAac } from "./compile-fdkaac.mjs"; import { enableZimg } from "./compile-zimg.mjs"; import { fixLinuxLinks } from "./fix-linux-links.mjs"; +import { enableNvencHeaders } from "./compile-nvenc.mjs"; if (existsSync("/opt/homebrew/opt/libx11/lib/libX11.6.dylib")) { console.log( @@ -137,6 +138,7 @@ enableX264(isMusl, isWindows); enableX265(isMusl, isWindows, isOldCmake); enableLibMp3Lame(isWindows); enableOpus(isWindows); +enableNvencHeaders(isWindows); const TAG = "n7.1"; @@ -288,6 +290,12 @@ execSync( process.platform === "darwin" ? "--enable-encoder=prores_videotoolbox" : null, + !isWindows && process.platform === "linux" + ? "--enable-encoder=h264_nvenc" + : null, + !isWindows && process.platform === "linux" + ? "--enable-encoder=hevc_nvenc" + : null, "--disable-muxers", "--enable-muxer=webm,opus,mp4,wav,mp3,mov,matroska,hevc,h264,gif,image2,image2pipe,adts,m4a,mpegts,null,avi", "--enable-libx264", diff --git a/compile-nvenc.mjs b/compile-nvenc.mjs new file mode 100644 index 0000000..48d8152 --- /dev/null +++ b/compile-nvenc.mjs @@ -0,0 +1,33 @@ +import { execSync } from "child_process"; +import { existsSync } from "fs"; +import { PREFIX } from "./const.mjs"; + +const NV_CODEC_HEADERS_TAG = "n12.2.16.0"; + +export const enableNvencHeaders = (isWindows) => { + // Only install on native Linux builds (not macOS, not Windows cross-compile) + // nv-codec-headers are header-only - no runtime dependency at build time + if (process.platform !== "linux" || isWindows) return; + + if (!existsSync("nv-codec-headers")) { + execSync( + "git clone https://github.com/FFmpeg/nv-codec-headers.git", + {stdio: "inherit"}, + ); + } + + execSync("git fetch --all --tags", { + cwd: "nv-codec-headers", + stdio: "inherit", + }); + + execSync(`git checkout ${NV_CODEC_HEADERS_TAG}`, { + cwd: "nv-codec-headers", + stdio: "inherit", + }); + + execSync(`make install PREFIX=${PREFIX}`, { + cwd: "nv-codec-headers", + stdio: "inherit", + }); +}; From 886e05b34abeb0db2b3d672a82c4782e3e640f84 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Sun, 31 May 2026 12:13:34 +0200 Subject: [PATCH 2/4] Update nv-codec-headers tag Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- compile-nvenc.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compile-nvenc.mjs b/compile-nvenc.mjs index 48d8152..6709be7 100644 --- a/compile-nvenc.mjs +++ b/compile-nvenc.mjs @@ -2,7 +2,7 @@ import { execSync } from "child_process"; import { existsSync } from "fs"; import { PREFIX } from "./const.mjs"; -const NV_CODEC_HEADERS_TAG = "n12.2.16.0"; +const NV_CODEC_HEADERS_TAG = "n12.2.72.0"; export const enableNvencHeaders = (isWindows) => { // Only install on native Linux builds (not macOS, not Windows cross-compile) From 90f568ff103aa58fa0ff2299a0d490e1b7050cd5 Mon Sep 17 00:00:00 2001 From: JonnyBurger Date: Mon, 1 Jun 2026 09:58:02 +0200 Subject: [PATCH 3/4] Fix nv-codec-headers install prefix so FFmpeg actually finds ffnvcodec The previous `make install PREFIX=remotion` ran with cwd=nv-codec-headers, so headers were installed into nv-codec-headers/remotion/, not the top-level ./remotion/ that FFmpeg's PKG_CONFIG_PATH points at. As a result pkg-config could not find ffnvcodec.pc and FFmpeg silently disabled h264_nvenc and hevc_nvenc with: WARNING: Disabled h264_nvenc_encoder because not all dependencies are satisfied: nvenc WARNING: Disabled hevc_nvenc_encoder because not all dependencies are satisfied: nvenc Use an absolute install prefix so the headers land where FFmpeg looks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- compile-nvenc.mjs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compile-nvenc.mjs b/compile-nvenc.mjs index 6709be7..a2bd2a4 100644 --- a/compile-nvenc.mjs +++ b/compile-nvenc.mjs @@ -1,3 +1,4 @@ +import path from "path"; import { execSync } from "child_process"; import { existsSync } from "fs"; import { PREFIX } from "./const.mjs"; @@ -26,7 +27,12 @@ export const enableNvencHeaders = (isWindows) => { stdio: "inherit", }); - execSync(`make install PREFIX=${PREFIX}`, { + // Install into the shared top-level PREFIX dir so FFmpeg's PKG_CONFIG_PATH + // (which points at /remotion/lib/pkgconfig) can find ffnvcodec.pc. + // Using a relative PREFIX here would install into nv-codec-headers/remotion + // and FFmpeg would silently disable h264_nvenc / hevc_nvenc. + const installPrefix = path.join(process.cwd(), PREFIX); + execSync(`make install PREFIX=${installPrefix}`, { cwd: "nv-codec-headers", stdio: "inherit", }); From 2425ee2ad23e350a41bcb97e704565d2f675ad42 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 2 Jun 2026 15:47:15 +0200 Subject: [PATCH 4/4] Adjust NVENC gating for Windows and ARM64 Enable NVENC on Windows cross-builds while excluding Linux ARM64 targets so ARM artifacts stay smaller. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- compile-ffmpeg.mjs | 12 +++++------- compile-nvenc.mjs | 49 +++++++++++++++++++++------------------------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/compile-ffmpeg.mjs b/compile-ffmpeg.mjs index 9745c6d..876bbb1 100644 --- a/compile-ffmpeg.mjs +++ b/compile-ffmpeg.mjs @@ -129,6 +129,8 @@ const isLambdaTarget = !isMusl && !isWindows; const shouldEnableAv1Encoder = !isLambdaTarget; +const shouldEnableNvenc = + process.platform === "linux" && (isWindows || process.arch !== "arm64"); await enableFdkAac(isWindows); enableAv1({ isWindows, enableEncoder: shouldEnableAv1Encoder }); @@ -138,7 +140,7 @@ enableX264(isMusl, isWindows); enableX265(isMusl, isWindows, isOldCmake); enableLibMp3Lame(isWindows); enableOpus(isWindows); -enableNvencHeaders(isWindows); +enableNvencHeaders(shouldEnableNvenc); const TAG = "n7.1"; @@ -290,12 +292,8 @@ execSync( process.platform === "darwin" ? "--enable-encoder=prores_videotoolbox" : null, - !isWindows && process.platform === "linux" - ? "--enable-encoder=h264_nvenc" - : null, - !isWindows && process.platform === "linux" - ? "--enable-encoder=hevc_nvenc" - : null, + shouldEnableNvenc ? "--enable-encoder=h264_nvenc" : null, + shouldEnableNvenc ? "--enable-encoder=hevc_nvenc" : null, "--disable-muxers", "--enable-muxer=webm,opus,mp4,wav,mp3,mov,matroska,hevc,h264,gif,image2,image2pipe,adts,m4a,mpegts,null,avi", "--enable-libx264", diff --git a/compile-nvenc.mjs b/compile-nvenc.mjs index a2bd2a4..c48db37 100644 --- a/compile-nvenc.mjs +++ b/compile-nvenc.mjs @@ -5,35 +5,30 @@ import { PREFIX } from "./const.mjs"; const NV_CODEC_HEADERS_TAG = "n12.2.72.0"; -export const enableNvencHeaders = (isWindows) => { - // Only install on native Linux builds (not macOS, not Windows cross-compile) - // nv-codec-headers are header-only - no runtime dependency at build time - if (process.platform !== "linux" || isWindows) return; +export const enableNvencHeaders = (shouldEnableNvenc) => { + if (!shouldEnableNvenc) { + return; + } - if (!existsSync("nv-codec-headers")) { - execSync( - "git clone https://github.com/FFmpeg/nv-codec-headers.git", - {stdio: "inherit"}, - ); - } + if (!existsSync("nv-codec-headers")) { + execSync("git clone https://github.com/FFmpeg/nv-codec-headers.git", { + stdio: "inherit", + }); + } - execSync("git fetch --all --tags", { - cwd: "nv-codec-headers", - stdio: "inherit", - }); + execSync("git fetch --all --tags", { + cwd: "nv-codec-headers", + stdio: "inherit", + }); - execSync(`git checkout ${NV_CODEC_HEADERS_TAG}`, { - cwd: "nv-codec-headers", - stdio: "inherit", - }); + execSync(`git checkout ${NV_CODEC_HEADERS_TAG}`, { + cwd: "nv-codec-headers", + stdio: "inherit", + }); - // Install into the shared top-level PREFIX dir so FFmpeg's PKG_CONFIG_PATH - // (which points at /remotion/lib/pkgconfig) can find ffnvcodec.pc. - // Using a relative PREFIX here would install into nv-codec-headers/remotion - // and FFmpeg would silently disable h264_nvenc / hevc_nvenc. - const installPrefix = path.join(process.cwd(), PREFIX); - execSync(`make install PREFIX=${installPrefix}`, { - cwd: "nv-codec-headers", - stdio: "inherit", - }); + const installPrefix = path.join(process.cwd(), PREFIX); + execSync(`make install PREFIX=${installPrefix}`, { + cwd: "nv-codec-headers", + stdio: "inherit", + }); };