Skip to content

Pre-compiled FFmpeg binaries for Node.js. Static builds with x264, x265, VP9, AV1, Opus and more. Supports macOS, Linux (glibc/musl), and Windows with hardware acceleration variants.

License

Notifications You must be signed in to change notification settings

pproenca/ffmpeg-prebuilds

Repository files navigation

FFmpeg Prebuilds

Static FFmpeg binaries and development libraries for Node.js, packaged as platform-specific npm modules.

Overview

This repository builds and distributes FFmpeg with comprehensive codec support (H.264, H.265, VP9, AV1, SVT-AV1, Opus, MP3, AAC, FLAC, and more) as:

  • Runtime packages: @pproenca/ffmpeg-* — FFmpeg binaries for direct use
  • Development packages: @pproenca/ffmpeg-dev-* — Static libraries + headers for native addon compilation
  • Main package: @pproenca/ffmpeg — Meta-package with automatic platform detection
  • Hardware acceleration packages: Optional GPU-accelerated builds (VA-API, NVENC, VideoToolbox, DXVA2)

Built following the sharp-libvips distribution model.

Installation

For CLI usage:

npm install @pproenca/ffmpeg

For native addon development:

# Install dev package for your platform
npm install --save-dev @pproenca/ffmpeg-dev-linux-x64-glibc

Usage

Using FFmpeg binaries:

const { ffmpegPath, ffprobePath } = require('@pproenca/ffmpeg');
const { execSync } = require('child_process');

// Get FFmpeg version
const version = execSync(`"${ffmpegPath}" -version`, { encoding: 'utf8' });
console.log(version);

// Transcode video
execSync(`"${ffmpegPath}" -i input.mp4 -c:v libx264 output.mp4`);

Using in native addons (binding.gyp):

{
  'targets': [{
    'target_name': 'addon',
    'sources': ['addon.cc'],
    'include_dirs': [
      '<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'include\')")',
    ],
    'libraries': [
      # Link directly against static libraries (no pkg-config needed)
      '<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'lib\')")/libavcodec.a',
      '<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'lib\')")/libavformat.a',
      '<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'lib\')")/libavutil.a',
      # Add other FFmpeg libraries as needed (libswscale.a, libswresample.a, etc.)
    ],
  }],
}

Or set FFMPEG_ROOT in your environment for easier linking:

export FFMPEG_ROOT="$(npm root)/@pproenca/ffmpeg-dev-linux-x64-glibc"

# In your binding.gyp, reference libraries via environment variable
# libraries: ['<(FFMPEG_ROOT)/lib/libavcodec.a', ...]
npm run build

Hardware Acceleration

For GPU-accelerated encoding/decoding (5-15x faster), install a hardware acceleration variant:

# Linux with Intel/AMD GPU
npm install @pproenca/ffmpeg-linux-x64-glibc-vaapi

# Linux with NVIDIA GPU
npm install @pproenca/ffmpeg-linux-x64-glibc-nvenc

# Windows with GPU decode
npm install @pproenca/ffmpeg-windows-x64-dxva2

Use with the hardwareAccel option:

const { getBinaryPath } = require('@pproenca/ffmpeg');

// Use hardware acceleration if available, fall back to software
const ffmpegPath = getBinaryPath('ffmpeg', { hardwareAccel: 'vaapi' });

Note: macOS builds include VideoToolbox hardware acceleration by default (no separate package needed).

See: HARDWARE.md for detailed setup, usage examples, and performance comparisons.

Supported Platforms

Standard Builds (Software Encoding)

Platform Runtime Package Dev Package
darwin-x64 @pproenca/ffmpeg-darwin @pproenca/ffmpeg-dev-darwin
linux-x64 (glibc) @pproenca/ffmpeg-linux-x64-glibc N/A
linux-x64 (musl) @pproenca/ffmpeg-linux-x64-musl N/A
linux-arm64 (glibc) @pproenca/ffmpeg-linux-arm64-glibc N/A
linux-arm64 (musl) @pproenca/ffmpeg-linux-arm64-musl N/A
linux-arm (glibc) @pproenca/ffmpeg-linux-armv7-glibc N/A
win32-x64 @pproenca/ffmpeg-windows-x64 N/A

