FFmpeg生成Android so库

上篇介绍了如何生成so库,这次介绍如何集成。

一、新建一个Android C++项目

这时候主工程目录下会有cpp文件夹,包含如下两个文件:

  • CMakeLists.txt:cmake脚本配置文件,cmake会根据该脚本文件中的指令去编译相关的C/C++源文件,并将编译后产物生成共享库或静态块,然后Gradle将其打包到APK中。
  • native-lib.cpp:用来写C相关的代码。

二、引入so库

  • app/src/main/cpp:将生成的include整体复制进去
  • src/main/jniLibs/arm64-v8a:创建文件路径,将生成的lib中的so库复制进去

三、配置app/build.gradle

plugins {id 'com.android.application'
}android {compileSdkVersion 29buildToolsVersion "29.0.3"defaultConfig {applicationId "com.simple.ffmpeg"minSdkVersion 19targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"//自动生成externalNativeBuild {cmake {cppFlags ''}}//1、手动添加ndk {abiFilters "arm64-v8a"//abiFilters "armeabi-v7a"}//2、手动添加packagingOptions {pickFirst 'lib/arm64-v8a/libswscale.so'pickFirst 'lib/arm64-v8a/libavcodec.so'pickFirst 'lib/lib/arm64-v8a/libavutil.so'pickFirst 'lib/arm64-v8a/libavutil.so'pickFirst 'lib/arm64-v8a/libavformat.so'pickFirst 'lib/arm64-v8a/libavfilter.so'pickFirst 'lib/arm64-v8a/libswresample.so'pickFirst 'lib/arm64-v8a/libavdevice.so'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}//自动生成externalNativeBuild {cmake {path file('src/main/cpp/CMakeLists.txt')version '3.10.2'}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}
}dependencies {implementation 'androidx.appcompat:appcompat:1.3.1'implementation 'com.google.android.material:material:1.4.0'implementation 'androidx.constraintlayout:constraintlayout:2.1.0'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.3'androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

第一个手动添加如果没有会报:

Execution failed for task ':app:externalNativeBuildDebug'.
> Build command failed.Error while executing process ../Android/sdk/cmake/3.10.2.4988404/bin/ninja with arguments {-C /Users/kewang/code/code_test/Ffmpeg/app/.cxx/cmake/debug/armeabi-v7a native-lib}ninja: Entering directory `/Users/kewang/code/code_test/Ffmpeg/app/.cxx/cmake/debug/armeabi-v7a'* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

第二个手动添加如果没有会报:

Execution failed for task ':app:mergeDebugNativeLibs'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade> More than one file was found with OS independent path 'lib/arm64-v8a/libswscale.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

四、CMakeLists.txt链接so库

需要在CMakeLists.txt中把相关的 so 添加和链接起来,要不然没法使用。

cmake_minimum_required(VERSION 3.10.2)# 支持gnu++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")# 1. 定义so库和头文件所在目录,方面后面使用
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
set(ffmpeg_head_dir ${CMAKE_SOURCE_DIR})# 2. 添加头文件目录
include_directories(${ffmpeg_head_dir}/include)# 3. 添加ffmpeg相关的so库
add_library( avutilSHAREDIMPORTED )
set_target_properties( avutilPROPERTIES IMPORTED_LOCATION${ffmpeg_lib_dir}/libavutil.so )add_library( swresampleSHAREDIMPORTED )
set_target_properties( swresamplePROPERTIES IMPORTED_LOCATION${ffmpeg_lib_dir}/libswresample.so )add_library( avcodecSHAREDIMPORTED )
set_target_properties( avcodecPROPERTIES IMPORTED_LOCATION${ffmpeg_lib_dir}/libavcodec.so )add_library( avfilterSHAREDIMPORTED)
set_target_properties( avfilterPROPERTIES IMPORTED_LOCATION${ffmpeg_lib_dir}/libavfilter.so )add_library( swscaleSHAREDIMPORTED)
set_target_properties( swscalePROPERTIES IMPORTED_LOCATION${ffmpeg_lib_dir}/libswscale.so )add_library( avformatSHAREDIMPORTED)
set_target_properties( avformatPROPERTIES IMPORTED_LOCATION${ffmpeg_lib_dir}/libavformat.so )add_library( avdeviceSHAREDIMPORTED)
set_target_properties( avdevicePROPERTIES IMPORTED_LOCATION${ffmpeg_lib_dir}/libavdevice.so )# 查找代码中使用到的系统库
find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log )# 配置目标so库编译信息
add_library( # Sets the name of the library.native-lib# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).native-lib.cpp)# 指定编译目标库时,cmake要链接的库
target_link_libraries(# 指定目标库,native-lib 是在上面 add_library 中配置的目标库native-lib# 4. 连接 FFmpeg 相关的库avutilswresampleavcodecavfilterswscaleavformatavdevice# Links the target library to the log library# included in the NDK.${log-lib} )

五、native-lib.cpp添加测试代码

完成好CMakeLists之后需要测试下到底成功没,这块打印输出FFmpeg的信息。

#include <jni.h>
#include <string>
#include <unistd.h>extern "C" JNIEXPORT jstring JNICALL
Java_com_simple_ffmpeg_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());
}extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libavcodec/jni.h>JNIEXPORT jstring JNICALL
Java_com_simple_ffmpeg_MainActivity_ffmpegInfo(JNIEnv *env, jobject  /* this */) {char info[40000] = {0};AVCodec *c_temp = av_codec_next(NULL);while (c_temp != NULL) {if (c_temp->decode != NULL) {sprintf(info, "%sdecode:", info);} else {sprintf(info, "%sencode:", 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[%s]\n", info, c_temp->name);c_temp = c_temp->next;}return env->NewStringUTF(info);
}
}

注意这个函数名称:Java_com_simple_ffmpeg_MainActivity_stringFromJNI,Java_包名的下划线格式_Java需要调用的方法名称。

六、加载native-lib.cpp测试代码

public class MainActivity extends AppCompatActivity {// 加载so库static {System.loadLibrary("native-lib");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = findViewById(R.id.sample_text);//调用JNI方法tv.setText(ffmpegInfo());}/*** A native method that is implemented by the 'ffmpeg' native library,* which is packaged with this application.*/public native String stringFromJNI();public native String ffmpegInfo();
}

结果如下:

Android FFmpeg集成相关推荐

  1. Mac 平台 Android FFmpeg 编译与集成实践

    文章目录 FFmpeg 是什么 为什么要学 FFmpeg 开发 FFmpeg 编译 1. 编译环境准备 2. FFmpeg 环境配置 3. 完整的脚本 4. FQA 编译小结 在Android Stu ...

  2. Android FFmpeg源码编译及在Android studio的集成

    准备工具: 1,ubuntu server 18.04.4(其他发行版服务器或桌面版都行,我这里以ubuntu为例,可以使用虚拟机,也可以使用公网的服务器) 2,ndk R17c linux版 (下载 ...

  3. 【Android RTMP】Android Studio 集成 x264 开源库 ( Ubuntu 交叉编译 | Android Studio 导入函数库 )

    文章目录 安卓直播推流专栏博客总结 一. x264 简介 二. x264 交叉编译 三. Android Studio 导入函数库 四. 交叉编译版本 五. GitHub 项目地址 安卓直播推流专栏博 ...

  4. FFmpeg 集成 x265 编译及解码

    x265 是一个免费的软件库和应用程序,用于将视频流编码为 H.265/MPEG-H HEVC 压缩格式,并在 GNU GPL 条款下发布. FFmpeg 为了支持 H.265 编.解码可以集成 x2 ...

  5. 三.ffmpeg 集成av1

    copy from zhujiamin 一.介绍 FFmpeg4.2支持AV1.AVS2等视频编码格式,但本身并不包含解码器,需要自己集成.集成的编解码器要避开GPL开源协议(–enable-gpl) ...

  6. Android FFmpeg视频播放器三 音频封装格式解码播放

    Android FFmpeg视频播放器一解封装 Android Android FFmpeg视频播放器二 视频封装格式解码播放 视频解封装之后就会得到音频流和视频流,解封状得到的数据是AVPackag ...

  7. Android FFmpeg 音视频开发教程

    LearnFFmpeg 项目地址:githubhaohao/LearnFFmpeg 简介: Android FFmpeg 音视频开发教程 更多:作者   提 Bug 标签: An Android FF ...

  8. FFmpeg集成到GPU

    FFmpeg集成到GPU GPU加速视频处理集成到最流行的开源多媒体工具中. FFmpeg是最流行的开源多媒体操作工具之一,它有一个插件库,可以应用于音频和视频处理管道的各个部分,并在世界各地得到广泛 ...

  9. shareinstall之Android SDK集成

    提示:以下代码(配置)由shareinstall根据当前应用动态生成,开发者可直接使用:按照以下步骤指引,10分钟即可完成Android SDK集成. 一.导入SDK Android SDK 下载 v ...

  10. 【Android FFMPEG 开发】Android 中使用 FFMPEG 对 MP3 文件进行混音操作

    文章目录 一.前置操作 ( 移植 FFMPEG ) 二.FFMPEG 混音命令 三.Android FFMPEG 混音源代码完整示例 四.博客源码 一.前置操作 ( 移植 FFMPEG ) 参考 [A ...

最新文章

  1. 《自然》:修复AI神经网络的缺陷
  2. 如果list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法,所以列表生成式会报错:...
  3. [你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考
  4. python读取整个txt文件-Python读写txt文本文件
  5. Luogu2791 幼儿园篮球题【斯特林数,数学】
  6. Spring多线程批量发送邮件(ThreadPoolTaskExecutor)
  7. PHP 获取IP地址 获取当前时间 写文件
  8. tomcat的class加载的优先顺序
  9. Ubuntu安装指定版本clang-format
  10. 死链提交为什么不能提交 html文件,百度提交网站后死链一直未处理掉的原因有哪些?...
  11. SQL SERver2005中row_number() 的用法
  12. 【mysql】使数据表ID连续的两个方法
  13. Matlab 2015b安装教程
  14. xp系统怎样添加桌面计算机,如何为XP系统计算机设置桌面
  15. 拼途网: 从线上到线下的拼途旅行社区
  16. 平行四边形(几何)题解
  17. 记录TI电量计采集化学ID过程
  18. FITC-GSL I荧光素标记的西非单叶豆凝集素 I
  19. 利用 python numpy +matplotlib 绘制股票k线图
  20. python的Tkinter库简单应用——开发一个简易计算器

热门文章

  1. linux 修改网卡 mac地址命令,Centos系统下查看和修改网卡Mac地址(附ifconfig命令格式)...
  2. 命名实体消歧的代码实现
  3. 正向最大匹配、逆向最大匹配与双向匹配算法实现
  4. MATLAB-非线性回归
  5. 51单片机dds信号发生器 扫频 c语言,基于DDS正弦信号发生器设计.doc
  6. Safari 14.0 版本安装json插件
  7. USACO 2016 JANUARY CONTEST, BRONZE PROBLEM 3. MOWING THE FIELD(收割庄稼)
  8. ABBYY最新OCR文字识别软件 ,需激活码序列号密钥安装下载
  9. jsonDB使用手冊
  10. python外贸应用_Python脚本+Sublime免费查询阿里巴巴国际站产品排名