为 Android 编译并集成 FFmpeg 的尝试与踩坑

前言与环境说明

随着 FFmpeg、NDK 与 Android Studio 的不断迭代,本文可能也会像我参考过的过期文章一样失效(很遗憾),但希望本文中提到的问题排查以及步骤说明能够帮到你,如果发现了文章中的谬误以及不足之处也欢迎你提供建议与指正,十分感谢 。

初步目标是使用 FFmpeg 实现 Android 内简单的视频剪辑、添加背景音乐、添加字幕等功能,由于本人初学 Android 开发,能力有限,基础薄弱,无法较为全面地深入学习过程中遇到的问题,文章中可能掺杂有一些知其然而不知其所以然的部分或一些不恰当不精确的个人理解,还请见谅 。

设备:macOS Big Sur 11.6 (Apple Silicon M1)

FFmpeg 版本:4.4

开发环境:

Android Studio Arctic Fox | 2020.3.1 Patch 3 arm64 preview

JavaVersion = 1.8

minSdk : 21

NDK Version : 23.1.7779620

目前 NDK 在苹果芯片下仍只能使用 Rosetta 2 转译后进行使用

CMake Version : 3.22.0-rc2

目前从 Android Studio 内 SDK Manager 中所能取得的最新版为 3.18.1

CMake 已在 3.19.3 版本后提供对苹果芯片的支持

Gradle Version:7.0.3

前置知识准备

在实际上手前,阅读了 Android 与 Java 的官方开发文档与几篇优秀的相关文章,按照自己的理解和知识水平,整理了一些概念的基本且浅显的解释,方便理解下一步要进行的操作。

Native 层

JNI

NDK

交叉编译、建构系统与 CMake

ABI 与动态链接库

FFmpeg

Android 系统的 Native 层

虽然 Android 系统的许多 API 使用 Java 开发,但许多核心 Android 系统组件和服务(如 ART 和 HAL 等)由 C/C++ 写成,需要以 C/C++ 编写的 Native 库。因此 Android 除了提供开发 Java 代码所需的 JDK (Java Development Kit) 之外,还提供了供开发者进行 Native 层开发的 NDK (Native Development Kit)。

Java 运行于 Java 虚拟机之上,因而实现了易移植、可跨平台运行等特性,但这也使得 Android 需要依赖一些「Native」的代码来访问系统底层,去完成一些 Java 实现不了的任务。也正因如此,C/C++ 这类「原生」的语言也使 Android 程序丧失了跨平台这一特性,在为 Android 编译 C/C++ 程序时需考虑目标机器所使用的 CPU 架构、操作系统版本等。

JNI

JNI 即 Java Native Interface,是 Java 提供用来与其他语言编写的程序通信的接口,之中定义了 Java 字节码与 Native 代码的交互方式。这里我们通过 NDK 来使用 JNI,从而实现 Android 程序中 Java 代码与 C/C++ 代码的相互调用。

这里记录一些遇到的问题和自己认为可以暂时过掉的一些 quick answer:

  • 动态链接库 (.so) 与静态库 (.a) 的区别
    • 静态库中的代码在编译后直接进入可执行文件中,而动态链接库则是将代码包含在程序外的库文件中,在运行时被程序所调用,不能单独执行

什么是工具链 (Toolchain) ?

NDK 中提供的用于交叉编译 C/C++ 代码的一系列工具

Cmake 在这里到底用来干什么?

CMake 根据 CMakeLists.txt 配置文件来生成一个指导工具链进行编译的标准建构文件,随后工具链便可根据建构文件将源代码编译成动态链接库

当我们编译一个 .c 文件的时候,我们可以直接将其丢进 gcc 中编译;但当我们需要编译一个项目的一系列 .c 文件时,一股脑丢进去编译显然就会大乱套了,于是我们需要一个建构系统来管理这个项目的编译。在 Windows 下我们使用 Visual Studio 的 .sln 文件,macOS 下我们使用 Xcode 的 .xcodeproj 文件,Linux 下我们可以使用 Make 的 Makefile 文件。这些建构系统的建构文件可以指导编译器或编译工具链来编译 .c 文件。

What about Ninja ?

  • Ninja 是一个专注于编译速度的建构系统,用了大家都说好

NDK

NDK 即 Native Development Kit,在这里可以让我们在 Android 开发中使用 C/C++ 语言编写而成的库。

在 Android 开发中,我们应当先在 Java 文件中编写 Native 方法,然后在 C/C++ 文件中实现 Native 方法,接着使用 NDK 的工具链将 C/C++ 代码编译成动态链接库,然后使用 Android Studio 的 Gradle 将我们编译好的库打包到 APK 中。随后在运行程序时,Java 代码就可以通过 Java 原生接口 (JNI) 框架调用库中的 Native 方法。

交叉编译、建构系统与 CMake

交叉编译 (Cross Com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值