android cmake 动态库,FFmpeg4.3编译动态库-Android+Cmake+ndk-r21b

环境

macOS High Sierra

FFmpeg 4.3

android-ndk-r21b

编译so库

下载FFmpeg4.3源代码,进入源码目录创建build_android.sh脚本,ffmpeg从4.0起新增了target-os=android,所以不用再修改configure文件。

注意:

ndk-17以前内置的编译器是gcc,而新版的ndk已经用clang替代了gcc编译器,所以使用-cc和-cxx指令时要特别注意自己要使用的编译器是gcc还是clang。

还有个我遇到的问题就是在ndk-r17c和ndk-18b中的toolchains/llvm/prebuilt/darwin-x86_64/bin中没有clang编译工具集,而是在上层目录中。

只有armv7-a的执行文件中间有eabi结尾,其他没有。例:armv7a-linux-androideabi21-clang,x86_64-linux-android21-clang。如果报错not found xxx file的错误,就自行到相应目录查看。

#!/bin/bash

#ndk路径

NDK=/Users/chenpeng/Desktop/work_space/ndk/android-ndk-r21b

#编译工具链目录,ndk17版本以上用的是clang,以下是gcc

TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64

#版本号

API=21

#交叉编译树的根目录(查找相应头文件和库用)

SYSROOT="${TOOLCHAIN}/sysroot"

#armv7-a

OUTPUT_FOLDER="armeabi-v7a"

ARCH="arm"

CPU="armv7-a"

TOOL_CPU_NAME=armv7a

TOOL_PREFIX="$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-androideabi"

OPTIMIZE_CFLAGS="-march=$CPU"

#arm64-v8a,这个指令集最低支持api21

#OUTPUT_FOLDER="arm64-v8a"

#ARCH="aarch64"

#CPU="armv8-a"

#TOOL_CPU_NAME=aarch64

#TOOL_PREFIX="$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-android"

#OPTIMIZE_CFLAGS="-march=$CPU"

#x86

#OUTPUT_FOLDER="x86"

#ARCH="x86"

#CPU="x86"

#TOOL_CPU_NAME="i686"

#TOOL_PREFIX="$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-android"

#OPTIMIZE_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"

#x86_64,这个指令集最低支持api21

#OUTPUT_FOLDER="x86_64"

#ARCH="x86_64"

#CPU="x86_64"

#TOOL_CPU_NAME="x86_64"

#TOOL_PREFIX="$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-android"

#OPTIMIZE_CFLAGS="-march=$CPU"

#输出目录

PREFIX="${PWD}/android/$OUTPUT_FOLDER"

#so的输出目录, --libdir=$LIB_DIR 可以不用指定,默认会生成在$PREFIX/lib目录中

#LIB_DIR="${PWD}/android/libs/$OUTPUT_FOLDER"

#编译器

CC="${TOOL_PREFIX}${API}-clang"

CXX="${TOOL_PREFIX}${API}-clang++"

#定义执行configure的shell方法

function build_android() {

./configure \

--prefix=$PREFIX \

--enable-shared \

--disable-static \

--enable-jni \

--disable-doc \

--disable-programs \

--disable-symver \

--target-os=android \

--arch=$ARCH \

--cpu=$CPU \

--cc=$CC \

--cxx=$CXX \

--enable-cross-compile \

--sysroot=$SYSROOT \

--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \

--extra-ldflags="" \

--disable-asm \

$COMMON_FF_CFG_FLAGS

make clean

make -j8

make install

}

build_android

复制代码

更多构建参数可以使用./configure -h参看

shell脚本语言不熟的可以查看我的shell学习笔记

执行build_android.sh脚本,等待脚本执行完成,执行过程可能会遇到缺少组件的问题,按需解决。

#如遇到permission denied,请chmod 777 xx.sh

sh build_android.sh

复制代码

生成文件目录如下:

9a5c4d9caa9c273c5e31323ad2e59b21.png

创建一个新的Android Cmake项目

将动态库放入libs/armeabi-v7a文件夹,将头文件方法cpp目录

72e4d22da3828c19dcdf392b6cd79d6e.png

新增ffmpeg_utils.cpp类,配置build.gradle,配置CMakeLists.txt

#include

//这里要注意,因为这是个c++文件,必须把头文件引用放到extern "C"中

//不然一直报undefined的错误,坑了很久,以前我都是写c

extern "C" {

#include

JNIEXPORT jstring JNICALL

Java_demo_simple_example_1ffmpeg_MainActivity_getVersion(JNIEnv *env, jclass clazz){

const char *version = av_version_info();

return env->NewStringUTF(version);

}

}

