You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

269 lines
9.0 KiB

#!/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" <<EOF
prefix=$INSTALL_DIR
exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include
Name: x265
Description: H.265/HEVC video encoder
Version: 4.1
Libs: -L\${libdir} -lx265
Libs.private: -lstdc++ -lm -lpthread
Cflags: -I\${includedir}
EOF
log "x265 OK"
else
log "Skip x265: already built"
fi
# --- libvpx (VP8/VP9 encoder) ---
if [ ! -f "$INSTALL_DIR/lib/pkgconfig/vpx.pc" ]; then
do_clone libvpx https://chromium.googlesource.com/webm/libvpx main
cd "$SRC_DIR/libvpx"
log "Configure libvpx..."
./configure --prefix="$INSTALL_DIR" --enable-static --disable-shared \
--enable-pic --enable-vp8 --enable-vp9 --enable-vp9-highbitdepth \
--disable-examples --disable-tools --disable-docs --disable-unit-tests
log "Build libvpx..."
make -j"$JOBS"
make install
log "libvpx OK"
else
log "Skip libvpx: already built"
fi
# --- SVT-AV1 (fast AV1 encoder) ---
if [ ! -f "$INSTALL_DIR/lib/pkgconfig/SvtAv1Enc.pc" ]; then
do_clone SVT-AV1 https://gitlab.com/AOMediaCodec/SVT-AV1.git v2.3.0
cd "$SRC_DIR/SVT-AV1"
mkdir -p build && cd build
log "Configure SVT-AV1..."
cmake .. -G "Unix Makefiles" \
-DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
-DBUILD_SHARED_LIBS=OFF -DBUILD_APPS=OFF \
-DBUILD_TESTING=OFF -DBUILD_DEC=OFF
log "Build SVT-AV1..."
cmake --build . -j"$JOBS"
cmake --install .
log "SVT-AV1 OK"
else
log "Skip SVT-AV1: already built"
fi
# --- libaom (reference AV1 encoder) ---
if [ ! -f "$INSTALL_DIR/lib/pkgconfig/aom.pc" ]; then
do_clone libaom https://aomedia.googlesource.com/aom v3.12.0
cd "$SRC_DIR/libaom"
mkdir -p build && cd build
log "Configure libaom..."
cmake .. -G "Unix Makefiles" \
-DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
-DBUILD_SHARED_LIBS=OFF -DENABLE_TESTS=OFF \
-DENABLE_TOOLS=OFF -DENABLE_DOCS=OFF \
-DENABLE_NASM=ON
log "Build libaom..."
cmake --build . -j"$JOBS"
cmake --install .
log "libaom OK"
else
log "Skip libaom: already built"
fi
# --- dav1d (fast AV1 decoder) ---
if [ ! -f "$INSTALL_DIR/lib/pkgconfig/dav1d.pc" ]; then
do_clone dav1d https://code.videolan.org/videolan/dav1d.git 1.5.1
cd "$SRC_DIR/dav1d"
log "Configure dav1d..."
meson setup build --prefix="$INSTALL_DIR" --buildtype release --libdir lib \
-Ddefault_library=static -Denable_tools=false -Denable_tests=false -Denable_docs=false
log "Build dav1d..."
meson compile -C build -j"$JOBS"
meson install -C build
log "dav1d OK"
else
log "Skip dav1d: already built"
fi
# --- nv-codec-headers (NVIDIA NVENC/NVDEC headers, no build needed) ---
if [ ! -f "$INSTALL_DIR/include/ffnvcodec/nvEncodeAPI.h" ]; then
do_clone nv-codec-headers https://github.com/FFmpeg/nv-codec-headers.git master
cd "$SRC_DIR/nv-codec-headers"
log "Install nv-codec-headers..."
make install PREFIX="$INSTALL_DIR"
log "nv-codec-headers OK"
else
log "Skip nv-codec-headers: already installed"
fi
# ============================================================================
# Step 2: FFmpeg
# ============================================================================
if [ -f "$INSTALL_DIR/lib/pkgconfig/libavcodec.pc" ]; then
log "FFmpeg already built, skipping."
log "Done: $INSTALL_DIR"
exit 0
fi
FFMPEG_SRC="$SRC_DIR/ffmpeg"
if [ ! -d "$FFMPEG_SRC" ]; then
log "Download FFmpeg 7.1.2..."
FFMPEG_TARBALL="$SRC_DIR/ffmpeg-7.1.2.tar.xz"
if [ ! -f "$FFMPEG_TARBALL" ]; then
for url in \
"https://ffmpeg.org/releases/ffmpeg-7.1.2.tar.xz" \
"https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.1.2.tar.gz"; do
curl -L --retry 3 -o "$FFMPEG_TARBALL" "$url" 2>&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 "==============================================================="