使用Ubuntu编译FFmpeg生成Android动态库/静态库

环境

我这里使用windows里的wsl2的ubuntu,使用物理机或者vmware,vbox之类的安装的ubuntu理论上也可以.
gcc编译使用的环境如下:
Ndk使用17
FFmpeg使用4.0.2.

clang编译使用的环境如下:
Ndk使用21.4
FFmpeg使用6.1

FFmpeg下载地址:https://ffmpeg.org/releases/
Ndk下载地址在Android官网

准备

把下载到的FFmpeg,ndk解压,注意ndk下载的是linux版本的,因为接下来会在ubuntu下编译

编写编译脚本

由于Ndk在17或以下的版本默认使用Gcc编译而17以上的版本使用Clang所以这里介绍两种编译方式。

Gcc编译

编写sh脚本

由于编译的命令并非一两条命令可以完成的所以我们需要使用.sh脚本保存起来,编写完成之后执行该脚本
在ffmpeg源码根目录新建一个.sh后缀的文件,我这里的命名为ffbuild.sh。以下为该文件的内容

# NDK目录
NDK_ROOT=/mnt/c/Users/Administrator/ubuntu_dev/ndk/android-ndk-r17c/android-ndk-r17c
# ndk对应平台编译器所在目录
TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

PREFIX=./android/ffmpeg

./configure \
--prefix=$PREFIX \
--disable-x86asm \
--enable-small \
--disable-programs \
--disable-avdevice \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--sysroot=$NDK_ROOT/platforms/android-23/arch-arm \
--extra-cflags="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=23 -U_FILE_OFFSET_BITS  -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fPIC" \
--arch=arm \
--target-os=android 

make clean
make -j20 install

以上命令的一些解释:
PREFIX:你编译好的库输出的目录
–PREFIX=./android/ffmpeg
指定输出路径

–enable-small
优化大小

–disable-programs
不编译ffmpeg程序(命令行工具)

----disable-avdevice
关闭avdevice模块 在安卓中无用

–disable-encoders
关闭所有编码器

–disable-filter
关闭所有滤镜

–enable-cross-compile
开启交叉编译

–cross-prefix
查找ndk的gcc(编译器)

–sysroot
寻找ndk所有的库文件

–disable-shared
关闭动态库输出

–extra-cflags
传给编译器的参数

–arch=arm
如果编译的是64位库则写成arm64

–target-os=android
目标系统

make clean
每次编译前都清理上一次运行产生的文件

make -j20 install
-j20的意思是并行20个线程,推荐写成你的cpu核心数

编译64位略有不同:

# NDK目录
NDK_ROOT=/mnt/c/Users/Administrator/ubuntu_dev/ndk/android-ndk-r17c/android-ndk-r17c
# ndk对应平台编译器所在目录
TOOLCHAIN=$NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64

PREFIX=./android/ffmpeg64

./configure \
--prefix=$PREFIX \
--disable-x86asm \
--enable-small \
--disable-programs \
--disable-avdevice \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \
--sysroot=$NDK_ROOT/platforms/android-23/arch-arm64 \
--extra-cflags="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=23 -U_FILE_OFFSET_BITS -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv8-a -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC" \
--arch=aarch64 \
--target-os=android \
--enable-shared


make clean
make -j20 install

执行命令

sudo sh xxx.sh

编译结果

很多时候会报错,一般报错之后都是编译失败了。可以停止编译,查看输出的信息去修改对应的命令。
如果控制台输出的信息判断不了是什么问题可以查看编译日志(以我这里为例):./ffbuild/config.log。
很多时候就是因为编译的命令路径问题或者版本问题导致的,有时候也因为linux发行版依赖的一些库缺失。

Clang编译

Clang编译与gcc编译基本一致,这里我们使用Ndk21.4和当下最新的FFmpeg6.1为例

编写sh脚本

与上面一致编写shell:

