博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
26.Android Studio下Ndk开发(ffmpeg导入Android studio以cmake方式编译的过程)
阅读量:6438 次
发布时间:2019-06-23

本文共 4524 字,大约阅读时间需要 15 分钟。

Android studio 2.2开始支持cmake的方式进行jni开发,我在另一篇中写过Eclipse下编译ffmpeg的过程,但是现在几乎没有人会使用eclipse作为Android开发工具了,所以很有必要写一下使用Android studio进行jni开发的一般步骤。

首要确保两点:第一,你的Android studio 是2.2及以版本,第二,在你的sdk tools中,确保安装了ndk,cmake,LLDB这三个东西。

其中LLDB是一个高效的c/c++的调试器,目前LLDB也已经取代GDB成为XCode的默认调试器,在Android studio中也可以使用。
CMake 则是一个跨平台的编译工具。

img_57484cb718aa8ed84a6cc9fdde18b101.png
ndk配置.png

那么我们如何进行开发呢,Android studio中项目的目录结构又是怎样安排,各有什么意义?

android studio下cmake编译ndk

新建项目时,添加c++支持很简单,Android studio为我们提供了一个选项(Include C++ support),只需要勾选,系统会为我们默认添加一些配置

那么如果是在旧项目上添加呢,这就需要我们手动配置一下了

img_2b60b01f851027c413a542a1c0f29b0a.png
Cmake配置文件目录.png

第一步,创建CMakeLists.txt文件,注意,文件名必须这样设置,大小写区分,默认放在项目根目录下,或者在其他位置,只需要你在build.gradle中配置即可

第二步,在项目根目录的build.gradle文件中配置

