文章目录
- 前言
- FFmpeg源码下载
- 交叉编译
- NDK下载
- x264编译
- 源码下载
- 编译
- FFmpeg编译脚本
- AOSP继承FFmpeg
前言
原生AOSP中并未继承FFmpeg,所以要想在android上使用,需要自己编译集成。
FFmpeg源码下载
git clone https://git.ffmpeg.org/ffmpeg.git
目前最新的release分支是release/7.0,我们编译最新分支
git checkout release/7.0
交叉编译
我们在ubuntu系统下编译出Android系统,也就是arm平台的FFmpeg库。
NDK下载
使用Android Studio下载即可。如下图所示:
我使用的版本是25.0.8775105
x264编译
FFmpeg解码h264时需要使用x264,但是x264是单独的库,需要单独下载编译,然后集成到FFmpeg。
源码下载
git clone http://git.videolan.org/git/x264.git
编译
#!/bin/bash
# 设置 NDK 路径,修改为你的 NDK 实际安装位置
export NDK=/home/zzh/Android/Sdk/ndk/25.0.8775105
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
# 设置目标架构和 API 级别
export API=30
export TARGET=aarch64-linux-android
export PREFIX=$(pwd)/x264_android
# 设置编译器和工具链
export AR=$TOOLCHAIN/bin/llvm-ar
export AS=$TOOLCHAIN/bin/llvm-as
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export NM=$TOOLCHAIN/bin/llvm-nm
export STRINGS=$TOOLCHAIN/bin/llvm-strings
# 配置 x264 编译选项
./configure \
--prefix=$PREFIX \
--disable-asm \
--enable-static \
--enable-pic \
--host=aarch64-linux-android \
--cross-prefix=$TOOLCHAIN/bin/$TARGET$API- \
--sysroot=$TOOLCHAIN/sysroot \
--extra-cflags="-Os -fPIC" \
# 检查 configure 的输出日志
if [ $? -ne 0 ]; then
echo "Configuration failed"
exit 1
fi
# 编译和安装
make -j$(nproc)
if [ $? -ne 0 ]; then
echo "Build failed"
exit 1
fi
make install
if [ $? -ne 0 ]; then
echo "Installation failed"
exit 1
fi
echo "x264 has been successfully built and installed"
FFmpeg编译脚本
x264会以静态库的方式集成到FFmpeg中。
#!/bin/bash
# 设置NDK路径,修改为你的NDK实际安装位置
export NDK=/home/zzh/Android/Sdk/ndk/25.0.8775105
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
# 设置目标架构和API级别
export API=30 # 根据你的需求选择合适的API级别
export TARGET=aarch64-linux-android
export PREFIX=$(pwd)/ffmpeg_android # 输出目录
# 设置编译器和工具链
export AR=$TOOLCHAIN/bin/llvm-ar
export AS=$TOOLCHAIN/bin/llvm-as
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export NM=$TOOLCHAIN/bin/llvm-nm
# 设置x264 pkg-config 路径
export PKG_CONFIG_PATH=/home/zzh/work/x264/x264_android/lib/pkgconfig:$PKG_CONFIG_PATH
# 配置 FFmpeg 编译选项
echo "Configuring FFmpeg..."
./configure \
--prefix=$PREFIX \
--disable-static \
--enable-shared \
--enable-gpl \
--enable-libx264 \
--pkg-config="pkg-config --static" \
--extra-ldflags="-L/home/zzh/work/x264/x264_android/lib" \
--pkg-config-flags="--static" \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-symver \
--disable-w32threads \
--disable-muxer=sctp \
--disable-demuxer=sctp \
--disable-devices \
--disable-postproc \
--cross-prefix=$TOOLCHAIN/bin/$TARGET$API- \
--target-os=android \
--arch=aarch64 \
--enable-cross-compile \
--sysroot=$TOOLCHAIN/sysroot \
--strip=$STRIP \
--nm=$NM 2>&1 | tee configure.log
if [ $? -ne 0 ]; then
echo "Configuration failed"
exit 1
fi
# 编译和安装
echo "Building FFmpeg..."
make -j$(nproc) 2>&1 | tee build.log
if [ $? -ne 0 ]; then
echo "Build failed"
exit 1
fi
make install
if [ $? -ne 0 ]; then
echo "Installation failed"
exit 1
fi
echo "FFmpeg has been successfully built and installed"
以上编译完成后,会在ffmpeg_android目录生成编译产物。
zzh@ubuntu:~/work/ffmpeg/ffmpeg_android$ ll
total 20
drwxrwxr-x 5 zzh zzh 4096 5月 26 22:54 ./
drwxrwxr-x 19 zzh zzh 4096 5月 26 23:37 ../
drwxrwxr-x 8 zzh zzh 4096 5月 26 22:54 include/
drwxrwxr-x 3 zzh zzh 4096 5月 26 23:39 lib/
drwxrwxr-x 3 zzh zzh 4096 5月 26 22:54 share/
AOSP继承FFmpeg
集成目录如下:
zzh@ubuntu:~/work/aosp/android-13.0.0_r44/external/ffmpeg_aarch64$ ls -lh
total 16K
-rw-rw-r-- 1 zzh zzh 1.6K 5月 1 21:45 Android.bp
drwxrwxr-x 8 zzh zzh 4.0K 5月 26 23:57 include
drwxrwxr-x 3 zzh zzh 4.0K 5月 26 23:57 lib
drwxrwxr-x 3 zzh zzh 4.0K 5月 26 23:57 share
Android.bp
// 定义libavutil
cc_prebuilt_library_shared {
name: "libavutil",
srcs: ["lib/libavutil.so"],
export_include_dirs: ["include"],
strip: {
none: true,
},
}
// 定义libswresample
cc_prebuilt_library_shared {
name: "libswresample",
srcs: ["lib/libswresample.so"],
export_include_dirs: ["include"],
shared_libs: [
"libavutil",
],
strip: {
none: true,
},
}
// 定义libswscale
cc_prebuilt_library_shared {
name: "libswscale",
srcs: ["lib/libswscale.so"],
export_include_dirs: ["include"],
shared_libs: [
"libavutil",
],
strip: {
none: true,
},
}
// 定义libavcodec
cc_prebuilt_library_shared {
name: "libavcodec",
srcs: ["lib/libavcodec.so"],
export_include_dirs: ["include"],
shared_libs: [
"libavutil",
"libc",
"libm",
"libswresample",
"libz",
],
strip: {
none: true,
},
}
// 定义libavformat
cc_prebuilt_library_shared {
name: "libavformat",
srcs: ["lib/libavformat.so"],
export_include_dirs: ["include"],
shared_libs: [
"libavcodec",
"libavutil",
"libc",
"libm",
"libz",
],
strip: {
none: true,
},
}
// 定义libavfilter
cc_prebuilt_library_shared {
name: "libavfilter",
srcs: ["lib/libavfilter.so"],
export_include_dirs: ["include"],
shared_libs: [
"libavformat",
"libavcodec",
"libswresample",
"libswscale",
"libavutil",
],
strip: {
none: true,
},
}
AOSP中其他模块使用时,引用上述库即可。