1 Universal binary (x64 + ARM64) with built-in VideoToolbox hardware acceleration

Hardware Acceleration Builds (GPU-Accelerated)

Platform Runtime Package Description
Linux VA-API @pproenca/ffmpeg-linux-x64-glibc-vaapi Intel/AMD GPU acceleration (5-8x faster)
Linux NVENC @pproenca/ffmpeg-linux-x64-glibc-nvenc NVIDIA GPU acceleration (10-15x faster)
Windows DXVA2 @pproenca/ffmpeg-windows-x64-dxva2 Windows GPU decode acceleration

See HARDWARE.md for hardware acceleration setup and usage.

Requirements:

  • macOS: 11.0 (Big Sur) or later
  • Linux (glibc): Ubuntu 24.04 or equivalent (glibc 2.35+)
  • Linux (musl): Alpine 3.21 or later
  • Windows: Windows 10 or later (x64)
  • ARM platforms: Raspberry Pi 2/3/4/5, AWS Graviton, NVIDIA Jetson

Included Codecs

Video

Codec Library License Description
H264 libx264 GPL-2.0-or-later H.264/AVC - Most widely supported video codec
H265 libx265 GPL-2.0-or-later H.265/HEVC - Better compression than H.264
VP8 libvpx BSD-3-Clause VP8 - WebM video codec
VP9 libvpx BSD-3-Clause VP9 - Improved WebM codec (shares libvpx with VP8)
AV1 libaom BSD-2-Clause AV1 - Royalty-free next-gen codec (reference encoder)
SVT-AV1 libsvtav1 BSD-2-Clause SVT-AV1 - Intel's optimized AV1 encoder (faster than libaom)
THEORA libtheora BSD-3-Clause Theora - Legacy Ogg video codec
XVID libxvid GPL-2.0-or-later Xvid - MPEG-4 ASP codec

Audio

Codec Library License Description
OPUS libopus BSD-3-Clause Opus - Best quality/bitrate for voice and music
MP3 libmp3lame LGPL-2.1-or-later MP3 - Universal audio codec (LAME encoder)
AAC native LGPL-2.1-or-later AAC - FFmpeg native encoder
FDK-AAC libfdk-aac Non-free fdk-aac - High-quality AAC encoder (better than native)
FLAC libflac BSD-3-Clause FLAC - Lossless audio compression
SPEEX libspeex BSD-3-Clause Speex - Speech codec (optimized for voice)
VORBIS libvorbis BSD-3-Clause Vorbis - Ogg audio codec

Subtitle & Other

  • libass (ISC) - Advanced subtitle rendering
  • libfreetype (FreeType License) - Font rendering

See CODECS.md for detailed licensing and codec information.

Build Artifacts

What's Included

  • Binaries: ffmpeg, ffprobe (statically linked, self-contained)
  • Static Libraries: libx264.a, libx265.a, libvpx.a, libaom.a, libopus.a, libmp3lame.a, etc.
  • Headers: Include files for all libraries (libavcodec, libavformat, libavutil, etc.)

What's Excluded

  • PKGConfig files (.pc): Not needed for static builds; removed to avoid path issues
  • Libtool files (.la): Can cause relocation issues; removed
  • CMake files: Build-time only; removed from distribution

Why Static Builds?

This project distributes ready-to-use FFmpeg binaries, not development libraries. All dependencies are statically linked into the final binaries, making them completely self-contained with no external dependencies.

Building from Source

Prerequisites

  • macOS: Xcode Command Line Tools, Homebrew
  • Linux: Docker (for reproducible builds)
  • All: Node.js 20+, Git

Build a single platform:

# Clone repository
git clone https://github.com/pproenca/ffmpeg-prebuilds.git
cd ffmpeg-prebuilds

# Install dependencies
npm install

# Build for your current platform
./build/orchestrator.sh darwin-arm64  # macOS ARM64
./build/orchestrator.sh linux-x64-glibc  # Linux (Docker)