android {    ......    defaultConfig {        ......        // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉)        //例如如果的的so只支持arm平台,那么就像下边这样设置,如果还支持其他平台则再后边追加        ndk{            abiFilters 'armeabi'        }    }    ......    externalNativeBuild{        //配置CMakeLists文件地址        cmake{            path 'CMakeLists.txt'        }    }}

这里贴出来我的CMakeLists.txt配置文件

部分参数解析:

include_directories:表示引入项目so文件所需的头文件的路径,在配置文件中配置之后,编写c代码的时候可以会在当前路径下查找头文件,引入的路径可以少些一些层级

find_library:引入内部已经支持的库文件

add_library:引入外部添加的库文件

cmake_minimum_required(VERSION 3.4.1)#引入头文件位置include_directories(src/main/cpp/include/ffmpeg)include_directories(src/main/cpp/include/owner)find_library(    android-lib    android)find_library(    log-lib    log)find_library(    jnigraphics-lib    jnigraphics)#自己的库add_library(    newffmpeg    SHARED    src/main/cpp/ffmpeg_player.c)# 编解码(最重要的库)add_library(    avcodec    SHARED    IMPORTED)#指定编码库的位置set_target_properties(    avcodec    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec-56.so)#设备信息add_library(    avdevice    SHARED    IMPORTED)#指定设备信息的位置set_target_properties(    avdevice    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice-56.so)#滤镜特效处理库add_library(    avfilter    SHARED    IMPORTED)#指定滤镜库位置set_target_properties(    avfilter    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter-5.so)#封装格式处理库add_library(    avformat    SHARED    IMPORTED)#指定格式库路径set_target_properties(    avformat    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat-56.so)#工具库(大部分库都需要这个库的支持)add_library(    avutil    SHARED    IMPORTED)#指定工具库路径set_target_properties(    avutil    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil-54.so)#后期处理add_library(    postproc    SHARED    IMPORTED)#指定后期处理库路径set_target_properties(    postproc    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libpostproc-53.so)#数据格式转换库add_library(    swresample    SHARED    IMPORTED)#指定库位置set_target_properties(    swresample    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample-1.so)#视频像素数据格式转换add_library(    swscale    SHARED    IMPORTED)#视频像素格式转换库位置set_target_properties(    swscale    PROPERTIES IMPORTED_LOCATION    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale-3.so)# 将预构建库与本地库相连target_link_libraries(    newffmpeg    avcodec    avdevice    avfilter    avformat    avutil    postproc    swresample    swscale    ${android-lib}    ${jnigraphics-lib}    ${log-lib})
so和C文件目录划分

配置文件搞好了,接下来就要正式的引入编译好的ffmpeg so文件了,如果不知道如何编译,可以参考我之前的一片文章 09.阿里云服务器(Ubantu系统)配置ndk 编译ffmpeghttps://www.jianshu.com/p/826d2175f157,我们在项目main package下创建jniLibs文件夹,将编译好的so放入这里

img_cafa4662377e3d18e84dbe4166009459.png
so目录.png
jniLibs目录也是系统默认支持的,你当然可以设置其他名字,或者将目录放在别的位置,但是要注意,如果你这样做,一定要在build.gradle中进行指定,否则系统找不到这些文件

细心的你可能发现在上边的截图上还有一个cpp的目录,这个目录是我们一般用来防止头文件和c c++文件的,系统默认不会创建这个目录,也需要我们手动添加,除非你在创建项目的时候就添加了c++ support

这时候,基本上过程已经接近尾声了,我们来看一下都做了什么:

1.创建CMakeLists.txt脚本文件
2.在build.gradle中配置编译选项
3.将so库加入jniLibs文件夹,将.h 和 .c(c++)文件放入cpp目录
4.还有一步,我们要创建native方法,生成头文件,加载so,
5.最后一步就是调用了,这一整个过程到此结束

package com.rzm.ffmpeglibrary;public class FFmpegUtils {    static{        System.loadLibrary("newffmpeg");    }    public native static void decode(String input,String output);}
#include "com_rzm_ffmpeglibrary_FFmpegUtils.h"/* * Class:     com_rzm_ffmpeglibrary_FFmpegUtils * Method:    decode * Signature: ()V */JNIEXPORT void JNICALL Java_com_rzm_ffmpeglibrary_FFmpegUtils_decode(JNIEnv *env, jclass jclazz,jstring input,jstring output){}

其实这里还有很多细节可以多说一点,比如javah命令如何生成头文件,javap命令如何获取方法或者属性的签名,最重要的一点,ffmpeg从编写脚本文件到开始编译,这一整个过程如何走来,这些基本上在之前的文章中有提到,这里就不再多说了。

总结一下,这里提到的每个过程,CMakeLists.txt文件的编写才是重中之重,也正是我想说的,把脚本中每一个命令搞清楚,在ndk开发的路上你就更近一步了。

转载地址:http://llkwo.baihongyu.com/

你可能感兴趣的文章
【算法】K-Means聚类算法(k-平均或k-均值)
查看>>
$routeParams $route.current.params
查看>>
C++调用matlab char16_t 重复定义
查看>>
Android深入浅出系列之Android工具的使用—调试桥ADB(二)
查看>>
面向对象进阶------>内置函数 str repr new call 方法
查看>>
JavaScript: 对象
查看>>
用CSS3来添加项目编号
查看>>
jmeter制造大批量的用户数据数据
查看>>
步步为营 .NET三层架构解析 四、Model设计(四种设计方式)
查看>>
sharepoint Lists Web service 用法
查看>>
关于TaskStatus状态WaitingForChildrenToComplete 的疑问
查看>>
A quick introduction to Google test
查看>>
virtualbox+vagrant学习-2(command cli)-27-vagrant connect命令
查看>>
【学时总结&模板时间】◆学时·10 & 模板·3◆ AC自动机
查看>>
linux命令2
查看>>
iOS-UICollectionView
查看>>
lombok(@Getter&@Setter)
查看>>
shiro+redis多次调用doReadSession方法的解决方案
查看>>
浅谈EntityFramework框架的使用
查看>>
asp.net identity的学习记录
查看>>