一、准备工作:下载所需资源
| 资源 | 版本/说明 | 下载地址 |
|---|---|---|
| FFmpeg 源码 | 7.1.5(与 Qt 6.11 内置版本一致) | https://ffmpeg.org/releases/ffmpeg-7.1.5.tar.gz |
| Android NDK | Windows 版 r26b (26.1.10909125) 或 r26d (26.3.11579264) | https://developer.android.com/ndk/downloads |
| MSYS2 | 提供 Windows 下的类 Unix 编译环境 | https://www.msys2.org/ |
⚠️ 关键点 :NDK 必须下载 Windows 版 (
android-ndk-r26d-windows.zip),不能使用 Linux 版。
这只下载了FFmpeg 7.1.5源码和MSYS2,Android NDK使用QT自带的,目录位于/e/Android/android-sdk/ndk/27.2.12479018
二、配置 MSYS2 编译环境
-
安装 MSYS2 后,打开 MSYS2 MINGW64 终端(不是普通 MSYS2 终端)。
-
安装编译依赖:
bashpacman -S --noconfirm make yasm diffutils -
设置环境变量(根据实际路径修改):
bashexport PATH=/e/Qt/Tools/mingw1310_64/bin:$PATH export ANDROID_NDK_ROOT=/e/Android/android-sdk/ndk/27.2.12479018
三、在 Windows 下编译 FFmpeg for Android
-
解压 FFmpeg 源码到不含中文和空格的路径,例如
/e/ffmpeg/ffmpeg-7.1.5/ffmpeg-7.1.5。 -
在源码目录下创建
build_android.sh:bash#!/bin/bash # 设置目标架构(这里以 arm64-v8a 为例) ARCH=aarch64 CPU=armv8-a TOOLCHAIN_ARCH=aarch64-linux-android # NDK 工具链路径 TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/windows-x86_64 # 最低支持的 Android API 级别,建议与你的 Qt 项目一致 API=28 # 进入源码目录 cd /e/ffmpeg/ffmpeg-7.1.5/ffmpeg-7.1.5 # 配置 FFmpeg ./configure \ --prefix=./install-android/$ARCH \ --target-os=android \ --arch=$ARCH \ --cpu=$CPU \ --enable-cross-compile \ --cross-prefix=$TOOLCHAIN/bin/llvm- \ --cc=$TOOLCHAIN/bin/${TOOLCHAIN_ARCH}${API}-clang \ --cxx=$TOOLCHAIN/bin/${TOOLCHAIN_ARCH}${API}-clang++ \ --sysroot=$TOOLCHAIN/sysroot \ --enable-shared \ --disable-static \ --disable-doc \ --disable-programs \ --enable-network # 开始编译,-j 后面的数字建议设为 CPU 核心数 make -j8 make install -
其他编译方式
3.1 build_x86.sh
bash#!/bin/bash # ========================================= # FFmpeg for Android - x86 # ========================================= set -e export ANDROID_NDK_ROOT=/e/Android/android-sdk/ndk/27.2.12479018 API=28 ABI_NAME="x86" ARCH="x86" CPU="i686" TOOLCHAIN_ARCH="i686-linux-android" case "$(uname -s)" in MINGW*|MSYS*|CYGWIN*) HOST_TAG=windows-x86_64 ;; Linux*) HOST_TAG=linux-x86_64 ;; *) echo "不支持的主机平台"; exit 1 ;; esac TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG SYSROOT=$TOOLCHAIN/sysroot SOURCE_DIR=$(pwd) PREFIX=$SOURCE_DIR/android/$ABI_NAME echo "==========================================" echo " 编译 FFmpeg for $ABI_NAME" echo "==========================================" cd "$SOURCE_DIR" rm -rf "$PREFIX" make distclean 2>/dev/null || true ./configure \ --prefix=$PREFIX \ --target-os=android \ --arch=$ARCH \ --cpu=$CPU \ --enable-cross-compile \ --cross-prefix=$TOOLCHAIN/bin/llvm- \ --cc=$TOOLCHAIN/bin/${TOOLCHAIN_ARCH}${API}-clang \ --cxx=$TOOLCHAIN/bin/${TOOLCHAIN_ARCH}${API}-clang++ \ --ar=$TOOLCHAIN/bin/llvm-ar \ --nm=$TOOLCHAIN/bin/llvm-nm \ --strip=$TOOLCHAIN/bin/llvm-strip \ --ranlib=$TOOLCHAIN/bin/llvm-ranlib \ --sysroot=$SYSROOT \ --enable-shared \ --disable-static \ --disable-doc \ --disable-programs \ --enable-network \ --enable-jni \ --enable-mediacodec \ --disable-asm make -j$(nproc 2>/dev/null || echo 8) make install echo "" echo "? $ABI_NAME 编译完成:$PREFIX" ls -la $PREFIX/lib3.2 build_arm64_v8a.sh
bash#!/bin/bash # ========================================= # FFmpeg for Android - arm64-v8a # ========================================= set -e # ---------- 配置 ---------- export ANDROID_NDK_ROOT=/e/Android/android-sdk/ndk/27.2.12479018 API=28 ABI_NAME="arm64-v8a" ARCH="aarch64" CPU="armv8-a" TOOLCHAIN_ARCH="aarch64-linux-android" # 判断主机平台 case "$(uname -s)" in MINGW*|MSYS*|CYGWIN*) HOST_TAG=windows-x86_64 ;; Linux*) HOST_TAG=linux-x86_64 ;; *) echo "不支持的主机平台"; exit 1 ;; esac TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG SYSROOT=$TOOLCHAIN/sysroot SOURCE_DIR=$(pwd) PREFIX=$SOURCE_DIR/android/$ABI_NAME echo "==========================================" echo " 编译 FFmpeg for $ABI_NAME" echo "==========================================" echo "NDK: $ANDROID_NDK_ROOT" echo "API: $API" echo "输出: $PREFIX" echo "==========================================" # ---------- 清理 ---------- cd "$SOURCE_DIR" rm -rf "$PREFIX" make distclean 2>/dev/null || true # ---------- 配置 ---------- ./configure \ --prefix=$PREFIX \ --target-os=android \ --arch=$ARCH \ --cpu=$CPU \ --enable-cross-compile \ --cross-prefix=$TOOLCHAIN/bin/llvm- \ --cc=$TOOLCHAIN/bin/${TOOLCHAIN_ARCH}${API}-clang \ --cxx=$TOOLCHAIN/bin/${TOOLCHAIN_ARCH}${API}-clang++ \ --ar=$TOOLCHAIN/bin/llvm-ar \ --nm=$TOOLCHAIN/bin/llvm-nm \ --strip=$TOOLCHAIN/bin/llvm-strip \ --ranlib=$TOOLCHAIN/bin/llvm-ranlib \ --sysroot=$SYSROOT \ --enable-shared \ --disable-static \ --disable-doc \ --disable-programs \ --enable-network \ --enable-jni \ --enable-mediacodec # ---------- 编译 ---------- make -j$(nproc 2>/dev/null || echo 8) make install echo "" echo "? $ABI_NAME 编译完成:$PREFIX" ls -la $PREFIX/lib -
赋予执行权限并运行:
bash# 4. 首次使用前赋权 chmod +x build_*.sh # 5. 编译 arm64-v8a ./build_arm64_v8a.sh # 6. 编译其他架构(可选) ./build_armv7.sh ./build_x86.sh ./build_x86_64.sh -
编译成功后,库文件位于
./android/aarch64/。
NDK r26+ 注意 :
--cross-prefix必须为llvm-,编译器名格式为aarch64-linux-android28-clang。显式指定--android-api可避免 "Defaulting to target API 21" 警告。
四、复制库文件到 Qt 项目
将编译生成的 include 和 lib 目录复制到 Qt 项目下:
text
D:\Desktop\WifiUAV_MY\WifiUAV_MY\libs\android\arm64-v8a\
├── include\
│ ├── libavcodec\
│ ├── libavformat\
│ ├── libavutil\
│ └── libswscale\
└── lib\
├── libavcodec.so
├── libavcodec.so.61
├── libavformat.so
├── libavformat.so.61
├── libavutil.so
├── libavutil.so.59
├── libswscale.so
└── libswscale.so.8
重要 :
.so和.so.xx软链接指向的实际文件都要复制,缺一不可
五、修改 .pro 文件
不要使用 $$ANDROID_ABI (它在 qmake 解析阶段为空),直接硬编码 arm64-v8a:
增加自行匹配
bash
# 2. 区分平台配置
android {
FFMPEG_DIR = $$PWD/libs/android
# 根据目标 ABI 选择对应的 FFmpeg 库
contains(ANDROID_TARGET_ARCH, arm64-v8a) {
FFMPEG_ANDROID_DIR = $$FFMPEG_DIR/arm64-v8a
}
contains(ANDROID_TARGET_ARCH, armeabi-v7a) {
FFMPEG_ANDROID_DIR = $$FFMPEG_DIR/armeabi-v7a
}
contains(ANDROID_TARGET_ARCH, x86) {
FFMPEG_ANDROID_DIR = $$FFMPEG_DIR/x86
}
contains(ANDROID_TARGET_ARCH, x86_64) {
FFMPEG_ANDROID_DIR = $$FFMPEG_DIR/x86_64
}
# 兜底:如果没匹配到,默认用 arm64
isEmpty(FFMPEG_ANDROID_DIR) {
FFMPEG_ANDROID_DIR = $$FFMPEG_DIR/arm64-v8a
message("Warning: Unknown ABI, fallback to arm64-v8a")
}
INCLUDEPATH += $$FFMPEG_ANDROID_DIR/include
LIBS += -L$$FFMPEG_ANDROID_DIR/lib \
-lavcodec -lavformat -lavutil -lswscale
} else:win32 {
# Windows 平台:使用项目内置的 Windows FFmpeg
FFMPEG_DIR = $$PWD/lib/ffmpeg
INCLUDEPATH += $$FFMPEG_DIR/include
LIBS += -L$$FFMPEG_DIR/lib \
-lavcodec \
-lavformat \
-lavutil \
-lswscale
} else:unix {
# Linux/Ubuntu 平台:使用系统 FFmpeg 开发包
CONFIG += link_pkgconfig
PKGCONFIG += libavcodec libavformat libavutil libswscale
}
修改后执行:清理项目 → 执行 qmake → 重新构建。