【Linux系统使用NDK交叉编译FFmpeg】

概要

FFmpeg官网有编译好的二进制,下载过来直接可以使用,但是面临一些定制特性,就束手无策了,于是乎,我们还是学习下如何使用NDK编译源代码。

本文所用版本:
FFmpeg:
版本:ffmpeg-5.1.4
官网:https://ffmpeg.org/download.html#releases
Linux:
版本:ubuntu 22
NDK
版本:r21e
官网:https://github.com/android/ndk/wiki/Unsupported-Downloads

编译步骤

  1. 下载安装NDK
  2. 下载FFmpeg源代码
  3. 编写编译脚本
  4. 拷贝生成的so和头文件
  5. android studio进行使用(这部分看情况待续…)

NDK

下载:
进入 https://github.com/android/ndk/wiki/Unsupported-Downloads下载Linux版本即可:
在这里插入图片描述
安装:

  • 解压之后目录如下:

在这里插入图片描述

  • 生成交叉编译工具链:

进入build/tools目录,并执行生成脚本;

cd build/tools
./make-standalone-toolchain.sh --toolchain=arm-linux-androideabi-4.9 --platform=android-19 --install-dir=../../../ndk21

生成交叉编译工具链如下:
在这里插入图片描述

  • 交叉编译工具链添加到环境变量:

执行命令:

vim /etc/profile

在文件最后添加

export ANDROID_NDK=/home/ricky/workspace/tools/ndk21
export PATH=$ANDROID_NDK:$PATH

使环境变量立马生效:

source /etc/profile

验证是否生效,执行命令:

echo $ANDROID_NDK

如果显示路径就成功了,比如:

/home/ricky/workspace/tools/ndk21

FFmpeg

官网简介:
技术性官网,非常简介直接,没半点废话,上来就是我们最常用的下载按钮:
在这里插入图片描述
我们点击进入“MoreRelease”,也就是:
https://ffmpeg.org/download.html#releases
下载ffmpeg-5.1.4

编写编译脚本

#!/bin/bash

PREFIX=/home/ricky/workspace/ffmpeg/build

NDK_HOME=${ANDROID_NDK}

echo "NDK_HOME=${NDK_HOME}"

COMMON_OPTIONS="\
        --target-os=android \
        --disable-static \
        --enable-shared \
        --enable-small \
        --disable-programs \
        --disable-ffmpeg \
        --disable-ffplay \
        --disable-ffprobe \
        --disable-doc \
        --disable-symver \
        --disable-asm \
        "
function build_android {
        ./configure \
        --libdir=${PREFIX}/libs/armeabi-v7a \
        --incdir=${PREFIX}/includes/armeabi-v7a \
        --pkgconfigdir=${PREFIX}/pkgconfig/armeabi-v7a \
        --arch=arm \
        --cpu=armv7-a \
        --cross-prefix="${NDK_HOME}/bin/arm-linux-androideabi-" \
        --sysroot="${NDK_HOME}/sysroot/" \
        --extra-ldexeflags=-pie \
        ${COMMON_OPTIONS}
        make clean
        make -j8 && make install
}

build_android

脚本拷贝到FFmpeg源代码解压后的根目录,并执行:

./build_android.sh

执行完成之后,在脚本的PREFIX=/home/ricky/workspace/ffmpeg/build即可看到如下结果:

