Android FFmpeg集成
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集成相关推荐
- Mac 平台 Android FFmpeg 编译与集成实践
文章目录 FFmpeg 是什么 为什么要学 FFmpeg 开发 FFmpeg 编译 1. 编译环境准备 2. FFmpeg 环境配置 3. 完整的脚本 4. FQA 编译小结 在Android Stu ...
- Android FFmpeg源码编译及在Android studio的集成
准备工具: 1,ubuntu server 18.04.4(其他发行版服务器或桌面版都行,我这里以ubuntu为例,可以使用虚拟机,也可以使用公网的服务器) 2,ndk R17c linux版 (下载 ...
- 【Android RTMP】Android Studio 集成 x264 开源库 ( Ubuntu 交叉编译 | Android Studio 导入函数库 )
文章目录 安卓直播推流专栏博客总结 一. x264 简介 二. x264 交叉编译 三. Android Studio 导入函数库 四. 交叉编译版本 五. GitHub 项目地址 安卓直播推流专栏博 ...
- FFmpeg 集成 x265 编译及解码
x265 是一个免费的软件库和应用程序,用于将视频流编码为 H.265/MPEG-H HEVC 压缩格式,并在 GNU GPL 条款下发布. FFmpeg 为了支持 H.265 编.解码可以集成 x2 ...
- 三.ffmpeg 集成av1
copy from zhujiamin 一.介绍 FFmpeg4.2支持AV1.AVS2等视频编码格式,但本身并不包含解码器,需要自己集成.集成的编解码器要避开GPL开源协议(–enable-gpl) ...
- Android FFmpeg视频播放器三 音频封装格式解码播放
Android FFmpeg视频播放器一解封装 Android Android FFmpeg视频播放器二 视频封装格式解码播放 视频解封装之后就会得到音频流和视频流,解封状得到的数据是AVPackag ...
- Android FFmpeg 音视频开发教程
LearnFFmpeg 项目地址:githubhaohao/LearnFFmpeg 简介: Android FFmpeg 音视频开发教程 更多:作者 提 Bug 标签: An Android FF ...
- FFmpeg集成到GPU
FFmpeg集成到GPU GPU加速视频处理集成到最流行的开源多媒体工具中. FFmpeg是最流行的开源多媒体操作工具之一,它有一个插件库,可以应用于音频和视频处理管道的各个部分,并在世界各地得到广泛 ...
- shareinstall之Android SDK集成
提示:以下代码(配置)由shareinstall根据当前应用动态生成,开发者可直接使用:按照以下步骤指引,10分钟即可完成Android SDK集成. 一.导入SDK Android SDK 下载 v ...
- 【Android FFMPEG 开发】Android 中使用 FFMPEG 对 MP3 文件进行混音操作
文章目录 一.前置操作 ( 移植 FFMPEG ) 二.FFMPEG 混音命令 三.Android FFMPEG 混音源代码完整示例 四.博客源码 一.前置操作 ( 移植 FFMPEG ) 参考 [A ...
最新文章
- 《自然》:修复AI神经网络的缺陷
- 如果list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法,所以列表生成式会报错:...
- [你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考
- python读取整个txt文件-Python读写txt文本文件
- Luogu2791 幼儿园篮球题【斯特林数,数学】
- Spring多线程批量发送邮件(ThreadPoolTaskExecutor)
- PHP 获取IP地址 获取当前时间 写文件
- tomcat的class加载的优先顺序
- Ubuntu安装指定版本clang-format
- 死链提交为什么不能提交 html文件,百度提交网站后死链一直未处理掉的原因有哪些?...
- SQL SERver2005中row_number() 的用法
- 【mysql】使数据表ID连续的两个方法
- Matlab 2015b安装教程
- xp系统怎样添加桌面计算机,如何为XP系统计算机设置桌面
- 拼途网: 从线上到线下的拼途旅行社区
- 平行四边形(几何)题解
- 记录TI电量计采集化学ID过程
- FITC-GSL I荧光素标记的西非单叶豆凝集素 I
- 利用 python numpy +matplotlib 绘制股票k线图
- python的Tkinter库简单应用——开发一个简易计算器
热门文章
- linux 修改网卡 mac地址命令,Centos系统下查看和修改网卡Mac地址(附ifconfig命令格式)...
- 命名实体消歧的代码实现
- 正向最大匹配、逆向最大匹配与双向匹配算法实现
- MATLAB-非线性回归
- 51单片机dds信号发生器 扫频 c语言,基于DDS正弦信号发生器设计.doc
- Safari 14.0 版本安装json插件
- USACO 2016 JANUARY CONTEST, BRONZE PROBLEM 3. MOWING THE FIELD(收割庄稼)
- ABBYY最新OCR文字识别软件 ,需激活码序列号密钥安装下载
- jsonDB使用手冊
- python外贸应用_Python脚本+Sublime免费查询阿里巴巴国际站产品排名