复制代码android {

compileSdkVersion 29

buildToolsVersion "30.0.0"

defaultConfig {

applicationId "demo.simple.example_ffmpeg"

minSdkVersion 21

targetSdkVersion 29

versionCode 1

versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

//ndk so架构的选择

externalNativeBuild {

ndk {

abiFilters 'armeabi-v7a'

}

}

//so查找路径

sourceSets {

main {

jniLibs.srcDirs = ['libs']

}

}

}

//cmake文件的查找路径

externalNativeBuild {

cmake {

path file('CMakeLists.txt')

}

}

}

复制代码# 设置构建本机库文件所需的 CMake的最小版本

cmake_minimum_required(VERSION 3.4.1)

#添加头文件的搜索路径

include_directories(src/main/cpp/include/)

# 添加自己写的 C/C++源文件

add_library(utils #so名称

SHARED #动态库

src/main/cpp/ffmpeg_utils.cpp

)

# 添加外部的库(可以是动态库或静态库),这里只引入了avutil

set(LIBS_DIR ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI})

add_library(

avutil

SHARED

IMPORTED)

set_target_properties(

avutil

PROPERTIES IMPORTED_LOCATION

${LIBS_DIR}/libavutil.so)

# 依赖 NDK中自带的log库

find_library(log-lib log)

# 链接库

target_link_libraries(

utils

avutil

${log-lib})

复制代码

加载动态库,获取FFmpeg的版本号

public class MainActivity extends AppCompatActivity{

private static final String TAG = "MainActivity";

@Override

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

TextView tvVersion = findViewById(R.id.tvVersion);

String version = String.format("ffmpeg version == %s", getVersion());

tvVersion.setText(version);

Log.d(TAG, version);

}

static {

System.loadLibrary("utils");

System.loadLibrary("avutil");

}

public static native String getVersion();

}

复制代码输出结果:

ffmpeg version == 4.3

简写导入动态库的cmake语句

上面CmakeList引入avutil使用了add_library和set_target_properties,如果同时引用很多动态库,那就要写很多的重复配置,我们完全可以使用下面的方式简写配置。或者也可以将所有动态库合并成一个动态库。

# 去掉`add_library`和`set_target_properties`的相关配置

#设置查找动态库位置

set(LINK_DIR ${CMAKE_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI})

link_directories(${LINK_DIR})

#找到所有的so库,存放在全局变量SO_DIR中

file(GLOB SO_DIR ${LINK_DIR}/*.so)

# 链接库

target_link_libraries(

utils

${SO_DIR}

${log-lib})

复制代码

源码地址

智慧旅游解决方案利用云计算、物联网和移动互联网技术,通过便携终端设备,实现对旅游资源、经济、活动和旅游者信息的智能感知和发布。这种技术的应用旨在提升游客在旅游各个环节的体验,使他们能够轻松获取信息、规划行程、预订票务和安排食宿。智慧旅游平台为旅游管理部门、企业和游客提供服务,包括政策发布、行政管理、景区安全、游客流量统计分析、投诉反馈等。此外,平台还提供广告促销、库存信息、景点介绍、电子门票、社交互动等功能。 智慧旅游的建设规划得到了国家政策的支持,如《国家中长期科技发展规划纲要》和国务院的《关于加快发展旅游业的意见》,这些政策强调了旅游信息服务平台的建设和信息化服务的重要性。随着技术的成熟和政策环境的优化,智慧旅游的时机已经到来。 智慧旅游平台采用SaaS、PaaS和IaaS等云服务模式,提供简化的软件开发、测试和部署环境,实现资源的按需配置和快速部署。这些服务模式支持旅游企业、消费者和管理部门开发高性能、高可扩展的应用服务。平台还整合了旅游信息资源,提供了丰富的旅游产品创意平台和统一的旅游综合信息库。 智慧旅游融合应用面向游客和景区景点主管机构,提供无线城市门户、智能导游、智能门票及优惠券、景区综合安防、车辆及停车场管理等服务。这些应用通过物联网和云计算技术,实现了旅游服务的智能化、个性化和协同化,提高了旅游服务的自由度和信息共享的动态性。 智慧旅游的发展标志着旅游信息化建设的智能化和应用多样化趋势,多种技术和应用交叉渗透至旅游行业的各个方面,预示着全面的智慧旅游时代已经到来。智慧旅游不仅提升了游客的旅游体验,也为旅游管理和服务提供了高效的技术支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值