编译FFmpeg动态库

2024-09-01 17:04
文章标签 动态 编译 ffmpeg

本文主要是介绍编译FFmpeg动态库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

编译FFmpeg动态库

环境

  • 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-r17cndk-18b中的toolchains/llvm/prebuilt/darwin-x86_64/bin中没有clang编译工具集,而是在上层目录中。

  • 只有armv7-a的执行文件中间有eabi结尾,其他没有。例:armv7a-linux-androideabi21-clangx86_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_FLAGSmake cleanmake -j8make install
}
build_android

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

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

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

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

生成文件目录如下:

创建一个新的Android Cmake项目

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

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

#include <span><span><span>&lt;</span>jni.h</span><span>&gt;</span></span>//这里要注意,因为这是个c++文件,必须把头文件引用放到extern "C"中
//不然一直报undefined的错误,坑了很久,以前我都是写c
extern "C" {
#include &lt;libavutil/avutil.h&gt;JNIEXPORT jstring JNICALL
Java_demo_simple_example_1ffmpeg_MainActivity_getVersion(JNIEnv *env, jclass clazz) {const char *version = av_version_info();return env-&gt;NewStringUTF(version);
}}
android {compileSdkVersion 29buildToolsVersion "30.0.0"defaultConfig {applicationId "demo.simple.example_ffmpeg"minSdkVersion 21targetSdkVersion 29versionCode 1versionName "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(avutilSHAREDIMPORTED)
set_target_properties(avutilPROPERTIES IMPORTED_LOCATION${LIBS_DIR}/libavutil.so)#  依赖 NDK中自带的log库
find_library(log-lib log)#  链接库
target_link_libraries(utilsavutil${log-lib})

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

public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected 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_libraryset_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})

源码地址

example_ffmpeg

这篇关于编译FFmpeg动态库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1127528

相关文章

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

Python使用FFmpeg实现高效音频格式转换工具

《Python使用FFmpeg实现高效音频格式转换工具》在数字音频处理领域,音频格式转换是一项基础但至关重要的功能,本文主要为大家介绍了Python如何使用FFmpeg实现强大功能的图形化音频转换工具... 目录概述功能详解软件效果展示主界面布局转换过程截图完成提示开发步骤详解1. 环境准备2. 项目功能结

SpringBoot使用ffmpeg实现视频压缩

《SpringBoot使用ffmpeg实现视频压缩》FFmpeg是一个开源的跨平台多媒体处理工具集,用于录制,转换,编辑和流式传输音频和视频,本文将使用ffmpeg实现视频压缩功能,有需要的可以参考... 目录核心功能1.格式转换2.编解码3.音视频处理4.流媒体支持5.滤镜(Filter)安装配置linu