Compile FFmpeg to WebAssembly with Emscripten

This guide provides a straightforward, step-by-step walkthrough on how to compile FFmpeg to WebAssembly (WASM) using the Emscripten toolchain. You will learn how to set up the compilation environment, configure the FFmpeg source code for cross-compilation, build the libraries, and link them into WebAssembly and JavaScript files suitable for execution directly inside a web browser.

Step 1: Install the Emscripten SDK (emsdk)

To compile C/C++ code to WebAssembly, you must first install and activate the Emscripten SDK. Run the following commands in your terminal:

# Clone the Emscripten repository
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk

# Install and activate the latest SDK version
./emsdk install latest
./emsdk activate latest

# Source the environment variables
source ./emsdk_env.sh

Keep this terminal window open, as the environment variables are only active in the current session.

Step 2: Download the FFmpeg Source Code

Clone the official FFmpeg repository and checkout a stable release branch.

git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
# Checkout a stable version (e.g., release 6.0)
git checkout n6.0

Step 3: Configure FFmpeg for WebAssembly

Standard FFmpeg features assembly optimizations and OS-specific system calls that are incompatible with the browser environment. You must disable these optimizations and configure the build to target a generic architecture using Emscripten’s tools.

Run emconfigure with the following configuration flags:

emconfigure ./configure \
  --target-os=none \
  --arch=x86_32 \
  --enable-cross-compile \
  --cc=emcc \
  --cxx=em++ \
  --ar=emar \
  --ranlib=emranlib \
  --disable-x86asm \
  --disable-inline-asm \
  --disable-stripping \
  --disable-programs \
  --disable-doc \
  --disable-all \
  --enable-avcodec \
  --enable-avformat \
  --enable-avutil \
  --enable-swresample \
  --enable-decoder=aac \
  --enable-decoder=h264 \
  --enable-parser=aac \
  --enable-parser=h264

Key Flag Explanations:

Step 4: Compile the Libraries

Run the compilation process using emmake. This generates static library archives (.a files) for the enabled FFmpeg modules.

emmake make -j$(nproc)

Once completed, the compiled static libraries (such as libavcodec.a, libavformat.a, and libavutil.a) will be located inside their respective directories.

To use the compiled libraries in JavaScript, you must write a custom C interface file (e.g., wrapper.c) that exposes the desired FFmpeg APIs, then compile and link everything together.

Assuming you have a wrapper.c file that handles your media processing logic, compile it using emcc:

emcc wrapper.c \
  libavformat/libavformat.a \
  libavcodec/libavcodec.a \
  libavutil/libavutil.a \
  libswresample/libswresample.a \
  -I. \
  -O3 \
  -s WASM=1 \
  -s EXPORTED_FUNCTIONS="['_malloc', '_free', '_your_custom_ffmpeg_function']" \
  -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" \
  -o ffmpeg.js

Key Linking Flags:

Once this compilation finishes, import ffmpeg.js into your web application to begin utilizing FFmpeg directly within the browser ecosystem.