FFmpeg 编译 for Android

环境 :
macOS Mojave
ndk - android-ndk-r14b
ffmpeg - V3.3.9

在实操的过程中发现,别的版本编译不成功,没有过多做深入的研究,找到了这个可以编译的版本使用。 

编译产物和demo已经放到github :
https://github.com/kongxs/ffmpegDemo

1. 编译

1. 替换configure 中的内容
    主要是为了修改编译完的产物和命名,以便于Android平台使用
 
1
2
3
4
5
6
7
8
9
10
11
	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)'


2. 编写脚本文件
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
	#!/bin/bash

make clean
# NDK的路径,根据自己的安装位置进行设置
export TMPDIR=替换为自己的一个路径
export NDK=替换为自己的ndk路径
export SYSROOT=$NDK/platforms/android-21/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
export CPU=arm
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"
function build_one
{
./configure \
--prefix=$PREFIX \
--target-os=linux \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
--enable-shared \
--enable-runtime-cpudetect \
--enable-gpl \
--enable-small \
--enable-cross-compile \
--disable-debug \
--disable-static \
--disable-doc \
--disable-asm \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-postproc \
--enable-avdevice \
--disable-symver \
--disable-stripping \
$ADDITIONAL_CONFIGURE_FLAG
sed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h
sed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h
sed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h
sed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h
sed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h
sed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h
sed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h
sed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h
make clean
# 这里是定义用几个CPU编译,我用4个,一般在5分钟之内编译完成
make -j4
make install
}
build_one

其中: 
TMPDIR为编译生成的临时文件存放的目录
SYSROOT为so文件支持的最低Android版本的平台目录
CPU为指定so文件支持的平台
PREFIX为生成的so文件存放目录
TOOLCHAIN为编译所使用的工具链目录
cross-prefix为编译所使用的工具链文件
enable和disable指定了需要编译的项
target-os为目标操作系统;

3. 执行脚本
./build_android.sh 

等待执行结束会在  目录下生成编译产物 。  位于 android/arm 文件夹下
    include //  c语言头文件
    lib //	android可用的so

2. 引入Androidstudio开发环境

1. build.gradle 脚本配置 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
externalNativeBuild {
cmake {
cppFlags ""
}
ndk {
abiFilters "armeabi-v7a"//添加平台过滤
}
}
//指定libs文件夹
sourceSets.main {
jniLibs.srcDirs = ['libs']
jni.srcDirs = []
}

1. 添加依赖文件 
我们将第一步编译好的so放入libs文件夹,将 include文件中的头文件放到cpp文件夹 . 如下所示

2. CMakeLists.txt 文件编写 
    按照如下进行编写,将我们所有的so都在cmakelist文件中进行注册,联合编译
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
	# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.


add_library( # Sets the name of the library.
native-lib

# Sets the library as a shared library.
SHARED

# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp
src/main/cpp/Utils.c
)

include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp)

add_library(avcodec-57 # 库名字
SHARED
IMPORTED)
set_target_properties( avcodec-57
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libavcodec-57.so)



add_library(libavdevice-57 # 库名字
SHARED
IMPORTED)
set_target_properties( libavdevice-57
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libavdevice-57.so)



add_library(libavfilter-6 # 库名字
SHARED
IMPORTED)
set_target_properties( libavfilter-6
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libavfilter-6.so)



add_library(libavformat-57 # 库名字
SHARED
IMPORTED)
set_target_properties( libavformat-57
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libavformat-57.so)



add_library(libavutil-55 # 库名字
SHARED
IMPORTED)
set_target_properties( libavutil-55
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libavutil-55.so)



add_library(libpostproc-54 # 库名字
SHARED
IMPORTED)
set_target_properties( libpostproc-54
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libpostproc-54.so)



add_library(libswresample-2 # 库名字
SHARED
IMPORTED)
set_target_properties( libswresample-2
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libswresample-2.so)



add_library(libswscale-4 # 库名字
SHARED
IMPORTED)
set_target_properties( libswscale-4
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/libswscale-4.so)



# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
log-lib

# Specifies the name of the NDK library that
# you want CMake to locate.
log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
native-lib
avcodec-57
libavdevice-57
libavfilter-6
libavformat-57
libavutil-55
libpostproc-54
libswresample-2
libswscale-4

# Links the target library to the log library
# included in the NDK.
${log-lib} )

3. 一些问题

1. 比如include 
1
2
3
4
5
extern "C"
{
#include "libavformat/avformat.h"
#include "libavutil/log.h"
}