diff --git a/README.md b/README.md index 58fb0c11..a7ca0325 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,33 @@ By downloading and using this script, you are fully aware of this. Use this script at your own risk. I maintain this script in my spare time. Please do not file bug reports for systems other than Debian and macOS, because I don't have the resources or time to maintain different systems. -## Installation +## Requirements to build -### Quick install and run (macOS, Linux) +### macOS -Open your command line and run (curl needs to be installed): +* XCode 10.x or greater + +### Linux + +* Debian >= Buster, Ubuntu => Focal Fossa; other distributions might work too +* Rocky Linux 8 ```bash +# Debian and Ubuntu +$ sudo apt install build-essential curl +# Fedora +$ sudo dnf install @development-tools curl +``` + +## Quick Script Installation + +Note: to enable hardware acceleration, see details below. +### Quick install and build (macOS, Linux) + +Open your command line and run (curl needs to be installed): + +```bash # Without GPL and non-free codes, see https://ffmpeg.org/legal.html $ bash <(curl -s "https://raw.githubusercontent.com/markus-perl/ffmpeg-build-script/master/web-install.sh?v1") @@ -39,12 +58,15 @@ $ bash <(curl -s "https://raw.githubusercontent.com/markus-perl/ffmpeg-build-scr This command downloads the build script and automatically starts the build process. -### Common installation (macOS, Linux) +### Common install and build (macOS, Linux) ```bash $ git clone https://github.com/markus-perl/ffmpeg-build-script.git $ cd ffmpeg-build-script +# Without GPL and non-free codecs $ ./build-ffmpeg --build +# With GPL and non-free codecs +$ ./build-ffmpeg --enable-gpl-and-non-free --build ``` ## Supported Codecs @@ -54,7 +76,7 @@ $ ./build-ffmpeg --build * `libsvtav1`: SVT-AV1 Encoder and Decoder * `aom`: AV1 Video Codec (Experimental and very slow!) * `librav1e`: rust based AV1 encoder (only available if [`cargo` is installed](https://doc.rust-lang.org/cargo/getting-started/installation.html)) -* `libdav1d`: Fastest AV1 decoder developed by the VideoLAN and FFmpeg communities and sponsored by the AOMedia (only available if `meson` and `ninja` are installed) +* `libdav1d`: Fastest AV1 decoder developed by the VideoLAN and FFmpeg communities and sponsored by the AOMedia (only available if `meson` and `ninja` are available) * `fdk_aac`: Fraunhofer FDK AAC Codec * `xvidcore`: MPEG-4 video coding standard * `VP8/VP9/webm`: VP8 / VP9 Video Codec for the WebM video file format @@ -100,45 +122,113 @@ $ ./build-ffmpeg --build * H264 `h264_amf` -### Apple M1 (Apple Silicon) Support +## Build Script Usage -The script also builds FFmpeg on a new MacBook with an Apple Silicon M1 processor. +```bash +Usage: build-ffmpeg [OPTIONS] +Options: + -h, --help Display usage information + --version Display version information + -b, --build Starts the build process + --enable-gpl-and-non-free Enable non-free codecs - https://ffmpeg.org/legal.html + --latest Build latest version of dependencies if newer available + -c, --cleanup Remove all working dirs + --small Prioritize small size over speed and usability; don't build manpages. + --full-static Complete static build of ffmpeg (eg. glibc, pthreads etc...) **only Linux** + Note: Because of the NSS (Name Service Switch), glibc does not recommend static links. +``` -### LV2 Plugin Support +### Notes on static linking -If Python is available, the script will build a ffmpeg binary with lv2 plugin support. +- Because of the NSS (Name Service Switch), glibc does **not recommend** static links. See [more details here](https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked_programs_need_some_shared_libraries_which_is_not_acceptable_for_me.__What_can_I_do.3F). -## Continuous Integration +- The libnpp in the CUDA SDK cannot be statically linked. +- Vaapi cannot be statically linked. -ffmpeg-build-script is very stable. Every commit runs against Linux and macOS -with https://github.com/markus-perl/ffmpeg-build-script/actions to make sure everything works as expected. -## Requirements +## Common full build (macOS, Linux) -### macOS +1) Install the [prerequisites](#requirements-to-build), above. +1) Install optional dependencies, as desired. + - If you have an NVIDIA GPU and want to enable CUDA acceleration, please refer to [these instructions](#Cuda-installation) to install the SDK. -* XCode 10.x or greater + - If you have an AMD GPU and want to enable AMF acceleration, please refer to [these instructions](#amf-installation) to install the drivers. -### Linux + - If you want to enable Vaapi acceleration (for most GPUs), please refer to [these instructions](#Vaapi-installation) to install the driver. -* Debian >= Buster, Ubuntu => Focal Fossa, other Distributions might work too -* Rocky Linux 8 -* A development environment and curl is required + - If you want the `librav1e` AV1 encoder, please install [rust](https://doc.rust-lang.org/cargo/getting-started/installation.html) to get `cargo` for the build process. Be sure to start a new shell before building, so that `cargo` is in the new path. If desired, it can be removed with `rustup self uninstall` after the build is complete. + + - If you want the `dav1d` AV1 decoder, please ensure that `python3` is installed. If using the system python installation, also ensure that `meson` and `ninja` are installed before running (otherwise the script will try to install them using `pip3`). + + - If you want the `Lv2` filter plugin, please ensure that `python3` is installed. + +1) Run the downoaded build script from the current directory, with your desired [options](#build-script-usage). + ```bash + $ ./build-ffmpeg [your parameters here] --build + ``` + - Packages will be under the `packages/` subdirectory. + - Build results will be under the `workspace/` subdirectory. + + Upon completion, build-ffmpeg will prompt you for whether to install. + +1) Once installed, if you are satisfied with your ffmpeg build, the ffmpeg-build-script directory can be removed completely. + +### CUDA installation + +CUDA is a parallel computing platform developed by NVIDIA. To be able to compile ffmpeg with CUDA support, you first +need a compatible NVIDIA GPU and the NVIDIA compiler nvcc from the CUDA toolkit. + +- Ubuntu: To install the CUDA toolkit on Ubuntu, run + ```bash + sudo apt install nvidia-cuda-toolkit + ``` + After compilation, you can run + ```bash + sudo apt install nvidia-cuda-dev && sudo apt remove nvidia-cuda-toolkit + ``` + This removes the compilers but leaves the needed shared library `libnpp`. + +- Other Linux distributions: Once you have the GPU and display driver installed, you can follow the + [official instructions](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html) + or [this blog](https://www.pugetsystems.com/labs/hpc/How-To-Install-CUDA-10-1-on-Ubuntu-19-04-1405/) + to setup the CUDA toolkit. + +### Vaapi installation + +You will need the libva driver, so please install it below. ```bash # Debian and Ubuntu -$ sudo apt install build-essential curl +$ sudo apt install libva-dev vainfo -# Fedora -$ sudo dnf install @development-tools curl +# Fedora and CentOS +$ sudo dnf install libva-devel libva-intel-driver libva-utils ``` -### Build in Docker (Linux) +### AMF installation + +To use the AMF encoder, you will need to be using the AMD GPU Pro drivers with OpenCL support. +Download the drivers from https://www.amd.com/en/support and install the appropriate opencl versions. + +```bash +./amdgpu-pro-install -y --opencl=rocr,legacy +``` + +### LV2 Plugin Support + +If python 3 is available, the script will build a ffmpeg binary with [Lv2 filter](https://github.com/lv2/lv2/wiki) plugin support. + +### Apple M1 (Apple Silicon) Support + +The script also builds FFmpeg on a new MacBook with an Apple Silicon M1 processor. + + +## Build in Docker (Linux) With Docker, FFmpeg can be built reliably without altering the host system. Also, there is no need to have the CUDA SDK installed outside of the Docker image. -##### Default +#### Default If you're running an operating system other than the one above, a completely static build may work. To build a full statically linked binary inside Docker, just run the following command: @@ -147,10 +237,10 @@ statically linked binary inside Docker, just run the following command: $ docker build --tag=ffmpeg:default --output type=local,dest=build -f Dockerfile . ``` -##### CUDA +#### CUDA These builds are always built with the --enable-gpl-and-non-free switch, as CUDA is non-free. See https://ffmpeg.org/legal.html -```bash +```bash ## Start the build $ docker build --tag=ffmpeg:cuda --output type=local,dest=build -f cuda-ubuntu.dockerfile . ``` @@ -170,7 +260,7 @@ $ ls build/lib libnppc.so.11 libnppicc.so.11 libnppidei.so.11 libnppig.so.11 ``` -##### Full static version +#### Full static version If you're running an operating system other than the one above, a completely static build may work. To build a full statically linked binary inside Docker, just run the following command: @@ -204,70 +294,6 @@ $ sudo docker build --tag=ffmpeg:cuda -f cuda-ubuntu.dockerfile . $ sudo docker run --gpus all ffmpeg-cuda -hwaccel cuvid -c:v h264_cuvid -i https://files.coconut.co.s3.amazonaws.com/test.mp4 -c:v hevc_nvenc -vf scale_npp=-1:1080 - > test.mp4 ``` -### Common build (macOS, Linux) - -If you want to enable CUDA, please refer to [these](#Cuda-installation) and install the SDK. - -If you want to enable Vaapi, please refer to [these](#Vaapi-installation) and install the driver. - -```bash -$ ./build-ffmpeg --build -``` - -## Cuda installation - -CUDA is a parallel computing platform developed by NVIDIA. To be able to compile ffmpeg with CUDA support, you first -need a compatible NVIDIA GPU. - -- Ubuntu: To install the CUDA toolkit on Ubuntu, run "sudo apt install nvidia-cuda-toolkit" -- Other Linux distributions: Once you have the GPU and display driver installed, you can follow the - [official instructions](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html) - or [this blog](https://www.pugetsystems.com/labs/hpc/How-To-Install-CUDA-10-1-on-Ubuntu-19-04-1405/) - to setup the CUDA toolkit. - -## Vaapi installation - -You will need the libva driver, so please install it below. - -```bash -# Debian and Ubuntu -$ sudo apt install libva-dev vainfo - -# Fedora and CentOS -$ sudo dnf install libva-devel libva-intel-driver libva-utils -``` - -## AMF installation - -To use the AMF encoder, you will need to be using the AMD GPU Pro drivers with OpenCL support. -Download the drivers from https://www.amd.com/en/support and install the appropriate opencl versions. - -```bash -./amdgpu-pro-install -y --opencl=rocr,legacy -``` - -## Usage - -```bash -Usage: build-ffmpeg [OPTIONS] -Options: - -h, --help Display usage information - --version Display version information - -b, --build Starts the build process - --enable-gpl-and-non-free Enable non-free codecs - https://ffmpeg.org/legal.html - --latest Build latest version of dependencies if newer available - -c, --cleanup Remove all working dirs - --full-static Complete static build of ffmpeg (eg. glibc, pthreads etc...) **only Linux** - Note: Because of the NSS (Name Service Switch), glibc does not recommend static links. -``` - -## Notes of static link - -- Because of the NSS (Name Service Switch), glibc does **not recommend** static links. See detail - below: https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked_programs_need_some_shared_libraries_which_is_not_acceptable_for_me.__What_can_I_do.3F - -- The libnpp in the CUDA SDK cannot be statically linked. -- Vaapi cannot be statically linked. Contact ------- @@ -281,6 +307,12 @@ Tested on * Debian 10 * Ubuntu 20.04 +## Continuous Integration + +ffmpeg-build-script is very stable. Every commit runs against Linux and macOS +with https://github.com/markus-perl/ffmpeg-build-script/actions to make sure everything works as expected. + + Example ------- diff --git a/build-ffmpeg b/build-ffmpeg index 5bc91684..9fa604c2 100755 --- a/build-ffmpeg +++ b/build-ffmpeg @@ -17,6 +17,7 @@ MACOS_M1=false CONFIGURE_OPTIONS=() NONFREE_AND_GPL=false LATEST=false +MANPAGES=1 # Check for Apple Silicon if [[ ("$(uname -m)" == "arm64") && ("$OSTYPE" == "darwin"*) ]]; then @@ -205,6 +206,7 @@ usage() { echo " --enable-gpl-and-non-free Enable GPL and non-free codecs - https://ffmpeg.org/legal.html" echo " -c, --cleanup Remove all working dirs" echo " --latest Build latest version of dependencies if newer available" + echo " --small Prioritize small size over speed and usability; don't build manpages" echo " --full-static Build a full static FFmpeg binary (eg. glibc, pthreads etc...) **only Linux**" echo " Note: Because of the NSS (Name Service Switch), glibc does not recommend static links." echo "" @@ -247,6 +249,10 @@ while (($# > 0)); do if [[ "$1" == "--latest" ]]; then LATEST=true fi + if [[ "$1" == "--small" ]]; then + CONFIGURE_OPTIONS+=("--enable-small" "--disable-doc") + MANPAGES=0 + fi shift ;; *) @@ -873,12 +879,12 @@ if [[ "$OSTYPE" == "linux-gnu" ]]; then if build "nv-codec" "11.1.5.2"; then download "https://github.com/FFmpeg/nv-codec-headers/releases/download/n11.1.5.2/nv-codec-headers-11.1.5.2.tar.gz" execute make PREFIX="${WORKSPACE}" - execute make PREFIX="${WORKSPACE}/usr" install + execute make PREFIX="${WORKSPACE}" install build_done "nv-codec" "11.1.5.2" fi CFLAGS+=" -I/usr/local/cuda/include" LDFLAGS+=" -L/usr/local/cuda/lib64" - CONFIGURE_OPTIONS+=("--enable-cuda-nvcc" "--enable-cuvid" "--enable-nvenc" "--enable-cuda-llvm") + CONFIGURE_OPTIONS+=("--enable-cuda-nvcc" "--enable-cuvid" "--enable-nvdec" "--enable-nvenc" "--enable-cuda-llvm" "--enable-ffnvcodec") if [ -z "$LDEXEFLAGS" ]; then CONFIGURE_OPTIONS+=("--enable-libnpp") # Only libnpp cannot be statically linked. @@ -886,6 +892,8 @@ if [[ "$OSTYPE" == "linux-gnu" ]]; then # https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/ CONFIGURE_OPTIONS+=("--nvccflags=-gencode arch=compute_52,code=sm_52") + else + CONFIGURE_OPTIONS+=("--disable-ffnvcodec") fi # Vaapi doesn't work well with static links FFmpeg. @@ -918,18 +926,21 @@ if [[ "$OSTYPE" == "darwin"* ]]; then EXTRA_VERSION="${FFMPEG_VERSION}" fi +if [ -d "$CWD/.git" ]; then + echo -e "\nTemporarily moving .git dir to .git.bak to workaround ffmpeg build bug" #causing ffmpeg version number to be wrong + mv "$CWD/.git" "$CWD/.git.bak" + # if build fails below, .git will remain in the wrong place... +fi + build "ffmpeg" "$FFMPEG_VERSION" download "https://github.com/FFmpeg/FFmpeg/archive/refs/heads/release/$FFMPEG_VERSION.tar.gz" "FFmpeg-release-$FFMPEG_VERSION.tar.gz" # shellcheck disable=SC2086 ./configure "${CONFIGURE_OPTIONS[@]}" \ --disable-debug \ - --disable-doc \ --disable-shared \ --enable-pthreads \ --enable-static \ - --enable-small \ --enable-version3 \ - --disable-ffnvcodec \ --extra-cflags="${CFLAGS}" \ --extra-ldexeflags="${LDEXEFLAGS}" \ --extra-ldflags="${LDFLAGS}" \ @@ -942,9 +953,19 @@ download "https://github.com/FFmpeg/FFmpeg/archive/refs/heads/release/$FFMPEG_VE execute make -j $MJOBS execute make install -INSTALL_FOLDER="/usr/bin" +if [ -d "$CWD/.git.bak" ]; then + mv "$CWD/.git.bak" "$CWD/.git" +fi + +INSTALL_FOLDER="/usr" # not recommended, overwrites system ffmpeg package if [[ "$OSTYPE" == "darwin"* ]]; then - INSTALL_FOLDER="/usr/local/bin" + INSTALL_FOLDER="/usr/local" +else + if [ -d "$HOME/.local" ]; then # systemd-standard user path + INSTALL_FOLDER="$HOME/.local" + elif [ -d "/usr/local" ]; then + INSTALL_FOLDER="/usr/local" + fi fi verify_binary_type @@ -956,34 +977,33 @@ echo "- ffprobe: $WORKSPACE/bin/ffprobe" echo "- ffplay: $WORKSPACE/bin/ffplay" echo "" +INSTALL_NOW=0 if [[ "$AUTOINSTALL" == "yes" ]]; then - if command_exists "sudo"; then - sudo cp "$WORKSPACE/bin/ffmpeg" "$INSTALL_FOLDER/ffmpeg" - sudo cp "$WORKSPACE/bin/ffprobe" "$INSTALL_FOLDER/ffprobe" - sudo cp "$WORKSPACE/bin/ffplay" "$INSTALL_FOLDER/ffplay" - echo "Done. FFmpeg is now installed to your system." - else - cp "$WORKSPACE/bin/ffmpeg" "$INSTALL_FOLDER/ffmpeg" - cp "$WORKSPACE/bin/ffprobe" "$INSTALL_FOLDER/ffprobe" - cp "$WORKSPACE/bin/ffplay" "$INSTALL_FOLDER/ffplay" - echo "Done. FFmpeg is now installed to your system." - fi + INSTALL_NOW=1 elif [[ ! "$SKIPINSTALL" == "yes" ]]; then read -r -p "Install these binaries to your $INSTALL_FOLDER folder? Existing binaries will be replaced. [Y/n] " response case $response in - [yY][eE][sS] | [yY]) - if command_exists "sudo"; then - sudo cp "$WORKSPACE/bin/ffmpeg" "$INSTALL_FOLDER/ffmpeg" - sudo cp "$WORKSPACE/bin/ffprobe" "$INSTALL_FOLDER/ffprobe" - sudo cp "$WORKSPACE/bin/ffplay" "$INSTALL_FOLDER/ffplay" - else - cp "$WORKSPACE/bin/ffmpeg" "$INSTALL_FOLDER/ffmpeg" - cp "$WORKSPACE/bin/ffprobe" "$INSTALL_FOLDER/ffprobe" - cp "$WORKSPACE/bin/ffplay" "$INSTALL_FOLDER/ffplay" - fi - echo "Done. FFmpeg is now installed to your system." + "" | [yY][eE][sS] | [yY]) + INSTALL_NOW=1 ;; esac fi +if [ "$INSTALL_NOW" = 1 ]; then + if command_exists "sudo" && [[ $INSTALL_FOLDER == /usr* ]]; then + SUDO=sudo + fi + $SUDO cp "$WORKSPACE/bin/ffmpeg" "$INSTALL_FOLDER/bin/ffmpeg" + $SUDO cp "$WORKSPACE/bin/ffprobe" "$INSTALL_FOLDER/bin/ffprobe" + $SUDO cp "$WORKSPACE/bin/ffplay" "$INSTALL_FOLDER/bin/ffplay" + if [ $MANPAGES = 1 ]; then + $SUDO mkdir -p "$INSTALL_FOLDER/share/man/man1" + $SUDO cp "$WORKSPACE/share/man/man1"/ff* "$INSTALL_FOLDER/share/man/man1" + if command_exists "mandb"; then + $SUDO mandb -q + fi + fi + echo "Done. FFmpeg is now installed to your system." +fi + exit 0