QtMultimedia on Android

From Qt Wiki
Jump to navigation Jump to search

Overview

With the introduction of FFmpeg in QtMultimedia for Android starting from version 6.7, developers now have a robust option for handling multimedia tasks. This shift is significant as the MediaCodec-based backend is deprecated from Qt 6.8 and is scheduled for removal in Qt 7.0. Therefore, it is highly recommended to transition to FFmpeg for future-proofing your multimedia applications on Android.

This guide will walk you through the steps to build QtMultimedia with FFmpeg on Android.

Building QtMultimedia with FFmpeg

1- Clone the FFmpeg Repository

Start by cloning the official FFmpeg repository:

git clone git@source.ffmpeg.org:ffmpeg

2- Create a Build Script

Copy the following script into a file named build-ffmpeg-android.sh. This script will be used to build FFmpeg for Android:

#!/bin/bash

helpFunction() {
    echo "Usage: ./build-ffmpeg-android.sh --arch=ARCH --install-path=PATH"
    echo -e "\t--arch            Select architecture [aarch64, armv7, x86, x86_64]"
    echo -e "\t--install-path    Install in PATH used in make install, full path please"
    exit 1
}

# Parse command-line options
for opt in "$@"; do
    case "$opt" in
        --arch=*)
            ARCH="${opt#*=}"
        ;;
        --install-path=*)
            INSTALL_PATH="${opt#*=}"
        ;;
        *)
            helpFunction
        ;;
    esac
done

# Check for empty parameters
if [ -z "$ARCH" ] || [ -z "$INSTALL_PATH" ]; then
    echo "Some or all of the parameters are empty"
    helpFunction
fi

# Check for required environment variables
if [ -z "$ANDROID_NDK_ROOT" ] || [ -z "$HOST_ARCH" ] || [ -z "$FFMPEG_LIBRARY_PATH" ]; then
    echo "Please set ANDROID_NDK_ROOT, HOST_ARCH, and FFMPEG_LIBRARY_PATH."
    exit 1
fi

# Setup architecture-specific variables
case "$ARCH" in
    aarch64)
        TOOLCHAIN_ARCH="aarch64-linux-android"
        CPU="armv8-a"
    ;;
    armv7)
        TOOLCHAIN_ARCH="armv7a-linux-androideabi"
        CPU="armv7-a"
    ;;
    x86)
        TOOLCHAIN_ARCH="i686-linux-android"
        CPU="i686"
    ;;
    x86_64)
        TOOLCHAIN_ARCH="x86_64-linux-android"
        CPU="x86-64"
    ;;
    *)
        echo "Invalid architecture: $ARCH"
        helpFunction
    ;;
esac

ANDROID_OPTIONS="
--target-os=android
--arch=${ARCH}
--cpu=${CPU}
--enable-cross-compile
--enable-jni
--enable-mediacodec
--enable-pthreads
--disable-indev=android_camera
--sysroot=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_ARCH}/sysroot
--sysinclude=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_ARCH}/sysroot/usr/include/
--cc=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_ARCH}/bin/${TOOLCHAIN_ARCH}24-clang
--cxx=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_ARCH}/bin/${TOOLCHAIN_ARCH}24-clang++
--disable-autodetect
--enable-neon
--disable-asm
"

export LDFLAGS="-L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_ARCH}/sysroot/usr/lib/${TOOLCHAIN_ARCH} -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_ARCH}/sysroot/usr/lib/${TOOLCHAIN_ARCH}/24 -lm -ldl -llog"
export CFLAGS="-O3 -Wl,exclude-libs,libgcc.a,libunwind.a"

COMMON_OPTIONS="
--prefix=${INSTALL_PATH}
--enable-static
--disable-shared
--host-os=${HOST_ARCH}
--install-name-dir=${INSTALL_PATH}
--disable-logging
--disable-debug
--disable-programs
--enable-pic
"

pushd ${FFMPEG_LIBRARY_PATH}
make clean
make distclean

echo "./configure ${COMMON_OPTIONS} ${ANDROID_OPTIONS}"
./configure ${COMMON_OPTIONS} ${ANDROID_OPTIONS}

sed -i "s/-fPIE/-fPIC/" ffbuild/config.mak
sed -i "s/-pie/-pic/" ffbuild/config.mak

make -j8 install
popd

Note: When deciding building FFmpeg with openssl dependencies. Make sure the below environment variables are set

export ANDROID_OPENSSL_INCLUDE=openssl_include_location
export ANDROID_OPENSSL_LIBS=openssl_libs_location

Please add the flags below during FFmpeg configuration (Line 99)

--enable-openssl --extra-cflags=-I${ANDROID_OPENSSL_INCLUDE} --extra-ldflags=-L${ANDROID_OPENSSL_LIBS}

3- Set Environment Variables

Set the environment variables as they are needed to build ffmpeg

export ANDROID_NDK_ROOT=android_ndk_location (i.e ~/Library/Android/sdk/ndk/25.1.8937393)
export HOST_ARCH="darwin-x86_64"   // or "linux-x86_64"
export FFMPEG_LIBRARY_PATH=cloned_ffmpeg_location (i.e ~/Workspace/Ffmpeg/ffmpeg-android/ffmpeg)

4- Build FFmpeg for Android

Run the build script to build FFmpeg for the specified architecture:

sh build-ffmpeg-android.sh --arch=aarch64 --install-path=desired_install_path (i.e ../build/arm64-v8a)

5- Configure and Build QtMultimedia

After generating the FFmpeg libraries, configure QtMultimedia with the appropriate flags:

cd /path/to/qt/source
./configure .... 
-D FFMPEG_DIR:PATH=ffmpeg_built_libs_path

If openssl is enabled during FFmpeg configuration make sure you add to the above command

-D OPENSSL_INCLUDE_DIR=openssl_include_folder_path

For more information on how to build qt for Android check Qt from source for Android