ricky@ricky-pc:~/workspace/ffmpeg/build$ tree -L 4
.
├── includes
│   └── armeabi-v7a
│       ├── libavcodec
│       │   ├── ac3_parser.h
│       │   ├── adts_parser.h
│       │   ├── avcodec.h
│       │   ├── avdct.h
│       │   ├── avfft.h
│       │   ├── bsf.h
│       │   ├── codec_desc.h
│       │   ├── codec.h
│       │   ├── codec_id.h
│       │   ├── codec_par.h
│       │   ├── d3d11va.h
│       │   ├── defs.h
│       │   ├── dirac.h
│       │   ├── dv_profile.h
│       │   ├── dxva2.h
│       │   ├── jni.h
│       │   ├── mediacodec.h
│       │   ├── packet.h
│       │   ├── qsv.h
│       │   ├── vdpau.h
│       │   ├── version.h
│       │   ├── version_major.h
│       │   ├── videotoolbox.h
│       │   ├── vorbis_parser.h
│       │   └── xvmc.h
│       ├── libavdevice
│       │   ├── avdevice.h
│       │   ├── version.h
│       │   └── version_major.h
│       ├── libavfilter
│       │   ├── avfilter.h
│       │   ├── buffersink.h
│       │   ├── buffersrc.h
│       │   ├── version.h
│       │   └── version_major.h
│       ├── libavformat
│       │   ├── avformat.h
│       │   ├── avio.h
│       │   ├── version.h
│       │   └── version_major.h
│       ├── libavutil
│       │   ├── adler32.h
│       │   ├── aes_ctr.h
│       │   ├── aes.h
│       │   ├── attributes.h
│       │   ├── audio_fifo.h
│       │   ├── avassert.h
│       │   ├── avconfig.h
│       │   ├── avstring.h
│       │   ├── avutil.h
│       │   ├── base64.h
│       │   ├── blowfish.h
│       │   ├── bprint.h
│       │   ├── bswap.h
│       │   ├── buffer.h
│       │   ├── camellia.h
│       │   ├── cast5.h
│       │   ├── channel_layout.h
│       │   ├── common.h
│       │   ├── cpu.h
│       │   ├── crc.h
│       │   ├── csp.h
│       │   ├── des.h
│       │   ├── detection_bbox.h
│       │   ├── dict.h
│       │   ├── display.h
│       │   ├── dovi_meta.h
│       │   ├── downmix_info.h
│       │   ├── encryption_info.h
│       │   ├── error.h
│       │   ├── eval.h
│       │   ├── ffversion.h
│       │   ├── fifo.h
│       │   ├── file.h
│       │   ├── film_grain_params.h
│       │   ├── frame.h
│       │   ├── hash.h
│       │   ├── hdr_dynamic_metadata.h
│       │   ├── hdr_dynamic_vivid_metadata.h
│       │   ├── hmac.h
│       │   ├── hwcontext_cuda.h
│       │   ├── hwcontext_d3d11va.h
│       │   ├── hwcontext_drm.h
│       │   ├── hwcontext_dxva2.h
│       │   ├── hwcontext.h
│       │   ├── hwcontext_mediacodec.h
│       │   ├── hwcontext_opencl.h
│       │   ├── hwcontext_qsv.h
│       │   ├── hwcontext_vaapi.h
│       │   ├── hwcontext_vdpau.h
│       │   ├── hwcontext_videotoolbox.h
│       │   ├── hwcontext_vulkan.h
│       │   ├── imgutils.h
│       │   ├── intfloat.h
│       │   ├── intreadwrite.h
│       │   ├── lfg.h
│       │   ├── log.h
│       │   ├── lzo.h
│       │   ├── macros.h
│       │   ├── mastering_display_metadata.h
│       │   ├── mathematics.h
│       │   ├── md5.h
│       │   ├── mem.h
│       │   ├── motion_vector.h
│       │   ├── murmur3.h
│       │   ├── opt.h
│       │   ├── parseutils.h
│       │   ├── pixdesc.h
│       │   ├── pixelutils.h
│       │   ├── pixfmt.h
│       │   ├── random_seed.h
│       │   ├── rational.h
│       │   ├── rc4.h
│       │   ├── replaygain.h
│       │   ├── ripemd.h
│       │   ├── samplefmt.h
│       │   ├── sha512.h
│       │   ├── sha.h
│       │   ├── spherical.h
│       │   ├── stereo3d.h
│       │   ├── tea.h
│       │   ├── threadmessage.h
│       │   ├── timecode.h
│       │   ├── time.h
│       │   ├── timestamp.h
│       │   ├── tree.h
│       │   ├── twofish.h
│       │   ├── tx.h
│       │   ├── uuid.h
│       │   ├── version.h
│       │   ├── video_enc_params.h
│       │   └── xtea.h
│       ├── libswresample
│       │   ├── swresample.h
│       │   ├── version.h
│       │   └── version_major.h
│       └── libswscale
│           ├── swscale.h
│           ├── version.h
│           └── version_major.h
├── libs
│   └── armeabi-v7a
│       ├── libavcodec.so
│       ├── libavdevice.so
│       ├── libavfilter.so
│       ├── libavformat.so
│       ├── libavutil.so
│       ├── libswresample.so
│       └── libswscale.so
└── pkgconfig
    └── armeabi-v7a
        ├── libavcodec.pc
        ├── libavdevice.pc
        ├── libavfilter.pc
        ├── libavformat.pc
        ├── libavutil.pc
        ├── libswresample.pc
        └── libswscale.pc

