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
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ env:
FORCE_COLOR: 1
jobs:
build:
name: Build on macOS M1
runs-on: macos-13-xlarge
name: Build on macOS ARM64
runs-on: macos-15
steps:
- uses: actions/checkout@main
- uses: actions/setup-node@v3
Expand All @@ -19,7 +19,7 @@ jobs:
- name: Install deps
run: HOMEBREW_INSTALL_FROM_API=1 brew install yasm nasm pkg-config cmake make meson ninja libtool autoconf automake
- run: curl https://sh.rustup.rs -sSf | sh -s -- -y
- run: rm /opt/homebrew/opt/libx11/lib/libX11.6.dylib
- run: rm -f /opt/homebrew/opt/libx11/lib/libX11.6.dylib
- run: node clean.mjs
- run: node compile-ffmpeg.mjs
- run: node generate-bindings.mjs
Expand All @@ -32,7 +32,7 @@ jobs:
path: ffmpeg.tar.gz
build-macos-x64:
name: Build on macOS x64
runs-on: macos-13
runs-on: macos-15-intel
steps:
- uses: actions/checkout@main
- uses: actions/setup-node@v3
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ out-test.png
out-test.jpeg
opus-1.3.1
av1
aom
aom-build
zimg
fdk-aac-2.0.2
fdkaac.tar.gz
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile-aws
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RUN amazon-linux-extras install epel python3.8 -y
RUN python3.8 -m pip install meson
RUN python3.8 -m pip install ninja
RUN yum install yasm nasm unzip curl gcc gcc-c++ tar git make ca-certificates pkgconfig bash make cmake3 build-base llvm-static llvm-dev clang-static clang-dev perl zlib zlib-devel clang-libs clang ninja autoconf automake libtool patchelf -y
RUN cd app && CFLAGS="$CFLAGS -static-libgcc" CXXFLAGS="$CXXFLAGS -static-libgcc -static-libstdc++" LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++" node compile-ffmpeg.mjs old-cmake || tail -n 30 ffmpeg/ffbuild/config.log
RUN cd app && CFLAGS="$CFLAGS -static-libgcc" CXXFLAGS="$CXXFLAGS -static-libgcc -static-libstdc++" LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++" node compile-ffmpeg.mjs old-cmake
RUN source "$HOME/.cargo/env" && cd app && node generate-bindings.mjs
RUN source "$HOME/.cargo/env" && cd app && node zip.mjs
RUN source "$HOME/.cargo/env" && cd app && node test-ffmpeg.mjs
Expand Down
2 changes: 2 additions & 0 deletions clean.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const paths = [
path.join(process.cwd(), "x264"),
path.join(process.cwd(), "x265"),
path.join(process.cwd(), "av1"),
path.join(process.cwd(), "aom"),
path.join(process.cwd(), "aom-build"),
path.join(process.cwd(), "zimg"),
path.join(process.cwd(), "opus"),
path.join(process.cwd(), "libmp3lame"),
Expand Down
126 changes: 124 additions & 2 deletions compile-av1.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
import { execSync } from "child_process";
import { join, dirname } from "node:path";
import { existsSync, mkdirSync, rmSync, cpSync, writeFileSync } from "node:fs";
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import { PREFIX } from "./const.mjs";

export const enableAv1 = (isWindows) => {
const getCmakeCommand = () => {
try {
execSync("cmake --version", { stdio: "ignore" });
return "cmake";
} catch {
try {
execSync("cmake3 --version", { stdio: "ignore" });
return "cmake3";
} catch {
throw new Error("Neither cmake nor cmake3 is available in PATH.");
}
}
};

const getToolPath = (tool) => {
try {
return execSync(`command -v ${tool}`, {
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
}).trim();
} catch {
throw new Error(`Required tool '${tool}' is not available in PATH.`);
}
};

const enableDav1d = (isWindows) => {
const pkgConfig = `
prefix=${process.cwd()}/av1/build
includedir=$\{prefix\}/include
Expand Down Expand Up @@ -61,3 +87,99 @@ Cflags: -I$\{prefix\}/src -I$\{srcdir\}/src -I$\{prefix\} -I$\{srcdir\} -I$\{pre

writeFileSync(outPath, pkgConfig);
};

const enableLibaom = (isWindows) => {
const AOM_TAG = "v3.9.1";
const AOM_BUILD_DIR = "aom-build";
const shouldEnableNasm = !(
process.platform === "darwin" &&
process.arch === "x64"
);
const windowsToolchain = isWindows
? {
cc: getToolPath("x86_64-w64-mingw32-gcc"),
cxx: getToolPath("x86_64-w64-mingw32-g++"),
rc: getToolPath("x86_64-w64-mingw32-windres"),
ar: getToolPath("x86_64-w64-mingw32-ar"),
ranlib: getToolPath("x86_64-w64-mingw32-ranlib"),
}
: null;
if (!existsSync("aom")) {
execSync("git clone https://aomedia.googlesource.com/aom aom", {
stdio: "inherit",
});
}

execSync("git fetch --tags", {
cwd: "aom",
stdio: "inherit",
});

execSync(`git checkout ${AOM_TAG}`, {
cwd: "aom",
stdio: "inherit",
});

rmSync(AOM_BUILD_DIR, {
force: true,
recursive: true,
});
mkdirSync(AOM_BUILD_DIR, {
recursive: true,
});

const cmakeCmd = getCmakeCommand();
execSync(
[
cmakeCmd,
join(process.cwd(), "aom"),
`-DCMAKE_INSTALL_PREFIX=${join(process.cwd(), "aom", PREFIX)}`,
"-DCMAKE_INSTALL_LIBDIR=lib",
"-DCMAKE_BUILD_TYPE=MinSizeRel",
"-DBUILD_SHARED_LIBS=OFF",
"-DENABLE_TESTS=0",
"-DENABLE_TESTDATA=0",
"-DENABLE_DOCS=0",
"-DENABLE_EXAMPLES=0",
"-DENABLE_TOOLS=0",
`-DENABLE_NASM=${shouldEnableNasm ? "1" : "0"}`,
"-DCONFIG_PIC=1",
"-DCMAKE_POSITION_INDEPENDENT_CODE=ON",
"-DCONFIG_AV1_DECODER=0",
"-DCONFIG_AV1_ENCODER=1",
"-DCONFIG_AV1_HIGHBITDEPTH=0",
isWindows ? "-DCMAKE_SYSTEM_NAME=Windows" : null,
isWindows ? `-DCMAKE_C_COMPILER=${windowsToolchain.cc}` : null,
isWindows ? `-DCMAKE_CXX_COMPILER=${windowsToolchain.cxx}` : null,
isWindows ? `-DCMAKE_RC_COMPILER=${windowsToolchain.rc}` : null,
isWindows ? `-DCMAKE_AR=${windowsToolchain.ar}` : null,
isWindows ? `-DCMAKE_RANLIB=${windowsToolchain.ranlib}` : null,
]
.filter(Boolean)
.join(" "),
{
cwd: AOM_BUILD_DIR,
stdio: "inherit",
}
);

execSync("make", {
cwd: AOM_BUILD_DIR,
stdio: "inherit",
});

execSync("make install", {
cwd: AOM_BUILD_DIR,
stdio: "inherit",
});

execSync("cp -r " + PREFIX + " ../", {
cwd: "aom",
stdio: "inherit",
});
};

export const enableAv1 = (isWindows) => {
enableDav1d(isWindows);
enableLibaom(isWindows);
};
11 changes: 9 additions & 2 deletions compile-ffmpeg.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ if (existsSync("/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib")) {
const decoders = [
"aac",
"ac3",
"av1",
"flac",
"h264",
"hevc",
Expand Down Expand Up @@ -197,6 +196,11 @@ const extraLdFlags = [

execSync("cp -r remotion ffmpeg", { stdio: "inherit" });

const pkgConfigDirs = [
path.join(process.cwd(), PREFIX, "lib", "pkgconfig"),
path.join(process.cwd(), PREFIX, "lib64", "pkgconfig"),
];

execSync(
[
path.posix.join(process.cwd().replace(/\\/g, "/"), "ffmpeg", "configure"),
Expand All @@ -213,6 +217,7 @@ execSync(
"--enable-small",
"--enable-shared",
"--enable-libdav1d",
"--enable-libaom",
"--enable-libzimg",
"--enable-libfdk-aac",
"--disable-static",
Expand Down Expand Up @@ -250,6 +255,7 @@ execSync(
"--enable-filter=tonemap",
"--enable-filter=copy",
"--disable-doc",
"--disable-debug",
"--enable-gpl",
"--enable-nonfree",
"--disable-encoders",
Expand All @@ -262,6 +268,7 @@ execSync(
"--enable-encoder=pcm_s24le",
"--enable-encoder=libx264",
"--enable-encoder=libx265",
"--enable-encoder=libaom-av1",
"--enable-libvpx",
"--enable-encoder=libvpx_vp8",
"--enable-encoder=libvpx_vp9",
Expand Down Expand Up @@ -295,7 +302,7 @@ execSync(
{
env: {
...process.env,
PKG_CONFIG_PATH: path.join(process.cwd(), PREFIX) + "/lib/pkgconfig",
PKG_CONFIG_PATH: pkgConfigDirs.join(path.delimiter),
},
cwd: "ffmpeg",
stdio: "inherit",
Expand Down
126 changes: 125 additions & 1 deletion zip.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { execSync } from "child_process";
import {
copyFileSync,
rmSync,
readdirSync,
renameSync,
unlinkSync,
Expand All @@ -11,9 +12,103 @@ import { PREFIX } from "./const.mjs";

const isWindows = process.argv[2] === "windows";
const remotionLibDir = path.join(process.cwd(), "remotion", "lib");
const remotionLib64Dir = path.join(process.cwd(), "remotion", "lib64");
const remotionBinDir = path.join(process.cwd(), "remotion", "bin");

const getStripTool = () => {
const candidates = isWindows
? ["x86_64-w64-mingw32-strip"]
: process.platform === "darwin"
? ["strip", "llvm-strip"]
: ["strip", "llvm-strip"];

for (const tool of candidates) {
try {
execSync(`command -v ${tool}`, {
stdio: "ignore",
});
return tool;
} catch {
// Continue trying alternatives.
}
}

return null;
};

const stripFilesInDir = (dir, shouldStrip, stripTool, stripArgs) => {
if (!existsSync(dir)) {
return;
}

const files = readdirSync(dir, {
withFileTypes: true,
});

for (const file of files) {
if (!file.isFile()) {
continue;
}

if (!shouldStrip(file.name)) {
continue;
}

const fullPath = path.join(dir, file.name);
try {
execSync(
[stripTool, ...stripArgs, `"${fullPath.replaceAll('"', '\\"')}"`].join(
" "
),
{
stdio: "inherit",
}
);
} catch (err) {
console.warn(`Skipping strip for ${fullPath}:`, err.message);
}
}
};

const removeDevArtifacts = () => {
const devPaths = [
path.join(remotionLibDir, "pkgconfig"),
path.join(remotionLib64Dir, "pkgconfig"),
path.join(remotionLibDir, "cmake"),
path.join(remotionLib64Dir, "cmake"),
];

for (const devPath of devPaths) {
if (existsSync(devPath)) {
rmSync(devPath, {
force: true,
recursive: true,
});
}
}

for (const libDir of [remotionLibDir, remotionLib64Dir]) {
if (!existsSync(libDir)) {
continue;
}

const files = readdirSync(libDir, {
withFileTypes: true,
});
for (const file of files) {
if (!file.isFile()) {
continue;
}
if (file.name.endsWith(".a") || file.name.endsWith(".la")) {
rmSync(path.join(libDir, file.name), {
force: true,
});
}
}
}
};

if (isWindows) {
const remotionBinDir = path.join(process.cwd(), "remotion", "bin");
copyFileSync(
"libwinpthread-1.dll",
path.join(remotionLibDir, "libwinpthread-1.dll")
Expand Down Expand Up @@ -49,6 +144,35 @@ if (isWindows) {
}
}

const stripTool = getStripTool();
if (stripTool) {
const stripArgs =
process.platform === "darwin" ? ["-x"] : ["--strip-unneeded"];
stripFilesInDir(
remotionBinDir,
(fileName) => (isWindows ? fileName.endsWith(".exe") : true),
stripTool,
stripArgs
);
stripFilesInDir(
remotionLibDir,
(fileName) =>
isWindows
? fileName.endsWith(".dll")
: fileName.endsWith(".dylib") || fileName.includes(".so"),
stripTool,
stripArgs
);
stripFilesInDir(
remotionLib64Dir,
(fileName) => fileName.endsWith(".dylib") || fileName.includes(".so"),
stripTool,
stripArgs
);
}

removeDevArtifacts();

execSync(`tar cvzf ffmpeg.tar.gz ${PREFIX} bindings.rs`, {
stdio: "inherit",
});
Loading