Files
lpms/install_ffmpeg.sh
2025-04-18 13:48:23 +05:30

243 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
set -exuo pipefail
ROOT="${1:-$HOME}"
NPROC="${NPROC:-$(nproc)}"
EXTRA_CFLAGS=""
EXTRA_LDFLAGS=""
EXTRA_X264_FLAGS=""
EXTRA_FFMPEG_FLAGS=""
BUILD_TAGS="${BUILD_TAGS:-}"
# Build platform flags
BUILDOS=$(uname -s | tr '[:upper:]' '[:lower:]')
BUILDARCH=$(uname -m | tr '[:upper:]' '[:lower:]')
if [[ $BUILDARCH == "aarch64" ]]; then
BUILDARCH=arm64
fi
if [[ $BUILDARCH == "x86_64" ]]; then
BUILDARCH=amd64
fi
# Override these for cross-compilation
export GOOS="${GOOS:-$BUILDOS}"
export GOARCH="${GOARCH:-$BUILDARCH}"
echo "BUILDOS: $BUILDOS"
echo "BUILDARCH: $BUILDARCH"
echo "GOOS: $GOOS"
echo "GOARCH: $GOARCH"
function check_sysroot() {
if ! stat $SYSROOT >/dev/null; then
echo "cross-compilation sysroot not found at $SYSROOT, try setting SYSROOT to the correct path"
exit 1
fi
}
if [[ "$BUILDARCH" == "amd64" && "$BUILDOS" == "linux" && "$GOARCH" == "arm64" && "$GOOS" == "linux" ]]; then
echo "cross-compiling linux-amd64 --> linux-arm64"
export CC="clang-14"
export STRIP="llvm-strip-14"
export AR="llvm-ar-14"
export RANLIB="llvm-ranlib-14"
export CFLAGS="--target=aarch64-linux-gnu"
export LDFLAGS="--target=aarch64-linux-gnu"
EXTRA_CFLAGS="--target=aarch64-linux-gnu -I/usr/local/cuda_arm64/include $EXTRA_CFLAGS"
EXTRA_LDFLAGS="-fuse-ld=lld --target=aarch64-linux-gnu -L/usr/local/cuda_arm64/lib64 $EXTRA_LDFLAGS"
EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=aarch64 --enable-cross-compile --cc=clang-14 --strip=llvm-strip-14"
HOST_OS="--host=aarch64-linux-gnu"
fi
if [[ "$BUILDARCH" == "arm64" && "$BUILDOS" == "darwin" && "$GOARCH" == "arm64" && "$GOOS" == "linux" ]]; then
SYSROOT="${SYSROOT:-"/tmp/sysroot-aarch64-linux-gnu"}"
check_sysroot
echo "cross-compiling darwin-arm64 --> linux-arm64"
LLVM_PATH="${LLVM_PATH:-/opt/homebrew/opt/llvm/bin}"
if [[ ! -f "$LLVM_PATH/ld.lld" ]]; then
echo "llvm linker not found at '$LLVM_PATH/ld.lld'. try 'brew install llvm' or set LLVM_PATH to your LLVM bin directory"
exit 1
fi
export CC="$LLVM_PATH/clang --sysroot=$SYSROOT"
export AR="/opt/homebrew/opt/llvm/bin/llvm-ar"
export RANLIB="/opt/homebrew/opt/llvm/bin/llvm-ranlib"
EXTRA_CFLAGS="--target=aarch64-linux-gnu $EXTRA_CFLAGS"
EXTRA_LDFLAGS="--target=aarch64-linux-gnu -fuse-ld=$LLVM_PATH/ld.lld $EXTRA_LDFLAGS"
EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=aarch64 --enable-cross-compile --cc=$LLVM_PATH/clang --sysroot=$SYSROOT --ar=$AR --ranlib=$RANLIB --target-os=linux"
EXTRA_X264_FLAGS="$EXTRA_X264_FLAGS --sysroot=$SYSROOT --ar=$AR --ranlib=$RANLIB"
HOST_OS="--host=aarch64-linux-gnu"
fi
if [[ "$BUILDOS" == "linux" && "$GOARCH" == "amd64" && "$GOOS" == "windows" ]]; then
echo "cross-compiling linux-$BUILDARCH --> windows-amd64"
SYSROOT="${SYSROOT:-"/usr/x86_64-w64-mingw32"}"
check_sysroot
EXTRA_CFLAGS="-L$SYSROOT/lib -I$SYSROOT/include $EXTRA_CFLAGS"
EXTRA_LDFLAGS="-L$SYSROOT/lib $EXTRA_LDFLAGS"
EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=x86_64 --enable-cross-compile --cross-prefix=x86_64-w64-mingw32- --target-os=mingw64 --sysroot=$SYSROOT"
EXTRA_X264_FLAGS="$EXTRA_X264_FLAGS --cross-prefix=x86_64-w64-mingw32- --sysroot=$SYSROOT"
HOST_OS="--host=mingw64"
# Workaround for https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=967969
export PKG_CONFIG_LIBDIR="/usr/local/x86_64-w64-mingw32/lib/pkgconfig"
EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --pkg-config=$(which pkg-config)"
fi
if [[ "$BUILDARCH" == "amd64" && "$BUILDOS" == "darwin" && "$GOARCH" == "arm64" && "$GOOS" == "darwin" ]]; then
echo "cross-compiling darwin-amd64 --> darwin-arm64"
EXTRA_CFLAGS="$EXTRA_CFLAGS --target=arm64-apple-macos11"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS --target=arm64-apple-macos11"
HOST_OS="--host=aarch64-darwin"
EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=aarch64 --enable-cross-compile"
fi
# Windows (MSYS2) needs a few tweaks
if [[ "$BUILDOS" == *"MSYS"* ]]; then
ROOT="/build"
export PATH="$PATH:/usr/bin:/mingw64/bin"
export C_INCLUDE_PATH="${C_INCLUDE_PATH:-}:/mingw64/lib"
export PATH="$ROOT/compiled/bin":$PATH
export PKG_CONFIG_PATH=/mingw64/lib/pkgconfig
export TARGET_OS="--target-os=mingw64"
export HOST_OS="--host=x86_64-w64-mingw32"
export BUILD_OS="--build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32"
# Needed for mbedtls
export WINDOWS_BUILD=1
fi
export PATH="$ROOT/compiled/bin:${PATH}"
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:-}:$ROOT/compiled/lib/pkgconfig"
mkdir -p "$ROOT/"
# NVENC only works on Windows/Linux
if [[ "$GOOS" != "darwin" ]]; then
if [[ ! -e "$ROOT/nv-codec-headers" ]]; then
git clone --depth 1 --single-branch --branch n12.2.72.0 https://github.com/FFmpeg/nv-codec-headers.git "$ROOT/nv-codec-headers"
cd $ROOT/nv-codec-headers
make -e PREFIX="$ROOT/compiled"
make install -e PREFIX="$ROOT/compiled"
fi
fi
if [[ "$GOOS" != "windows" && "$GOARCH" == "amd64" ]]; then
if [[ ! -e "$ROOT/nasm-2.14.02" ]]; then
# sudo apt-get -y install asciidoc xmlto # this fails :(
cd "$ROOT"
curl -o nasm-2.14.02.tar.gz "https://gstreamer.freedesktop.org/src/mirror/nasm-2.14.02.tar.xz"
echo 'e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5 nasm-2.14.02.tar.gz' >nasm-2.14.02.tar.gz.sha256
sha256sum -c nasm-2.14.02.tar.gz.sha256
tar xf nasm-2.14.02.tar.gz
rm nasm-2.14.02.tar.gz nasm-2.14.02.tar.gz.sha256
cd "$ROOT/nasm-2.14.02"
./configure --prefix="$ROOT/compiled"
make -j$NPROC
make -j$NPROC install || echo "Installing docs fails but should be OK otherwise"
fi
fi
if [[ ! -e "$ROOT/x264" ]]; then
git clone http://git.videolan.org/git/x264.git "$ROOT/x264"
cd "$ROOT/x264"
if [[ $GOARCH == "arm64" ]]; then
# newer git master, compiles on Apple Silicon
git checkout 66a5bc1bd1563d8227d5d18440b525a09bcf17ca
else
# older git master, does not compile on Apple Silicon
git checkout 545de2ffec6ae9a80738de1b2c8cf820249a2530
fi
./configure --prefix="$ROOT/compiled" --enable-pic --enable-static ${HOST_OS:-} --disable-cli --extra-cflags="$EXTRA_CFLAGS" --extra-asflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" $EXTRA_X264_FLAGS || (cat $ROOT/x264/config.log && exit 1)
make -j$NPROC
make -j$NPROC install-lib-static
fi
if [[ ! -e "$ROOT/zlib-1.2.11" ]]; then
cd "$ROOT"
curl -o zlib-1.2.11.tar.gz https://zlib.net/fossils/zlib-1.2.11.tar.gz
tar xf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure --prefix="$ROOT/compiled" --static
make -j$NPROC
make -j$NPROC install
fi
if [[ "$GOOS" == "linux" && "$BUILD_TAGS" == *"debug-video"* ]]; then
sudo apt-get install -y libnuma-dev cmake
if [[ ! -e "$ROOT/x265" ]]; then
git clone https://bitbucket.org/multicoreware/x265_git.git "$ROOT/x265"
cd "$ROOT/x265"
git checkout 17839cc0dc5a389e27810944ae2128a65ac39318
cd build/linux/
cmake -DCMAKE_INSTALL_PREFIX=$ROOT/compiled -G "Unix Makefiles" ../../source
make -j$NPROC
make -j$NPROC install
fi
# VP8/9 support
if [[ ! -e "$ROOT/libvpx" ]]; then
git clone https://chromium.googlesource.com/webm/libvpx.git "$ROOT/libvpx"
cd "$ROOT/libvpx"
git checkout ab35ee100a38347433af24df05a5e1578172a2ae
./configure --prefix="$ROOT/compiled" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --enable-shared --as=nasm
make -j$NPROC
make -j$NPROC install
fi
fi
DISABLE_FFMPEG_COMPONENTS=""
EXTRA_FFMPEG_LDFLAGS="$EXTRA_LDFLAGS"
# all flags which should be present for production build, but should be replaced/removed for debug build
DEV_FFMPEG_FLAGS=""
if [[ "$BUILDOS" == "darwin" && "$GOOS" == "darwin" ]]; then
EXTRA_FFMPEG_LDFLAGS="$EXTRA_FFMPEG_LDFLAGS -framework CoreFoundation -framework Security"
elif [[ "$GOOS" == "windows" ]]; then
EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvenc --enable-decoder=h264_cuvid,hevc_cuvid,vp8_cuvid,vp9_cuvid --enable-filter=scale_cuda,signature_cuda,hwupload_cuda --enable-encoder=h264_nvenc,hevc_nvenc"
elif [[ -e "/usr/local/cuda/lib64" ]]; then
echo "CUDA SDK detected, building with GPU support"
EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --enable-nonfree --enable-cuda-nvcc --enable-libnpp --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvenc --enable-decoder=h264_cuvid,hevc_cuvid,vp8_cuvid,vp9_cuvid --enable-filter=scale_npp,signature_cuda,hwupload_cuda --enable-encoder=h264_nvenc,hevc_nvenc"
else
echo "No CUDA SDK detected, building without GPU support"
fi
if [[ $BUILD_TAGS == *"debug-video"* ]]; then
echo "video debug mode, building ffmpeg with tools, debug info and additional capabilities for running tests"
DEV_FFMPEG_FLAGS="--enable-muxer=md5 --enable-demuxer=hls --enable-filter=ssim,tinterlace --enable-encoder=wrapped_avframe,pcm_s16le "
DEV_FFMPEG_FLAGS+="--enable-shared --enable-debug=3 --disable-stripping --disable-optimizations --enable-encoder=libx265,libvpx_vp8,libvpx_vp9 "
DEV_FFMPEG_FLAGS+="--enable-decoder=hevc,libvpx_vp8,libvpx_vp9 --enable-libx265 --enable-libvpx --enable-bsf=noise "
else
# disable all unnecessary features for production build
DISABLE_FFMPEG_COMPONENTS+=" --disable-doc --disable-sdl2 --disable-iconv --disable-muxers --disable-demuxers --disable-parsers --disable-protocols "
DISABLE_FFMPEG_COMPONENTS+=" --disable-encoders --disable-decoders --disable-filters --disable-bsfs --disable-postproc --disable-lzma "
fi
if [[ ! -e "$ROOT/ffmpeg/libavcodec/libavcodec.a" ]]; then
git clone https://github.com/livepeer/FFmpeg.git "$ROOT/ffmpeg" || echo "FFmpeg dir already exists"
cd "$ROOT/ffmpeg"
git checkout d9751c73e714b01b363483db358b1ea8022c9bea
./configure ${TARGET_OS:-} $DISABLE_FFMPEG_COMPONENTS --fatal-warnings \
--enable-libx264 --enable-gpl \
--enable-protocol=rtmp,file,pipe \
--enable-muxer=mp3,wav,flac,mpegts,hls,segment,mp4,hevc,matroska,webm,flv,null --enable-demuxer=mp3,wav,flac,flv,mpegts,mp4,mov,webm,matroska,image2 \
--enable-bsf=h264_mp4toannexb,aac_adtstoasc,h264_metadata,h264_redundant_pps,hevc_mp4toannexb,extract_extradata \
--enable-parser=mpegaudio,vorbis,opus,flac,aac,aac_latm,h264,hevc,vp8,vp9,png \
--enable-filter=abuffer,buffer,abuffersink,buffersink,afifo,fifo,aformat,format \
--enable-filter=aresample,asetnsamples,fps,scale,hwdownload,select,livepeer_dnn,signature \
--enable-encoder=mp3,vorbis,flac,aac,opus,libx264 \
--enable-decoder=mp3,vorbis,flac,aac,opus,h264,png \
--extra-cflags="${EXTRA_CFLAGS} -I${ROOT}/compiled/include -I/usr/local/cuda/include" \
--extra-ldflags="${EXTRA_FFMPEG_LDFLAGS} -L${ROOT}/compiled/lib -L/usr/local/cuda/lib64" \
--prefix="$ROOT/compiled" \
$EXTRA_FFMPEG_FLAGS \
$DEV_FFMPEG_FLAGS || (tail -100 ${ROOT}/ffmpeg/ffbuild/config.log && exit 1)
# If configure fails, then print the last 100 log lines for debugging and exit.
fi
if [[ ! -e "$ROOT/ffmpeg/libavcodec/libavcodec.a" || $BUILD_TAGS == *"debug-video"* ]]; then
cd "$ROOT/ffmpeg"
make -j$NPROC
make -j$NPROC install
fi