Android系统集成和使用FFmpeg

发布于:2024-07-05 ⋅ 阅读:(19) ⋅ 点赞:(0)

文章目录

  • 前言
  • 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下载即可。如下图所示:
NDK下载
我使用的版本是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中其他模块使用时,引用上述库即可。