16 directories, 148 files
ricky@ricky-pc:~/workspace/ffmpeg/build$

pkgconfig这种方式其实android并没有使用,可以不拷贝,我编译的是armv7-a版本,新手机可以编译armv8-a,64位高性能

集成到Android Studio工程即可

这个大家应该都会了吧,有同学不会的,我后面可以抽空补充

### FFmpeg NDK 交叉编译指南 为了在 Android 平台上使用 FFmpeg 库,通常需要通过 Android NDK 进行交叉编译。以下是关于如何配置环境并完成 FFmpegNDK 交叉编译的相关说明。 #### 环境准备 首先,确保已安装以下工具和依赖项: - 安装 Android NDK 和 CMake 工具链。 - 下载 FFmpeg 源码至本地目录[^1]。 可以通过 `git` 命令克隆官方仓库中的最新版本源码: ```bash git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg cd ffmpeg ``` #### 配置交叉编译选项 FFmpeg 提供了一个灵活的构建脚本,允许开发者指定目标平台以及所需的架构支持。对于 Android 平台,可以利用 NDK 中预定义的工具链文件来设置交叉编译参数。 创建一个名为 `build_android.sh` 的脚本来自动化此过程: ```bash #!/bin/bash # 设置变量 ANDROID_NDK=/path/to/android_ndk TOOLCHAIN=$ANDROID_NDK/build/tools/make_standalone_toolchain.py API=21 ARCH=arm64-v8a PREFIX=$(pwd)/android_build/$ARCH # 创建工具链 $TOOLCHAIN --api $API --arch $ARCH --install-dir $(pwd)/toolchains/$ARCH export PATH=$(pwd)/toolchains/$ARCH/bin:$PATH export CC=aarch64-linux-android-gcc export AR=aarch64-linux-android-ar export STRIP=aarch64-linux-android-strip ./configure \ --prefix=$PREFIX \ --enable-cross-compile \ --target-os=android \ --arch=arm64 \ --sysroot=$(pwd)/toolchains/$ARCH/sysroot \ --disable-doc \ --disable-ffplay \ --disable-ffprobe \ --disable-symver \ --extra-cflags="-Os -fpic" \ --extra-ldflags="" make clean make -j$(nproc) make install ``` 上述脚本会针对 ARM64 架构生成静态链接库,并将其存储于 `$PREFIX` 路径下。如果需要其他架构的支持(如 armeabi-v7a 或 x86),只需调整 `ARCH` 参数即可重复执行该脚本。 #### 多线程解码支持 自 FFmpeg 版本 0.7.x 开始引入了一种新的封装方式,能够实现多线程解码功能[^2]。因此,在实际开发过程中推荐选用较新版本以获得更优性能表现。 当完成编译后,还需确认动态或静态库已被正确放置到项目工程中,并将 `/local/bin`, `/local/include`, 及 `/local/lib` 添加至系统的 PATH 和编译器搜索路径内[^3]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值