QtMultimedia on Android
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_SDK_ROOT" ] || [ -z "$ANDROID_NDK_ROOT" ] || [ -z "$HOST_ARCH" ] || [ -z "$FFMPEG_LIBRARY_PATH" ]; then
echo "Please set ANDROID_SDK_ROOT, 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
3- Set Environment Variables
Set the environment variables as they are needed to build ffmpeg
export ANDROID_SDK_ROOT=android_sdk_location (i.e ~/Library/Android/sdk)
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
export ANDROID_OPENSSL_INCLUDE=openssl_include_location
export ANDROID_OPENSSL_LIBS=openssl_libs_location
After generating the FFmpeg libraries, configure QtMultimedia with the appropriate flags:
cd /path/to/qt/source
./configure ....
-D OPENSSL_INCLUDE_DIR=openssl_include_folder_path
-D FFMPEG_DIR:PATH=ffmpeg_built_libs_path
Check how to build Qt from source for Android