#!/bin/bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" BUILD_DIR="$SCRIPT_DIR/ffmpeg_build" SRC_DIR="$BUILD_DIR/src" INSTALL_DIR="$BUILD_DIR/install" JOBS=$(nproc 2>/dev/null || echo 4) case "$(uname -s)" in Linux) PLATFORM=linux ;; MINGW*|MSYS*|CYGWIN*) PLATFORM=windows ;; *) echo "Unsupported platform: $(uname -s)"; exit 1 ;; esac log() { echo "[FFmpeg] $1"; } die() { echo "[FFmpeg] ERROR: $1" >&2; exit 1; } check_cmd() { command -v "$1" >/dev/null 2>&1 || die "$1 not found. Install it first."; } do_clone() { local name="$1" url="$2" tag="$3" if [ ! -d "$SRC_DIR/$name" ]; then log "Clone $name..." for i in 1 2 3; do git clone --depth 1 --branch "$tag" "$url" "$SRC_DIR/$name" 2>&1 && break log "Clone attempt $i failed, retrying..." rm -rf "$SRC_DIR/$name" sleep 2 done [ -d "$SRC_DIR/$name/.git" ] || die "Failed to clone $name after 3 attempts" else log "Skip clone $name: already exists" fi } # ============================================================================ # Step 0: System dependencies # ============================================================================ if [ "$PLATFORM" = "linux" ]; then MISSING="" for pkg in build-essential cmake nasm pkg-config meson ninja-build git; do dpkg -s "$pkg" >/dev/null 2>&1 || MISSING="$MISSING $pkg" done if [ -n "$MISSING" ]; then log "Installing build tools:$MISSING" sudo apt update -qq && sudo apt install -y $MISSING fi HW_DEPS="libva-dev libvdpau-dev" for pkg in $HW_DEPS; do dpkg -s "$pkg" >/dev/null 2>&1 || { log "Installing $pkg (HW accel)"; sudo apt install -y $pkg; } done else check_cmd pacman for pkg in mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-nasm \ mingw-w64-ucrt-x86_64-pkg-config mingw-w64-ucrt-x86_64-meson; do pacman -Qi "$pkg" >/dev/null 2>&1 || { log "Installing $pkg"; pacman -S --noconfirm "$pkg"; } done fi check_cmd cmake check_cmd nasm check_cmd pkg-config check_cmd meson check_cmd git # ============================================================================ # Step 1: Codec libraries (static .a, built with -fPIC) # ============================================================================ mkdir -p "$SRC_DIR" "$INSTALL_DIR/lib/pkgconfig" export PKG_CONFIG_PATH="$INSTALL_DIR/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" # --- x264 (H.264 encoder) --- if [ ! -f "$INSTALL_DIR/lib/pkgconfig/x264.pc" ]; then do_clone x264 https://code.videolan.org/videolan/x264.git stable cd "$SRC_DIR/x264" log "Configure x264..." ./configure --prefix="$INSTALL_DIR" --enable-static --disable-shared \ --disable-opencl --disable-avs --disable-swscale --disable-lavf \ --disable-ffms --disable-gpac --disable-lsmash \ --extra-cflags="-fPIC" --disable-cli log "Build x264..." make -j"$JOBS" make install log "x264 OK" else log "Skip x264: already built" fi # --- x265 (H.265/HEVC encoder) --- if [ ! -f "$INSTALL_DIR/lib/pkgconfig/x265.pc" ]; then do_clone x265 https://bitbucket.org/multicoreware/x265_git.git master cd "$SRC_DIR/x265" mkdir -p build && cd build log "Configure x265..." cmake ../source -G "Unix Makefiles" \ -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ -DBUILD_SHARED_LIBS=OFF \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DENABLE_CLI=OFF -DENABLE_SHARED=OFF \ -DHIGH_BIT_DEPTH=OFF -DENABLE_HDR10_PLUS=OFF log "Build x265..." cmake --build . -j"$JOBS" cmake --install . cat > "$INSTALL_DIR/lib/pkgconfig/x265.pc" <&1 && break log "Download from $url failed, trying next..." rm -f "$FFMPEG_TARBALL" done [ -f "$FFMPEG_TARBALL" ] || die "Failed to download FFmpeg tarball" log "Download OK ($(du -h "$FFMPEG_TARBALL" | cut -f1))" fi log "Extract FFmpeg..." mkdir -p "$FFMPEG_SRC" tar -xf "$FFMPEG_TARBALL" -C "$FFMPEG_SRC" --strip-components=1 rm -f "$FFMPEG_TARBALL" fi cd "$SRC_DIR/ffmpeg" log "Configure FFmpeg..." CONFIGURE_ARGS=( --prefix="$INSTALL_DIR" --enable-shared --disable-static --enable-gpl --enable-version3 --pkg-config-flags=--static --extra-cflags="-I$INSTALL_DIR/include" --extra-ldflags="-L$INSTALL_DIR/lib" --extra-libs="-lpthread -lm -ldl" --enable-libx264 --enable-libx265 --enable-libvpx --enable-libsvtav1 --enable-libaom --enable-libdav1d --enable-nvenc --enable-cuda --enable-cuvid --enable-vaapi --enable-vdpau --disable-programs --disable-doc --disable-avdevice --disable-ffprobe --disable-ffplay --disable-ffmpeg --disable-debug --enable-optimizations ) if [ "$PLATFORM" = "windows" ]; then CONFIGURE_ARGS+=( --enable-d3d11va --enable-dxva2 ) fi "./configure" "${CONFIGURE_ARGS[@]}" log "Build FFmpeg..." make -j"$JOBS" make install log "===============================================================" log "FFmpeg build SUCCESS" log "Install prefix: $INSTALL_DIR" log "Libraries: $(ls "$INSTALL_DIR/lib/"*.so* "$INSTALL_DIR/lib/"*.dll.a "$INSTALL_DIR/bin/"*.dll 2>/dev/null | tr '\n' ' ')" log "==============================================================="