这种方式可以把我们在外部编译好的.so库导进来
还有几种我也没用过了,可以参考官方文档看下add_library
- include_directories 用来导入相关头文件
include_directories(src/main/cpp)
- find_library 用来引入NDK中提供的库. Android NDK 原生 API
find_library(
定义存储NDK库位置的路径变量的名称。
log-lib
指定CMake要查找的NDK库的名称。
log )
- target_link_libraries 将导入的库和自己的原生库关联起来
target_link_libraries(
指定目标库。
native-lib
将目标库链接到NDK中包含的日志库。
${log-lib} )
FFmpeg
FFmpeg
是一套可以用来记录、处理数字音频、视频,并将其转换为流的开源框架,采用LPL或GPL许可证,提供了录制、转换以及流化音视频的完整解决方案。名称中的mpeg来自视频编码标准mpeg
,而前缀FF
是Fast Forward
的首字母缩写.音视频处理的开源库,可以完成绝大多数音视频相关的功能.很多知名软件,开源库都是基于它进行的二次开发,比如bilibi的ijkPlayer
.
编译FFmpeg
FFmpeg
与大部分GNU软件的编译方式类似,都是通过configure
脚本来实现编译前的定制,这种方式允许用户在编译前对软件进行裁剪,同时通过对最终运行到的系统及目标平台的配置来决定对某些模块设定合适的配置.所以这里是通过configure
的方式来生成Makefile
文件,然后使用make
和make install
编译和安装.
- 配置环境
首先我们需要先准备相关的编译环境,这里推荐在linux
下进行编译,配置简单问题少.当然Mac
也行,不推荐Windows
.
- Linux环境(Ubuntu 16.04)
Windows
的话下载个VMware Workstation
,装个ubuntu
还是方便的. - NDK环境 这里使用的是ndk-r17,附上相关下载链接NDK 下载
- 下载FFmpeg源码 FFmpeg下载地址
- 修改configure文件
由于FFmpeg默认生成的库文件格式为libavcodec.so.xx.xx.x。其中的xx就是主副版本号,这种格式在Ubuntu下使用是没有问题的,但是在Android下开发使用,并不把其作为有效的库文件。所以需要修改其他生成的文件名的格式。
通过修改configure文件要实现,打开configure,找到如下内容:
SLIBNAME_WITH_MAJOR=‘
(
S
L
I
B
N
A
M
E
)
.
(SLIBNAME).
(SLIBNAME).(LIBMAJOR)’
LIB_INSTALL_EXTRA_CMD=‘?(RANLIB)“
(
L
I
B
D
I
R
)
/
(LIBDIR)/
(LIBDIR)/(LIBNAME)”’
SLIB_INSTALL_NAME=‘
(
S
L
I
B
N
A
M
E
W
I
T
H
V
E
R
S
I
O
N
)
′
S
L
I
B
I
N
S
T
A
L
L
L
I
N
K
S
=
′
(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='
(SLIBNAMEWITHVERSION)′SLIBINSTALLLINKS=′(SLIBNAME_WITH_MAJOR)$(SLIBNAME)’
修改为:
SLIBNAME_WITH_MAJOR=‘
(
S
L
I
B
P
R
E
F
)
(SLIBPREF)
(SLIBPREF)(FULLNAME)-
(
L
I
B
M
A
J
O
R
)
(LIBMAJOR)
(LIBMAJOR)(SLIBSUF)’
LIB_INSTALL_EXTRA_CMD=‘?(RANLIB)“
(
L
I
B
D
I
R
)
/
(LIBDIR)/
(LIBDIR)/(LIBNAME)”’
SLIB_INSTALL_NAME=‘
(
S
L
I
B
N
A
M
E
W
I
T
H
M
A
J
O
R
)
′
S
L
I
B
I
N
S
T
A
L
L
L
I
N
K
S
=
′
(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS='
(SLIBNAMEWITHMAJOR)′SLIBINSTALLLINKS=′(SLIBNAME)’
- 编写脚本文件 在
FFmpeg
根目录下创建build.sh
脚本文件,来更方便的配置configure
.如下:
#!/bin/bash
配置NDK路径
NDK=/home/xinyang/develop/android-ndk-r17
指定了交叉编译环境,使其在编译过程中能够引用到 NDK 提供的原生标头和共享库文件
SYSROOT= N D K / p l a t f o r m s / a n d r o i d − 23 / a r c h − a r m / T O O L C H A I N = NDK/platforms/android-23/arch-arm/ TOOLCHAIN= NDK/platforms/android−23/arch−arm/TOOLCHAIN=NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
声明方法
function build_one
{
./configure
–prefix=KaTeX parse error: Expected 'EOF', got '#' at position 15: PREFIX \ #̲ 设置输出路径 --enabl…TOOLCHAIN/bin/arm-linux-androideabi- \ # 指定交叉编译工具链
–target-os=linux \ # 目标系统 android基于linux 所以这里指定为linux
–arch=armeabi-v7a \ # 目标平台架构
–enable-cross-compile # 开启交叉编译
–sysroot=$SYSROOT \ # 交叉编译环境
–extra-cflags=“-Os -fpic
A
D
D
I
C
F
L
A
G
S
"
−
−
e
x
t
r
a
−
l
d
f
l
a
g
s
=
"
ADDI_CFLAGS" \ --extra-ldflags="
ADDICFLAGS" −−extra−ldflags="ADDI_LDFLAGS”
KaTeX parse error: Expected 'EOF', got '}' at position 56: …e make install }̲ CPU=armeabi-v7…(pwd)/android/$CPU
ADDI_CFLAGS=“-marm”
build_one
–cross-prefix
类似于通配符方式指定 bin 目录下以 arm-linux-androideabi- 开头的交叉编译工具,假如不支持这种配置方式则需分别指定:
- CC:$TOOLCHAIN/bin/arm-linux-androideabi-gcc 编译器,对C源文件进行编译处理,生成汇编文件.
- CXX:$TOOLCHAIN/bin/arm-linux-androideabi-g++
- AR:$TOOLCHAIN/bin/arm-linux-androideabi-ar 打包器,用于库操作,可以通过该工具从一个库中删除或者增加目标代码模块.
- LD:$TOOLCHAIN/bin/arm-linux-androideabi-ld 链接器,为前面生成的目标代码分配地址空间,将多个目标文件链接成一个库或是可执行文件.
- 执行脚本 cd 到ffmpeg目录下
chmod 777 build.sh
首先修改下脚本文件的可执行权限
./build.sh
然后执行脚本,整个过程比较慢,耐心等待就好,整个过程大概需要5-10分钟.编译完成后就可以看到如下图,其中include
中是一些头文件,lib
中就是生成的.so动态库了
集成FFmpeg
到这里就可以把生成的.so文件集成到我们的项目中了,来看看步骤:
-
项目关联NDK,按这里的教程执行向您的项目添加C和C++ 代码;
-
拷贝生成的.so文件到
libs
目录下(或是jniLibs); -
拷贝生成的
include
文件夹到cpp
目录; -
拷贝
ffmpeg\fftools
目录下文件到cpp目录; -
编写
native
方法
package com.xinyang.ndkdemo;
public class FFmpegCmd {
static {
System.loadLibrary(“ffmpeg”);
}
public native static void handle();
}
- 在
cpp
目录下创建ffmpeg_cmd.c
文件,实现native
方法,这里可以采用javah
生成头文件再实现的方式,也可以直接在java
类中使用快捷键提示,直接生成方法:
#include <jni.h>
#include <malloc.h>
#include <string.h>
#include <android/log.h>
#include “ffmpeg/ffmpeg.h”
JNIEXPORT void JNICALL Java_com_xinyang_ndkdemo_FFmpegCmd_handle
(JNIEnv *env, jclass obj){
char info[40000] = {0};
av_register_all();
AVCodec *c_temp = av_codec_next(NULL);
while(c_temp != NULL){
if(c_temp->decode!=NULL){
sprintf(info,“%s[Dec]”,info);
}else{
sprintf(info,“%s[Enc]”,info);
}
switch(c_temp->type){
case AVMEDIA_TYPE_VIDEO:
sprintf(info,“%s[Video]”,info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf(info,“%s[Audio]”,info);
break;
default:
sprintf(info,“%s[Other]”,info);
break;
}
sprintf(info,“%s[%10s]\n”,info,c_temp->name);
c_temp=c_temp->next;
}
__android_log_print(ANDROID_LOG_INFO,“myTag”,“info:\n%s”,info);
}
这段程序用于输出 FFmpeg 支持的编解码信息,通过 < android/log.h > 的 __android_log_print 方法可以直接将信息输出到 Android Studio 的 logcat 。
- 编辑
CMakeLists.txt
导入相关.so文件,使用add_library
导入库的方式把生成的.so文件依次导入,使用include_directories
导入头文件,最后再用target_link_libraries
把导入的库和生成的目标库关联起来,如下所示:
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.
ffmpeg
Sets the library as a shared library.
SHARED
Provides a relative path to your source file(s).
src/main/cpp/ffmpeg_cmd.c
src/main/cpp/ffmpeg/cmdutils.c
src/main/cpp/ffmpeg/ffmpeg.c
src/main/cpp/ffmpeg/ffmpeg_filter.c
src/main/cpp/ffmpeg/ffmpeg_opt.c
)
include_directories(src/main/cpp)
include_directories(src/main/cpp/include)
add_library(
avutil-55
SHARED
IMPORTED
)
set_target_properties( avutil-55
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavutil-55.so )
add_library(
avcodec-57
SHARED
IMPORTED
)
set_target_properties( avcodec-57
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavcodec-57.so )
add_library(
avformat-57
SHARED
IMPORTED
)
set_target_properties( avformat-57
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavformat-57.so )
add_library(
avdevice-57
SHARED
IMPORTED
)
set_target_properties( avdevice-57
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavdevice-57.so )
add_library(
swresample-2
SHARED
IMPORTED
)
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
更多Android高级工程师进阶学习资料
进阶学习视频
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
Android高级工程师进阶学习资料
进阶学习视频
[外链图片转存中…(img-Pwde1iZq-1712070908504)]
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中…(img-8BCdUqZC-1712070908505)]
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…