# Verify build
./build/verify.sh darwin-arm64

# Create npm packages
npm run package

Build all platforms (via GitHub Actions):

git tag v8.0.0
git push --tags
# GitHub Actions will build all platforms in parallel

Version Management

All codec versions are centralized in versions.properties:

FFMPEG_VERSION=n8.0
X264_VERSION=stable
X265_VERSION=4.0
LIBVPX_VERSION=v1.15.2
LIBAOM_VERSION=v3.12.1
# ... etc

To update dependencies:

  1. Run npm run fetch-versions to preview updates
  2. Update versions.properties (or run npm run fetch-versions:write)
  3. Bump CACHE_VERSION to invalidate CI cache
  4. Run builds locally to test
  5. Create a git tag and push to trigger release

CI/CD Pipeline

The repository uses GitHub Actions for automated builds:

  • build.yml: Matrix builds for all platforms (parallel, ~30min total)
  • release.yml: Publishes to npm on version tags (v*)

Workflow:

Tag Push (v8.0.0)
  ↓
Matrix Build (darwin-x64, darwin-arm64, linux-x64-glibc, linux-x64-musl)
  ↓
Create npm packages (runtime + dev)
  ↓
Publish to npm (@pproenca scope)
  ↓
Create GitHub Release (with binary tarballs)

Development

Testing changes locally:

# Build one platform
./build/orchestrator.sh darwin-arm64

# Verify output
ls -lh artifacts/darwin-arm64/

# Create packages
npm run package

# Test package installation
cd /tmp
npm install /path/to/ffmpeg-prebuilds/npm-dist/@pproenca/ffmpeg-darwin-arm64

# Verify binary works
node -e "console.log(require('@pproenca/ffmpeg').ffmpegPath)"

Adding a new platform:

  1. Create platforms/<new-platform>/Dockerfile (for Docker-based builds)
  2. Add platform to PLATFORMS array in scripts/package-npm.ts
  3. Update build/orchestrator.sh routing logic
  4. Add matrix entry to .github/workflows/build.yml
  5. Test build locally
  6. Update this README

Architecture

ffmpeg-prebuilds/
├── build/
│   ├── orchestrator.sh      # Delegates to platform scripts
│   ├── macos.sh             # macOS native builds
│   ├── linux.sh             # Docker-based Linux builds
│   └── verify.sh            # ABI validation
├── platforms/
│   ├── linux-x64-glibc/Dockerfile
│   ├── linux-x64-musl/Dockerfile
│   └── darwin-*/README.md   # Native runner docs
├── scripts/
│   └── package-npm.ts       # Creates npm packages from artifacts
├── versions.properties      # Single source of truth for versions
└── .github/workflows/
    ├── build.yml            # Parallel matrix builds
    └── release.yml          # npm publishing

License

GPL-2.0-or-later

This package includes FFmpeg with x264 and x265, which are licensed under GPL v2+. Therefore, the entire distribution must be GPL v2 or later.

Individual codec licenses:

  • FFmpeg: LGPL v2.1+ or GPL v2+ (we distribute GPL version)
  • x264, x265: GPL v2+
  • libvpx, libaom, Opus, Vorbis, Ogg: BSD

See LICENSE for full details.

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Test builds on your platform
  4. Commit changes (git commit -m 'Add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Reporting Issues

When reporting bugs, please include:

  • Platform (macOS/Linux, architecture, libc variant)
  • FFmpeg version (from versions.properties)
  • Full error output
  • Steps to reproduce

Related Projects

  • node-webcodecs - W3C WebCodecs API for Node.js (uses these prebuilts)
  • sharp-libvips - Inspiration for this distribution model
  • FFmpeg - The multimedia framework we're packaging

Acknowledgments

  • FFmpeg team for the amazing multimedia framework
  • Lovell Fuller for the sharp-libvips distribution pattern
  • VideoLAN for x264
  • MulticoreWare for x265
  • Google/Chromium for libvpx
  • Alliance for Open Media for libaom

Support