NDK
1.什么是ndk?
ndk (Native Development Kit)跟sdk差不多的是他也是一个开发工具包。用他开发c/c++是很方便的。他有一个强大的编译集合。
2.为什么出现ndk?
如果你要操作底层直接操作内存。操作地址那你不得不去使用c/c++因为java这块想做这些。那恐怕有点困难。所以ndk是必须需要出现的。
通过NDK,你就可以用c或c++来开发app了
使用NDK好处:
1、代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大;
2、可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的;
3、提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率;
4、便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
NDK配置(包含构建工具,调试工具)
下载安装NDK,有俩种方式,其实都一样,只是一个需要手动下载,解压,配置目录,一个Android Studio自动完成以上操作。
- 点击Project Structure,选择 Download Android NDK;
我们看一下ndk目录各个作用,简单了解下。
- docs: 帮助文档
- build/tools:linux的批处理文件
- platforms:编译c代码需要使用的头文件和类库
- prebuilt:预编译使用的二进制可执行文件
- sample:jni的使用例子
- source:ndk的源码
- toolchains:工具链
- ndk-build.cmd:编译打包c代码的一个指令,需要配置系统环境变量
配置构建工具以及调试工具
1.如下图所示,点击SDK Manager,选择下载安装CMake以及LLDB;
基本配置已完成,但是如何查验NDK是否成功安装了呢?
配置下环境变量
创建项目时,记得勾选下面的Include C++ support哦~
导入C++支持库,不然没法玩哈~
· cpp 目录存放所有 native code 的地方,包括源码,头文件,预编译项目等。对于新项目,Android Studio 创建了一个 C++ 模板文件:native-lib.cpp,并且将该文件放到了你的 app 模块的 src/main/cpp/ 目录下。这份模板代码提供了一个简答的 C++ 函数:stringFromJNI(),该函数返回一个字符串:”Hello from C++”
· External Build Files 目录是存放 CMake 或 ndk-build 构建脚本的地方。有点类似于 build.gradle 文件告诉 Gradle 如何编译你的 APP 一样,CMake 和 ndk-build 也需要一个脚本来告知如何编译你的 native library。对于一个新的项目,Android Studio 创建了一个 CMake 脚本:CMakeLists.txt,并且将其放到了你的 module 的根目录下
Java_cn_hlq_hlqjnipro_MainActivity_hlqFromJNI这个名称,方法名必须为Java_包名全路径_方法名
Gradle 会将你的本地库构建成 .so 文件,然后将其打包到你的 APK 中。如果你想 Gradle 构建并打包某个特定的 ABI 。你可以在你的 module 层级的 build.gradle 文件中使用 ndk.abiFilters 标签来指定他们:
.查看activity代码
首先static静态块去加载so库,本地编写native方法,调用方法输出内容。
Jni
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。
JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境。
可以看到Android上层的Application和ApplicationFramework都是使用Java编写,底层包括系统和使用众多的Libraries都是C/C++编写的,所以上层Java要调用底层的C/C++函数库必须通过Java的JNI来实现。
总之,只有当你必须在同一进程中调用本地代码时,再使用JNI。
FFmpeg简单介绍
FFmpeg全名是Fast Forward MPEG(Moving Picture Experts Group)
FFmpeg是一个全球领先的多媒体框架,能够友好的在大部分设备实现解码、编码、转码、复用、解复用、流媒体、过滤和播放。它支持最不起眼的古老的格式,最高可达前沿。不管他们的一些标准委员会,社区或公司设计。具有较可靠的可移植性:FFmpeg能够在各个平台(Linux、Mac OS X、Microsoft Windows、BSDs、Solaris等)和架构(x86、arm、mips等)中运行和编译,经得起考验。
1.编译 x264 视频编码器
x264文件放libx264的源码,fad-aac-0.1.5文件夹放libfdk-aac源码,ffmpeg-3.2.5文件夹放FFmpeg-3.2.5源码,buildoutput里面放我们编译上述源码的so文件及头文件。我们所做的工作就是把号称最好的视频编码器libx264和音频编码器libfdk-aac替换ffmpeg自带的音视频编码器,然后把ffmpeg编译出来丢到buildoutput文件里面去。
2、编译 fad-aac 音频编码器
3.交叉编译FFmpeg
所以的准备工作做好了后,我们开始编译ffmpeg,同样的我们还是在buildoutput目录创建一个配置脚本文件ffmpeg_arm_build.sh,由于完全编译的话可能so文件会很大,所以我们编译一个精简版的ffmpeg,我们从如何几个方面入手:
- disable-encoders 禁用全部的编码器,然后视频使用libx264,音频使用libfdk_aac,以及图片mjpeg png等
- disable-decoders 禁用全部的解码器,然后使用几个常用的
- disable-demuxers 禁用全部的视音频分离器,然后使用几个常用的
- disable-parsers 禁止全部的解析器,然后使用几个常用的
主要是这四个方面,其他一些应该也是通用作用的,具体没研究过。执行脚本命令./ffmpeg_arm_build.sh
编译Android环境的FFmpeg
上面我们已经把我们定制的ffmpeg编译出来了,接下来我们需要修改ffmpeg源码的某些c类来满足Android环境下的使用,然后通过JNI给Java调用执行ffmpeg的命令,我们用cMake方式来写jni。
1.创建默认支持jni的项目,找到编译后ffmpeg-3.2.5文件目录找到如下8个文件,然后复制到项目的cpp目录(最新的ffmpeg源码目录没有cmdutils_common_opts.h编译方式未知)
ffmpeg_filter.c
ffmpeg_opt.c
ffmpeg.c
ffmpeg.h
cmdutils_common_opts.h
cmdutils.c
cmdutils.h
config.h (编译后才会有生成config.h)
android视频压缩,使用ffmpeg方案,集成fdk-aac与264编码,适用于32位系统与64位系统,支持ARM 32/64 cpu与x86 32/64 cpu,mips 32/64 cpu,即支持android7.0系统
视频压缩网址:
https://blog.csdn.net/tijjyire/article/details/78287790
https://blog.csdn.net/wang_k516/article/details/79071773
总结:
1.首先我们要配置ndk,ndk是一套可以使用原生代码语言(例如c和c++)实现部分应用的工具集。
第一步:NDK有俩种配置方式,一个是手动下载,解压配置目录,另一个Android Studio自动下载完成,
第二步:我们点击SDK Manager选择下载安装CMake构建工具和LLDB调试工具。
第三步:我们通过配置环境变量,在cmd命令框输入ndk-build,查看NDK是否安装成功。
- 在创建项目时,记得勾选支持C++选项,在我们调用C++代码时,首先static静态块去加载so库,本地编写native方法,调用方法输出内容。
- 我们在编译时,我们采用FFmpeg多媒体框架对视频进行编译,视频编码器我们采用x264编译,音频编码器我们采用fad-aac编译。上层Java要调用底层的C/C++函数库必须通过Java的JNI来实现。JNI它提供了若干的API实现了Java和其他语言的通信(主要是C&C++),然后通过JNI给Java调用执行ffmpeg的命令进行视频压缩。
- 使用ffmpeg方案,集成fdk-aac与264编码,适用于32位系统与64位系统,支持ARM 32/64 cpu与x86 32/64 cpu,mips 32/64 cpu,即支持android7.0系统