音视频:11.Shell脚本-动手编译FFmpeg

避坑指南

1.Cmake交叉编译Android动态库

交叉编译:Linux上编译Android的so

ndk 16的以上版本自带交叉编译工具链

1
2
3
4
5
cmake -DANDROID_NDK=${NDK_PATH} \ # ndk的安装目录(空格 \回车,相当于所有命令弄到同一行)
-DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \ # cmake 交叉编译工具链
-DANDROID_ABI="armeabi-v7a" \ # 指定CPU
-DANDROID_NATIVE_API_LEVEL=19 \ # 指定最低版本
..

2.配置NDK环境

在NDKr17以后,NDK 不再支持32位和64位 MIPS 和ARM v5(armeabi)

所以现在NDK中只支持armeabi-v7a,armeabi-v8a,x86,x86_64四类

注意如果是虚拟机的linux系统 需要把要拷贝的文件放到桌面,然后通过ctrl+c复制,最后在虚拟机上 ctrl+v复制

  1. 下载NDK
  2. 将下载好的linux系统的ndk,拷贝到linux系统的 /lib目录下新建的ndk目录解压,需要root权限
  3. 配置环境变量
    1
    2
    3
    4
    5
    6
    7
    配置环境变量:

    配置环境变量 vim /etc/profile
    文件最后面输入:
    export NDK_PATH=/lib/ndk/android-ndk-r21b
    export PATH=$NDK_PATH:$PATH
    使环境变量生效 source /etc/profile

2.1 NDK中交叉编译工具的变化

在ndkr17c 以后默认使用的变成了clang而不是gcc

2.1.1. 交叉编译工具位置的变化:

在 NDK r19以前的 ndk 内置了一个可以自动生成交叉编译工具(toolchain) 的.py文件,放在

ndk路径下面的build/tool/make_standalone_toolchain.py

要生成toolchain,使用下面的命令

1
2
3
4
5
6
7
8
9
$NDK_HOME/build/tools/make_standalone_toolchain.py --arch arm --api 21 --install-dir /Users/fczhao/Desktop

后面的几个都是必要的

--arch 指定了生成的toolchain要在哪个CPU框架中使用

--api 指定了生成的toolchain要在哪个Android API 中使用

--install-dir 生成的toolchain的路径

但是NDK r19以后的NDK已经内置了这些文件,如果运行上面的命令,会出现这样的日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WARNING:__main__:make_standalone_toolchain.py is no longer necessary. The

#$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin 这个路径已经有了我们要生成的文件
$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin directory contains target-specific scripts that perform
the same task. For example, instead of:

$ python $NDK/build/tools/make_standalone_toolchain.py \
--arch arm --api 21 --install-dir toolchain
$ toolchain/bin/clang++ src.cpp

Instead use:

$ $NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang++ src.cpp

Installation directory already exists. Use --force.

3.手写FFmpeg编译脚本

关于版本问题:学习尽量使用最新的版本(api过时,api改进),开发尽量使用大众的版本(方便查询解决问题)版本3.3.9

第三方库编译的通用思想:
  1. 首先先看下README.md文件
  2. 编译项目(动静态库)需要 Makefile 管理,如果已经有写好的Makefile可以尝试着用make命令去编译,如果没有需要自己写Makefile或者采用 cmake 构建
  3. 如果Makefile报错需要解决,一般情况下都是Makefile的一些配置文件没生成,所以一般需要先运行configure文件
  4. 生成配置文件之后,再次运行make,但是编译后的文件(elf,so,a)只能在当前类型系统上运行。如果需要跑到android或ios那么需要交叉编译因此我们一般都需要往configure文件里面传一些交叉编译参数
  • ./configure --help > help.txt:将configure 的帮助说明写到help.txt中去

NDKr16以上的版本NDKr19以下需要我们自己去生成android版本的交叉编译链 ,NDKr19以上不需要

1
2
3
4
5
6
7
8
1. 创建目录 /lib/ndk/android-ndk-r21b/android-toolchains/android-19/arch-arm
2. 进入 /lib/ndk/android-ndk-r21b/build/tools 目录下
3. 执行命令:
sudo ./make_standalone_toolchain.py --arch arm --api 19 --install-dir /lib/ndk/android-ndk-r16b/android-toolchains/android-19/arch-arm

如果出现 Installation directory already exists. Use --force.

在上条命令最后面加上 --force就行

ndk-r16b和ffmpeg3.3.9的脚本文件请查看ffmpeg_build_r16b.sh,还需要注意修改configure里生成文件名的方式:

1
2
3
4
5
6
7
8
9
10
11
按 esc 键输入 /build setting 查找

# SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
# LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
# SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
# SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
# 替换成如下
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

ndk-r16b和ffmpeg3.3.9的脚本文件请查看ffmpeg_build_r21b.sh

4.编译遇到的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
clang is unable to create an executable file. C compiler test failed.
C compiler test failed.

If you think configure made a mistake, make sure you are using the latest
version from Git. If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "config.log" produced by configure as this will help
solving the problem.


当遇到这个问题的时候

大部分是NDK支持平台错了

sudo uname --m

如果显示i686,你安装的是32位操作系统
如果显示 x86_64,你安装的是64位操作系统

下载的时候按下面

android-ndk64-r10b-linux-x86.tar
支持的是32位操作系统
android-ndk64-r10b-linux-x86_64.tar.bz2
支持的是64位操作系统

5.如何适配so框架

目前支持有不同的 7 中 cpu 的架构,ARMv5,ARMv7(2010年),ARMv8,x86(2011年),mips(2012年),mip64,x86_64

每一种架构都关联着一种ABI。 现在一般只需要arm架构就行

armv5,armv7(32位),armv8(64位):高版本会兼容低版本的,因此只需要放一个低版本的就可以了,armeabi或者armeabi-v7a(现在一般都是v7a,AS上只支持v7以上的,AS4.1提示后面上架到google play 的应用都需要支持64位的)

armeabi:v5因为比较旧,因此早期缺少浮点计算的硬件支持,在需要大量计算是有一定的性能影响。

6.编译参数传递

7.运行调试音频解码

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%