编译FFmpeg3.3.1
的so文件,并在Android
工程中使用。
FFmpeg版本:3.3.1 / OS:Mac OSX
ps: 开始的时候我只编译出了6个so文件,缺少libavdevice.so
和libpostproc.so
,主要是因为build_andorid.sh
的配置不同,现在可以编译出8个so文件,在文章中的图片出现的都是6个so文件,特此声明。
源代码 GitHub - FFmpegAndroidSupport(注意在 hello_world 分支)
配置 NDK 环境
打开~/.bash_profile
文件,添加ndk
的环境变量,最后别忘了source .bash_profile
更新配置,完成之后运行 ndk-build -v
查看版本,没有提示找不到命令就可以了。
1 | # ndk |
修改 configure
修改ffmpeg-3.3.1/configure
文件,这个主要是生成的lib包的包名规范成以libxxx.so的形式。 否则生成的so文件在android下是无法加载的,替换过程一定要谨慎,需要全部替换掉。这里我提供一个替换好的configure文件供参考:thumbsup:
1 | # 找到下面几行替换一下 |
编写 build_android.sh 脚本
编写ffmpeg-3.3.1/build_android.sh
脚本注意,NDK后面的路径换成自己的路径,可以参考编写好的文件:smile:
关注下面的配置,不要直接拷贝--disable-avdevice
加上之后将不会生成avdevice.so
文件--enable-gpl
加上之后将会生成postproc.so
文件
1 |
|
编译生成 ffmpeg so 库
执行build_android.sh
脚本
如果没有权限可以使用chomd +x
增加执行权限
然后等一段时间,😯不,是很长时间,所以前面的配置要谨慎,不然编译完了之后发现有问题,就会很💔,你会发现在FFmpeg中出现了一个名为android的文件夹。
目录如下
将编译生成的文件 copy 到 AS 中
目录如下,jniLibs里面是最后我们编译生成好之后拷贝进去的,现在应该是空的,编译生成的so文件会生成在src/main/libs
目录里面,生成好之后,如果你使用jniLibs
目录加载so,就拷贝到这里。图片中的描述略有歧义。
编写 C 语言的 JNI 接口
这里是拷贝了别人写好的代码,这篇文章主要还是把整个编译流程完成,因此直接用了别人已经写好的,后面的文章会对这一块详细介绍。
编写文件名为ffmpeg_support.c
的c文件,声明java调用接口,函数命名需要按照Java_包名_类名_方法名
的形式来编写,区分大小写。
1 |
|
编写 Android.mk
1 | LOCAL_PATH :=$(call my-dir) |
编写 Application.mk
关于Application.mk的相关配置可以查看官方文档
下面android-14指的是最小支持的AndroidApi在4.0以上,具体看可以查看官方文档APP_PLATFORM这块的内容。这个跟你在manifest文件里面配置的min-sdk也有些关联,不拼配会有警告,不过现在都会在gradle文件中配置minSdk,不用在意也可以,实在强迫症就在manifest里面再声明一次。
1 | APP_ABI := armeabi armeabi-v7a |
编译生成可用的 so 文件
local.properties
如下配置ndk目录,通常是默认配置好的。
1 | ndk.dir=/Users/march/AndroidRes/sdk/ndk-bundle |
然后进入到terminal,cd到jni目录,执行 ndk-build
命令
等待一段时间
编译完成的结果应该是这样的,如果你使用jniLibs目录作为加载so的目录,将so文件拷贝到jniLibs中。
在 app/build.gradle
配置以下代码,可以将 jniLibs
目录指向 libs
,这样就不需要每次拷贝 so
文件到 jniLibs
了
1 | sourceSets { |
调用 JNI
加载so文件以及java层的调用接口
1 | public class FFmpegSupport { |
运行项目
编辑app/build.gradle
配置好so加载路径,将so文件拷贝进jniLibs目录,当然你如果喜欢放在libs目录里面也是可以的,一定要记得armeabi/xxx.so
,abi目录不要忘记,不然会提示找不到,不要问我为什么特别提醒 :smile:
1 | sourceSets { |
点击运行,出现了以下错误:Your project contains C++ files but it is not using a supported native build system。下面的配置可以解决这个问题。
1 | // 在gradle.properties添加 |