近一周的时间里,由于项目中需要用到FFmpeg(一款强大的音视频操作开源项目,据说可以用来写播放器什么的)编解码项目,这么大牛的项目又是开源的注定是十分复杂的,所以在Android接入这一方面还是又机智的大牛做了尝试的,android接入 不过这是接入Skype的silk编码,以及这个大牛的文章。不过道理都是一样的,废话不多说!进入主题,

一.环境准备

Ubuntu 16.04;
ndk-r10d;
AndroidStudio(之后才意识到在sdkManager下载好的ndk比较快,推荐这种方式下载);
FFmpeg(注意选择版本下载)
具体的下载安装我就不说了 ,我们接入android是不需要将FFmpeg其在Ubuntu中编译的,主要源码就好,我第一次弄的时候就失足在Ubuntu中编译了FFmpeg,也无害。
如果不是在AndroidStudio中下载的ndk最好设置一下环境变量,然后指定ndk位置到项目。

二.在NDK中编译so

这个过程是比较麻烦的,有个大神的博客很好逝者已矣,愿天堂美好,盗用里面的一张图

整个步骤包括现将ffmpeg利用NDK编译成适应android指令集的动态库(这个依赖于c语言代码有没有适配不同的cpu指令集),通过编写JNI调用so库。其中图中的Moudule Source(*.c)部分就是原生c
语言调用so库。
首先修改configure配置文件,这只是ffmpeg需要这样做,其他的不同的库,最好参考REDEME文件,这个参考雷大神的博客这里写链接内容
我说说我遇到的坑,他的步骤是configure,make,make install三大步,在configure这一步的时候,书写的build脚本在执行的时候,总是出现未找到命令的提示,总是无法编译成功,经过google大神的帮助后,找到合适的解决方法,(这可是花了一天的时间啊!哭晕在厕所)网址是大神地址,编译成功后会在相应的文件夹中出现(在configure中设置)相应的so文件以及相应的头文件,编译完成后产生的相应的so文件,注意!配置文件如图:

时隔一年回头看这个博客,对这个build.sh也有了更深的理解,其实这个build.sh就是个命令脚本,在你的系统存在gcc环境下的一下编译命令集合。关于各个命令的具体意义还不是很了解,不过在这其中需要注意的是编译中遇到的各种问题的解决,比如:

1. 出现找不到文件,这是没有找到c标准类库,及其有可能是ndk的版本过高,将这个文件的位置更改了,需要手动指定位置,在build.sh文件中指定位置

2. 注意看文件路径,不要盲目的抄博客中的build,切记

三.在AndroidStudio中的java中接入so

这个过程首先我们得会写一个jni的helloworld,由于AndroidStudio在2.2后引进了CMake编译套件,加上之前的ndk的手动编译就有两种方式(CMake只是将编译的工作集成简化)运用ndk-build的方式建议之前推荐的雷大神的博客来操作,我在这里只说几点我的感悟。
1.Android.mk是编译知道文件需要理解
2.jni调用时函数的名称一定要按照规则来: Java_com_skystudio_ndkdemo_NativeUtils_strFromNdk( JNIEnv* env,jobject thiz )
3.ndk-build结束后可以将so文件放入jniLibs文件夹中,就可以将c源码删除了

四. 采用CMake方式接入FFmpeg

  1. 新建支持C++的Android project
  2. 将so库以及包含的头文件放置在正确的位置,其实也不一定是固定死的位置,只要你的CMakeList文件能够对应起来就是可以的,普遍的一种放置如图:
  3. 重头戏来了就是编写CmakeList文件了,关于Cmake语法有很多内容,了解的也不够,只就这个需要用的含义解释一下,首先是cmake_minimum_required(VERSION 3.4.1),新建的时候会自带,必须要!
#添加库add_library( # Sets the name of the library.添加编译后库的名字             native             # Sets the library as a shared library.设置库为动态库,static为静态库             SHARED             # Provides a relative path to your source file(s).设置编译库的源文件             src/main/cpp/ffmpeg/native-lib.cpp )              #ImPorted 引进已编译好的库add_library( avfilter             SHARED             IMPORTED) #设置引进目标属性set_target_properties( #添加到的库名avfilter#引进地址,${CMKE_SOURCE_DIR}变量地址默认到项目名下,不知道在哪里设置                       PROPERTIES IMPORTED_LOCATION                       ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libavfilter.so)#设置头文件地址include_directories(src/main/cpp/ffmpeg/include)#指定目标库,就是最后确认项目用到的库意思target_link_libraries( # Specifies the target library.                        native                        avcodec                        avfilter                        avformat                        avutil                        swresample                        swscale                       # Links the target library to the log library                       # included in the NDK.                       ${log-lib} )
  1. 然后就可以愉快的编译代码了(千万注意,地址的对应)

总结

  1. 问:什么叫交叉编译
    答:在某个平台上编译本平台可用的程序叫做本地编译,比如在windows平台上编译windows下的可执行程序。而交叉编译就是在某个平台上编译另一个平台程序。在Android中常用到在x86上编译arm平台上的程序。在交叉编译的时候由于平台差异性大,需要工具来解决这一问题,就出现了各种工具链,即Toolchains。而NDK就是提供了交叉编译的一整套工具的集合。
  2. 问:什么是ABI
    答:Application Binary Interface (应用程序二进制接口) 顾名思义就是应用程序与底层系统间的接口,它定义了程序如何与系统交互,所以我们需要指定不同类型cpu架构的ABI,即builde.gradle中的abiFilter{“x86”,“armeabi”“”}等。
  3. 问:什么是CMake,ndk-build,Android.mk
    答:这一块还不是很了解,推荐google官方文档

更多相关文章

  1. [置顶] Android(安卓)NDK使用分析
  2. . Android內核Porting相關背景知識 转载
  3. Android(安卓)NDK安装及使用简介
  4. Android使用ttf字体库替代替图片
  5. Android资源管理器程序
  6. Android(安卓)Okhttp断点续传面试深入解析
  7. Android内核开发:系统启动速度优化
  8. 交叉编译-5:使用NDK和CMake在Linux上编译Android动态库
  9. Android录音并进行本地转码为MP3

随机推荐

  1. android-数据库操作实例,留着以后用
  2. Android 如何获取最顶端的Top Activity
  3. Android源码中的单例模式android.util.Si
  4. Android Studio实现Activity生命周期的7
  5. android 硬解码用opengles3.0渲染视频
  6. 调试android ethernet 的常用命令
  7. android ndk知识汇总
  8. Android Studio加载老旧项目会遇到的问题
  9. android TextView 如何实现消息滚动
  10. Android studio中关于 No cached version