# NDK目录
NDK_ROOT=/mnt/c/Users/Administrator/ubuntu_dev/ndk/android-ndk-r21e
# ndk对应平台编译器所在目录
TOOLCHAIN=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64
# 需要编译出的平台,这里是 arm64-v8a
ARCH=aarch64

# 支持的最低 Android API
API=23

PREFIX=./android/ffmpeg64

  ./configure \
  --target-os=android \
  --prefix=$PREFIX \
  --arch=$ARCH \
  --sysroot=$TOOLCHAIN/sysroot \
  --disable-static \
  --disable-ffmpeg \
  --disable-ffplay \
  --disable-ffprobe \
  --disable-debug \
  --disable-doc \
  --disable-avdevice \
  --enable-shared \
  --enable-cross-compile \
  --cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \
  --cc=$TOOLCHAIN/bin/aarch64-linux-android$API-clang \
  --cxx=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++ \
  --extra-cflags="-fpic"

make clean all
make -j20 install

可见这里的脚本与上面差不多,只是编写更加规范,常修改的值都提取出来作为变量,方便日后修改编译

使用ndk22或以上

参考脚本:

#!/bin/bash

# NDK目录
NDK_ROOT=/mnt/c/Users/Administrator/ubuntu_dev/ndk/android-ndk-r22b
# ndk对应平台编译器所在目录
TOOLCHAIN=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64

#配置交叉编译环境的根路径
SYSROOT=$TOOLCHAIN/sysroot
#NDK新版本使用llvm-ar, llvm-nm, llvm-strip等
CROSS_PREFIX_LLVM=$TOOLCHAIN/bin/llvm-

#arm64-v8a
API=30
ARCH=arm64
CPU=armv8-a
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
CROSS_PREFIX_CLANG="$TOOLCHAIN/bin/aarch64-linux-android$API"
OPTIMIZE_CFLAGS="-march=$CPU"
OUTPUT=./android/$CPU

#armeabi-v7a
#API=30
#ARCH=arm
#CPU=armv7-a
#CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
#CROSS_PREFIX_CLANG="$TOOLCHAIN/bin/armv7a-linux-androideabi$API"
#OPTIMIZE_CFLAGS="-march=$CPU"
#OUTPUT=./android/$CPU
#   --disable-static \
#   --enable-shared \
build()
{
    ./configure \
    --prefix=$OUTPUT \
    --target-os=android \
    --arch=$ARCH \
    --cpu=$CPU \
    --enable-neon \
    --enable-cross-compile \
    --enable-jni \
    --enable-mediacodec \
    --enable-decoder=h264_mediacodec \
    --enable-decoder=hevc_mediacodec \
    --enable-decoder=mpeg4_mediacodec \
    --disable-vulkan \
    --disable-asm \
    --disable-doc \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-symver \
    --disable-ffmpeg \
    --disable-avdevice \
    --disable-debug \
    --disable-postproc \
    --sysroot=$SYSROOT \
    --cross-prefix=$CROSS_PREFIX \
    --cross_prefix_clang=$CROSS_PREFIX_CLANG- \
    --cross_prefix_llvm=$CROSS_PREFIX_LLVM \
    --extra-cflags="-Os -fpic -DVK_ENABLE_BETA_EXTENSIONS=0 $OPTIMIZE_CFLAGS"
    
    make clean all
    make -j24
    make install
}
build

使用前需要修改一下ffmpeg根目录下的configure文件,修改如下

CMDLINE_SET添加“cross_prefix_clang”和“cross_prefix_llvm”,
然后搜索ar_default找到如图所示的位置,替换:
在这里插入图片描述
然后就可以执行了

现成的FFmpeg库

这里提供作者自己编译好的FFmpeg供大家直接使用:

6.1 https://download.youkuaiyun.com/download/javy_codercoder/88661461
7.0 https://download.youkuaiyun.com/download/javy_codercoder/89247612

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值