Skip to content

Instantly share code, notes, and snippets.

@yagop
Last active November 17, 2025 09:15
Show Gist options
  • Select an option

  • Save yagop/34866f7f1971be9da962141311667d3c to your computer and use it in GitHub Desktop.

Select an option

Save yagop/34866f7f1971be9da962141311667d3c to your computer and use it in GitHub Desktop.
ffmpeg Alpine for OpenWRT compilation
#!/bin/bash
docker build \
-t ffmpeg-alpine-muslc-arm64-cortex-a53 \
--platform linux/arm64 \
--build-arg CFLAGS="-O3 -mcpu=cortex-a53+crc+crypto+simd -D_POSIX_C_SOURCE=200809L -D_DEFAULT_SOURCE" \
--build-arg FFMPEG_EXTRA_ARGS="--cpu=cortex-a53" \
${@} \
.
# ===============================
# Alpine-based Dockerfile for FFmpeg compilation
# Use Alpine Linux as the base image which uses musl libc
# Should be able to run in OpenWrt (tested in OpenWrt 24.10.2)
# Static build with libx264 + libx265 + libdav1d + libogg + libvorbis + libopus + libmp3lame + libvpx + libtheora + libaom + libfdk-aac + libass + libfreetype + fontconfig + libwebp
# ===============================
# ===============================
# Stage 1: Builder
# ===============================
FROM alpine:3.22 AS builder
# ------------------------------
# Install build dependencies
# ------------------------------
RUN apk update && apk add --no-cache \
bash \
busybox \
cmake \
file \
g++ \
gcc \
git \
gnutls \
gnutls-dev \
libc-dev \
make \
musl-dev \
nasm \
perl \
yasm \
wget \
curl \
meson \
ninja \
autoconf \
automake \
libtool \
gperf \
diffutils \
upx
# ------------------------------
# Environment variables
# ------------------------------
ENV PREFIX="/usr/local"
ENV PATH="$PREFIX/bin:$PATH"
ENV PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig"
# Set default compiler flags and FFmpeg CPU target
ARG CFLAGS="-O3 -D_POSIX_C_SOURCE=200809L -D_DEFAULT_SOURCE -fPIC"
ARG CXXFLAGS="$CFLAGS"
ARG FFMPEG_EXTRA_ARGS=""
# ENV LDFLAGS="-static"
WORKDIR /tmp
# ------------------------------
# Build zlib (static)
# ------------------------------
RUN wget https://zlib.net/zlib-1.3.1.tar.gz \
&& tar xzf zlib-1.3.1.tar.gz \
&& cd zlib-1.3.1 \
&& ./configure \
--prefix=$PREFIX \
--static \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build x264 (static)
# ------------------------------
RUN git clone https://code.videolan.org/videolan/x264.git \
&& cd x264 \
&& git checkout 0480cb05fa188d37ae87e8f4fd8f1aea3711f7ee \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
--enable-pic \
--disable-cli \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build x265 (static, 8-bit + 10-bit + 12-bit, disable tests)
# ------------------------------
RUN git clone https://bitbucket.org/multicoreware/x265_git.git \
&& cd x265_git/source \
&& git checkout 4.1 \
&& mkdir -p build/linux
# Build 12-bit
RUN cd x265_git/source/build/linux \
&& mkdir -p 12bit && cd 12bit \
&& cmake ../../.. \
-DCMAKE_INSTALL_PREFIX=$PREFIX \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_SHARED=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DHIGH_BIT_DEPTH=ON \
-DENABLE_HDR10_PLUS=ON \
-DEXPORT_C_API=OFF \
-DENABLE_CLI=OFF \
-DMAIN12=ON \
&& make -j$(nproc)
# Build 10-bit
RUN cd x265_git/source/build/linux \
&& mkdir -p 10bit && cd 10bit \
&& cmake ../../.. \
-DCMAKE_INSTALL_PREFIX=$PREFIX \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_SHARED=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DHIGH_BIT_DEPTH=ON \
-DENABLE_HDR10_PLUS=ON \
-DEXPORT_C_API=OFF \
-DENABLE_CLI=OFF \
&& make -j$(nproc)
# Build 8-bit and combine all
RUN cd x265_git/source/build/linux \
&& mkdir -p 8bit && cd 8bit \
&& ln -sf ../10bit/libx265.a libx265_main10.a \
&& ln -sf ../12bit/libx265.a libx265_main12.a \
&& cmake ../../.. \
-DCMAKE_INSTALL_PREFIX=$PREFIX \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_SHARED=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DEXTRA_LIB="x265_main10.a;x265_main12.a;-ldl" \
-DEXTRA_LINK_FLAGS=-L. \
-DLINKED_10BIT=ON \
-DLINKED_12BIT=ON \
&& make -j$(nproc) \
&& mv libx265.a libx265_main.a \
&& printf 'CREATE libx265.a\nADDLIB libx265_main.a\nADDLIB libx265_main10.a\nADDLIB libx265_main12.a\nSAVE\nEND\n' | ar -M \
&& make install
RUN git clone https://gitlab.com/AOMediaCodec/SVT-AV1.git \
&& cd SVT-AV1 \
&& git checkout v3.1.2 \
&& mkdir -p build && cd build \
&& cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_UNIT_TESTS=OFF \
-DENABLE_APPS=OFF \
-DCMAKE_INSTALL_PREFIX=/usr/local \
&& make -j$(nproc) \
&& make install
# --------------------------
# Build dav1d (static)
# --------------------------
RUN git clone --branch 1.5.2 https://code.videolan.org/videolan/dav1d.git dav1d && \
cd dav1d && \
meson setup build --prefix=$PREFIX --buildtype=release --default-library=static && \
meson compile -C build && \
meson install -C build && \
pkg-config --modversion dav1d
# ------------------------------
# Build libogg (static)
# ------------------------------
RUN wget https://downloads.xiph.org/releases/ogg/libogg-1.3.5.tar.gz \
&& tar xzf libogg-1.3.5.tar.gz \
&& cd libogg-1.3.5 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libvorbis (static)
# ------------------------------
RUN wget https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.gz \
&& tar xzf libvorbis-1.3.7.tar.gz \
&& cd libvorbis-1.3.7 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libopus (static)
# ------------------------------
RUN wget https://downloads.xiph.org/releases/opus/opus-1.5.2.tar.gz \
&& tar xzf opus-1.5.2.tar.gz \
&& cd opus-1.5.2 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
--disable-doc \
--disable-extra-programs \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libmp3lame (static)
# ------------------------------
RUN wget https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz \
&& tar xzf lame-3.100.tar.gz \
&& cd lame-3.100 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
--disable-frontend \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build expat (static)
# ------------------------------
RUN wget https://github.com/libexpat/libexpat/releases/download/R_2_6_4/expat-2.6.4.tar.gz \
&& tar xzf expat-2.6.4.tar.gz \
&& cd expat-2.6.4 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build fribidi (static)
# ------------------------------
RUN wget https://github.com/fribidi/fribidi/releases/download/v1.0.16/fribidi-1.0.16.tar.xz \
&& tar xf fribidi-1.0.16.tar.xz \
&& cd fribidi-1.0.16 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build harfbuzz (static)
# ------------------------------
RUN wget https://github.com/harfbuzz/harfbuzz/releases/download/10.1.0/harfbuzz-10.1.0.tar.xz \
&& tar xf harfbuzz-10.1.0.tar.xz \
&& cd harfbuzz-10.1.0 \
&& meson setup build --prefix=$PREFIX --buildtype=release --default-library=static \
&& meson compile -C build \
&& meson install -C build
# ------------------------------
# Build libfreetype (static)
# ------------------------------
RUN wget https://download.savannah.gnu.org/releases/freetype/freetype-2.13.3.tar.gz \
&& tar xzf freetype-2.13.3.tar.gz \
&& cd freetype-2.13.3 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build fontconfig (static)
# ------------------------------
RUN wget https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.15.0.tar.gz \
&& tar xzf fontconfig-2.15.0.tar.gz \
&& cd fontconfig-2.15.0 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libass (static)
# ------------------------------
RUN wget https://github.com/libass/libass/releases/download/0.17.3/libass-0.17.3.tar.gz \
&& tar xzf libass-0.17.3.tar.gz \
&& cd libass-0.17.3 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libwebp (static)
# ------------------------------
RUN wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.4.0.tar.gz \
&& tar xzf libwebp-1.4.0.tar.gz \
&& cd libwebp-1.4.0 \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libvpx (static)
# ------------------------------
RUN git clone --depth 1 --branch v1.14.1 https://chromium.googlesource.com/webm/libvpx \
&& cd libvpx \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
--disable-examples \
--disable-unit-tests \
--enable-vp9-highbitdepth \
--as=yasm \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libtheora (static)
# ------------------------------
RUN wget https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2 \
&& tar xjf libtheora-1.1.1.tar.bz2 \
&& cd libtheora-1.1.1 \
&& wget -O config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' \
&& wget -O config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
--disable-examples \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libaom (static)
# ------------------------------
RUN git clone --depth 1 --branch v3.10.0 https://aomedia.googlesource.com/aom \
&& cd aom \
&& mkdir -p build && cd build \
&& cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_TESTS=OFF \
-DENABLE_EXAMPLES=OFF \
-DENABLE_DOCS=OFF \
-DCMAKE_INSTALL_PREFIX=$PREFIX \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build libfdk-aac (static)
# ------------------------------
RUN git clone --depth 1 --branch v2.0.3 https://github.com/mstorsjo/fdk-aac.git \
&& cd fdk-aac \
&& ./autogen.sh \
&& ./configure \
--prefix=$PREFIX \
--enable-static \
--disable-shared \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Build FFmpeg stable version
# ------------------------------
RUN wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.1.2.tar.gz \
&& tar xvf n7.1.2.tar.gz \
&& cd FFmpeg-n7.1.2 \
&& ./configure \
--prefix=$PREFIX \
--enable-gpl \
--enable-nonfree \
--enable-static \
--disable-shared \
--pkg-config-flags="--static" \
--enable-pthreads \
--enable-zlib \
--disable-doc \
--disable-debug \
--enable-lto \
--disable-vaapi \
--disable-vdpau \
--disable-outdevs \
--disable-decoder=atrac3 \
--disable-muxer=vc1 \
--disable-demuxer=vc1 \
--disable-parser=vc1 \
--enable-libopus \
--enable-libvorbis \
--enable-libmp3lame \
--enable-libx264 \
--enable-libx265 \
--enable-libsvtav1 \
--enable-libdav1d \
--enable-libvpx \
--enable-libtheora \
--enable-libaom \
--enable-libfdk-aac \
--enable-libass \
--enable-libfreetype \
--enable-fontconfig \
--enable-libwebp \
--disable-ffplay \
--enable-pic \
${FFMPEG_EXTRA_ARGS} \
&& make -j$(nproc) \
&& make install
# ------------------------------
# Compress binaries with UPX
# ------------------------------
# RUN upx --best --lzma /usr/local/bin/ffmpeg /usr/local/bin/ffprobe || true
# ===============================
# Stage 2: Runtime
# ===============================
FROM alpine:3.22
# Copy only the compiled binaries from builder
COPY --from=builder /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg
COPY --from=builder /usr/local/bin/ffprobe /usr/local/bin/ffprobe
# Install only runtime dependencies (minimal)
RUN apk add --no-cache \
libstdc++ \
libgcc
RUN ffmpeg -version \
&& ffprobe -version
CMD ["ffmpeg", "-version"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment