ffmpeg 在 win平台下的编译以及集成

目录
  • 引言
  • 1、交叉编译
  • 2、FFmpeg编译
  • 3、FFmpeg集成

引言

Java是 write once,run anywhre,但 C 不一样,各平台均有差异,无法只写一次,而且各个平台的编译都不一样。比如android的ndk工具链,不同平台的库都是不一样的

本文主要讲解下 ffmpeg 在 win 平台下的编译以及集成

1、交叉编译

交叉编译:交叉编译就是程序的编译环境和实际运行环境不一致,即在一个平台上生成另一个平台上的可执行代码。

为什么要交叉编译,其实之前原因已经说过了,因为不同平台的差异,指令集都不一样,比如win上面是intel的指令集,但android手机上几乎百分百都是arm的指令集,所以直接拿win上编译出来的库给android用,肯定无法使用的,所以需要交叉编译。

交叉编译主要是借助android 的ndk工具包

下面大致列举了一下经常会用到的组件。

  • ARM 交叉编译器
  • 构建工具
  • Java 原生接口头文件
  • C 库
  • Math 库
  • 最小的 C++ 库
  • ZLib 压缩库
  • POSIX 线程
  • Android 日志库
  • Android 原生应用 API
  • OpenGL ES 库
  • OpenSL ES 库

下面来看一下 Android 所提供的 NDK 跟目录下的结构。

  • ndk-build: 该 Shell 脚本是 Android NDK 构建系统的起始点,一般在项目中仅仅执行这一个命令就可以编译出对应的动态链接库了。
  • ndk-gdb: 该 Shell 脚本允许用 GUN 调试器调试 Native 代码,并且可以配置到 AS 中,可以做到像调试 Java 代码一样调试 Native 代码。
  • ndk-stack: 该 Shell 脚本可以帮组分析 Native 代码崩溃时的堆栈信息。
  • build: 该目录包含 NDK 构建系统的所有模块。
  • platforms: 该目录包含支持不同 Android 目标版本的头文件和库文件, NDK 构建系统会根据具体的配置来引用指定平台下的头文件和库文件。
  • toolchains: 该目录包含目前 NDK 所支持的不同平台下的交叉编译器 - ARM 、X86、MIPS ,目前比较常用的是 ARM 。构建系统会根据具体的配置选择不同的交叉编译器。

toolchains里一般会提供这么一些工具:

  • CC:编译器,对C源文件进行编译处理,生成汇编文件。
  • AS:将汇编文件生成目标文件(汇编文件使用的是指令助记符,AS将它翻译成机器码)。
  • AR:打包器,用于库操作,可以通过该工具从一个库中删除或者增加目标代码模块。
  • LD:链接器,为前面生成的目标代码分配地址空间,将多个目标文件链接成一个库或者是可执行文件。
  • GDB:调试工具,可以对运行过程中的程序进行代码调试工作。
  • STRIP:以最终生成的可执行文件或者库文件作为输入,然后消除掉其中的源码。
  • NM:查看静态库文件中的符号表。
  • Objdump:查看静态库或者动态库的方法签名。

不过不同版本的ndk,里边的工具不一样,部分新的ndk里可能就没有ar 、strip 之类的,可能在新的ndk里这些工具命名不一样或者是放在其它地方了,比如本人发现的21.1.6352462(win)中包含 strip 和 ar,但 24.0.8215888 版本中没有相关库,而且这几个版本中都没有 nm 库,在编译 ffmpeg时一定会提示找不到nm,幸好 nm不是必须的,不慌,如果遇到找不到相关工具,说明路径设置的有问题,或者根本就是当前版本的ndk中没有此类工具或者已经改名,需要去找找资料看看新版本的工具叫啥或者干脆下载旧版本ndk

2、FFmpeg编译

一名优秀的c++开发,必须得对c++编译有一定了解。前文已经介绍了交叉编译,那现在就来学习如何编译 ffmpeg 吧

在ffmpeg官网下载源码:

git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg

根据自己需要,切换自己想要的版本。

ffmpeg的编译其实已经非常简单了,因为牛逼的ffmpeg开发者提供了一个脚本,叫 configure,其实我们写的编译脚本就是在指定编译工具的位置,然后调用 configure 脚本编译

本人是在win11上编译 ffmpeg,需要下载msys2工具并配置相关环境,必须以管理员运行msys2之后才能来配置环境,否则就会报异常

pacman -S make yasm diffutils pkg-config #在msys2上安装必要软件

然后在ffmpeg文件夹内建脚本文件,并把如下内容贴上:

 #!/bin/sh

NDK_PATH=/c/workspace/android_sdk/ndk/21.1.6352462

BUILD_PLATFORM=windows-x86_64

API=21

ANDROID_ARMV5_CFLAGS="-march=armv5te"
ANDROID_ARMV7_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"
ANDROID_ARMV8_CFLAGS="-march=armv8-a"
ANDROID_X86_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
ANDROID_X86_64_CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"

# params($1:arch,$2:arch_abi,$3:compiler,$4:cross_prefix,$5:cflags)
build_bin() {

    echo "-------------------star build $2-------------------------"

    ARCH=$1         # arm arm64 x86 x86_64
    # CPU
    ANDROID_ARCH_ABI=$2     # armeabi armeabi-v7a x86 mips

    COMPILER=$3

    PREFIX=$(pwd)/dist/${ANDROID_ARCH_ABI}/

    TOOLCHAIN=${NDK_PATH}/toolchains/llvm/prebuilt/${BUILD_PLATFORM}

    CC=${TOOLCHAIN}/bin/${COMPILER}-clang

    CXX=${TOOLCHAIN}/bin/${COMPILER}-clang++

    SYSROOT=${TOOLCHAIN}/sysroot

    CROSS_PREFIX=${TOOLCHAIN}/bin/$4-

    CFLAGS=$5

    echo "pwd==$(pwd)"
    echo "ARCH==${ARCH}"
    echo "PREFIX==${PREFIX}"
    echo "SYSROOT=${SYSROOT}"
    echo "CFLAGS=${CFLAGS}"
    echo "CC==${CC}"
    echo "CROSS_PREFIX=${CROSS_PREFIX}"

	sh ./configure \
        --prefix=${PREFIX} \
        --enable-neon \
        --enable-hwaccels \
        --enable-gpl \
        --disable-postproc \
        --disable-debug \
        --enable-small \
        --enable-jni \
        --enable-mediacodec \
        --enable-decoder=h264_mediacodec \
        --disable-static \
        --enable-shared \
        --disable-doc \
        --enable-ffmpeg \
        --disable-ffplay \
        --disable-ffprobe \
        --disable-avdevice \
        --disable-doc \
        --disable-symver \
        --target-os=android \
        --arch=${ARCH} \
        --cc=$CC \
        --sysroot=$SYSROOT \
        --enable-cross-compile \
        --cross-prefix=${CROSS_PREFIX} \
        --extra-cflags="-Os -fPIC -DANDROID -Wfatal-errors -Wno-deprecated $CFLAGS" \
        --extra-cxxflags="-D__thumb__ -fexceptions -frtti" \
        --extra-ldflags="-L${SYSROOT}/usr/lib" \

    make clean
    make -j8
    make install

    echo "-------------------$2 build end-------------------------"
}

# build armeabi
# build_bin arm armeabi arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV5_CFLAGS"

#build armeabi-v7a
#build_bin arm armeabi-v7a armv7a-linux-androideabi${API} arm-linux-androideabi "$ANDROID_ARMV7_CFLAGS"

#build arm64-v8a
 build_bin arm64 arm64-v8a aarch64-linux-android${API} aarch64-linux-android "$ANDROID_ARMV8_CFLAGS"

#build x86
# build_bin x86 x86 i686-linux-android${API} i686-linux-android "$ANDROID_X86_CFLAGS"

#build x86_64
# build_bin x86_64 x86_64 x86_64-linux-android${API} x86_64-linux-android "$ANDROID_X86_64_CFLAGS"

相关解释:

  • CC:指定c编译器路径
  • CROSS_PREFIX:指定交叉编译工具文件路径的统一前缀。各个工具的最终文件路径为:cross-prefix + 工具名,比如上面脚本的prefix为TOOLCHAIN/bin/arm-linux-androideabi-,那么ar工具的路径即为TOOLCHAIN/bin/arm-linux-androideabi-ar
  • target-os:指定目标平台,因为 ffmpeg 可以在各平台上运行的,各平台上一些配置不太一样,所以需要指定的

另外编译脚本里边还有大量的 enable disable ,这些都是 configure 脚本里的编译选项,比如说 --enable-shared 意思就是编译动态库,所以上面的脚本最终会生成 so 文件,而不会生成 a 文件。

这些编译选项都可以使用 configure --help,可以查询到,大家可以试试

不管是这些 enable 编译选项,还是像 CC 一类的选项,都是在配置 configure 脚本,通过文本方式打开 configure 文件,可以看到:

--cc=CC                  use C compiler CC [$cc_default]
--target-os=OS           compiler targets OS [$target_os]
--enable-shared          build shared libraries [no]

运行编译脚本之后,如果编译成功了就会看到相关so库了,so库在lib文件夹中

3、FFmpeg集成

首先看cmakelist怎么写:

# 设置最小使用版本
cmake_minimum_required(VERSION 3.18.1)

project("demo")

include_directories(include)

# 添加本地so库 native-lib:这个是声明引用so库的名称 SHARED:表示共享so库文件
# 构建so库的源文件
add_library(
        demo
        SHARED
        native-lib.cpp
)

set(SO_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

# 使用系统ndk 提供的库,如 log库
# log-lib 这个指定的是在NDK库中每个类型的库会存放一个特定的位置,而log库存放
# 在log-lib中
# log 指定使用log库
find_library(
        log-lib
        log
)

message("c_CMAKE_SOURCE_DIR:" ${CMAKE_SOURCE_DIR} )

# 加载avcodec-57库
add_library( avcodec
        SHARED
        IMPORTED)
set_target_properties( avcodec
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libavcodec.so)

add_library( avutil
        SHARED
        IMPORTED)
set_target_properties( avutil
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libavutil.so)

add_library( swresample
        SHARED
        IMPORTED)
set_target_properties( swresample
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libswresample.so)

add_library( avfilter
        SHARED
        IMPORTED)
set_target_properties( avfilter
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libavfilter.so)

add_library( avformat
        SHARED
        IMPORTED)
set_target_properties( avformat
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libavformat.so)

add_library( swscale
        SHARED
        IMPORTED)
set_target_properties( swscale
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libswscale.so)
#----------------------end-----------------------

# 如果你本地的库(native-lib)想要调用log库的方法,
# 那么就需要配置这个属性,意思是把NDK库关联到本地库。
# 第一个参数表示本地的库 native-lib 要调用到log库的方法,即要被关联的库名称,log-lib 要关联的库名称
target_link_libraries(
        demo
        #ffmpeg------start----------
        avcodec
        avutil
        swresample
        avfilter
        avformat
        swscale
        #ffmpeg------end------------
        ${log-lib}
)

其实这些写法都非常简单,如果出错肯定是没写对,注意下相关细节即可。 所有代码均已上传到本人github中

以上就是ffmpeg 在 win平台下的编译以及集成的详细内容,更多关于FFmpeg win编译集成的资料请关注我们其它相关文章!

(0)

相关推荐

  • Go语言调用ffmpeg-api实现音频重采样

    目录 前言 环境部署 代码 总结 前言 最近对golang处理音视频很感兴趣,对golang音视频常用库goav进行了一番研究.自己写了一个wav转采样率的功能.给大家分享一下,中间遇到了不少坑,解决的过程中还是蛮有意思的. 环境部署 代码运行在Ubuntu环境上,需要使用到goav,goav是对ffmpeg源码的golang封装. goav地址:https://github.com/giorgisio/goav goav安装如下 sudo apt-get -y install autoconf

  • Mac上Python使用ffmpeg完美解决方案(避坑必看!)

    目录 一.在系统中安装ffmpeg 二.配置环境变量 三.在Python中安装ffmpeg 四.配置文件让Python能够使用 总结 近期有个需要进行音频转码的小任务需要用到ffmpeg,安装和使用的过程中遇到了很多问题没有办法解决,从网上找了各种教程也是一言难近,本文二哥来梳理一下从0到1在Mac上使用ffmpeg. 一.在系统中安装ffmpeg 第一步需要在系统中安装ffmpeg,很多人都给出了使用brew命令进行下载的方案,在此说一下,多数人brew后都需要等n分钟,最后以报错告终,这种外

  • 如何利用FFmpeg合并音频和视频(多种方式)

    目录 一.FFmpeg 多个音频合并的2种方法 一种方法是连接到一起 另一种方法是混合到一起 音频文件截取指定时间部分 音频文件格式转换 二.FFmpeg合并视频文件的4种方法 1.使用concat协议进行视频文件的合并 2.使用concat滤镜(filter)进行视频文件的合并: 方法一:FFmpeg concat 协议 方法二:FFmpeg concat 分离器 方法三:Mencoder 连接文件并重建索引 方法四:使用 FFmpeg concat 过滤器重新编码(有损) 一.FFmpeg

  • Python进行ffmpeg推流和拉流rtsp、rtmp实例详解

    目录 前言 1.RTMP(Real Time Messaging Protocol,实时消息协议) 2.RTSP(Real Time Streaming Protocol,实时流协议) 3.FFmpeg 4.python实现ffmpge的rtsp和rtmp推流拉流(待更) 总结 前言 流媒体协议,英文学名Streaming Protocol,用一句人话来解释:流媒体协议是一种用于通过 Web 传递多媒体的协议.传统视频流协议:RTMP和RTSP,其中 RTMP 是基于 TCP 开发的,那么 RT

  • FFmpeg进阶教程之给视频添加文字水印

    目录 前言 文字水印配置项 文字水印关键点 定义滤镜实现 项目工程源码 使用效果 总结 前言 和图片水印一样,很多时候为了声明视频的原创性,我们会给视频添加文字水印进行版权保护.添加文字水印和添加图片水印的流程相似,但又略有不同,这里介绍一下如何通过FFmpeg给视频添加文字水印.添加文字水印的流程图如下图所示: 文字水印配置项 在讲文字水印之前先介绍一下文字水印支持的那些配置,方便大家的使用. 项目 介绍 使用格式 drawtext=fontfile=font_f:text=text1…(通过

  • C/C++在Java、Android和Objective-C三大平台下实现混合编程

    Android和iOS开发都支持C++开发,可以一套代码多平台使用.同时C++难以反编译的特性也可以为Android开发带来代码的保密,另一native特性也可以提高代码的运行效率. 一.为什么使用C/C++ 便于移植,用C/C++写得库可以方便在其他的平台上再次使用. 代码的保护,由于java层代码很容易被反编译,而C/C++库反汇难度较大. 提高程序的执行效率,将要求高性能的应用逻辑使用C/C++开发,从而提高应用程序的执行效率. 访问现有开源库,需要访问底层的API或引用一些只有C/C++

  • PHP pthreads v3在centos7平台下的安装与配置操作方法

    本文实例讲述了PHP pthreads v3在centos7平台下的安装与配置操作方法.分享给大家供大家参考,具体如下: 我的centos版本是7.4.1708,php的版本是7.2.4(注意要是线程安全版),如下图所示: 首先我们在如下网址下载好pthreads的源码: http://pecl.php.net/package/pthreads 如:pthreads-3.1.6.tgz 1.解压.并进入目录 > tar xf pthreads-3.1.6.tgz > cd pthreads-3

  • Linux 6下安装编译安装Nginx的步骤

    Linux 6下安装编译安装Nginx的步骤 前言: Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.在高连接并发的情况下,Nginx是Apache服务器不错的替代品:Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一.能够支持高达50,000个并发连接数的响应,而且内存开销极小.这也是Nginx广受欢迎的重要原因.本文演示了基于Linux 6下编译安装Nginx,供大家参考. 一.安装环境 # cat /etc/issue Red Ha

  • Linux下g++编译与使用静态库和动态库的方法

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库(*.a)与动态库(*.so)的生成与使用方式是不同的.刚开始可能会不适应,但是用多了应该会习惯这种使用,因为步骤上并没有VS下配置那么繁琐. 下面就分别总结下linux下生成并使用静态库与动态库的方法:(由于是C++项目,所以编译器用的g++,但是与gcc的使用是相通的) 首先是准备工作,把我们需

  • Windows7下安装 Nodejs 并在 WebStorm 9.0.1 下搭建编译 LESS 环境的图文教程

    1. 打开Nodejs官网http://www.nodejs.org/,点"DOWNLOADS",点64-bit下载"node-v0.10.33-x64.msi". 2. 下载好后,双击"node-v0.10.33-x64.msi",按照默认选项安装Nodejs,默认安装路径为:C:\Program Files\nodejs. (请根据系统位数自行安装) 3. "开始"-->cmd,打开cmd程序,输入"nod

  • Win 2000下ASP.NET开发环境的配置

    Win 2000下ASP.NET的配置 Win 2000(包括Professional,Server和Advanced Server)在默认情况下是不支持ASP.NET的.必须对它进行一个环境的配置. 客户端 SQL Server .NET 数据提供程序 Microsoft 数据访问组件 (MDAC) 2.6 或更高版本 对系统管理信息的访问 Windows Management Instrumentation (WMI)(在 Windows 2000操作系统一起安装)COM+ 服务 Windo

  • Linux下手动编译安装PHP扩展的例子分享

    开发和部署的过程中可能会经常出现需要额外安装PHP扩展的情况,下边以PDO_MYSQL为例,介绍下手动编译安装PHP扩展: 先到http://pecl.php.net/找需要的版本,我用的是稳定的版本.要先看看说明,特别是要注意mysql的php的版本. 复制代码 代码如下: wget http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz tar xzvf PDO_MYSQL-1.0.2.tgz cd PDO_MYSQL-1.0.2 /usr/local/php

  • win系统下nodejs环境安装配置

    win系统下nodejs安装及环境配置,具体内容如下 第一步:下载安装文件 下载nodejs,官网:http://nodejs.org/download/,我这里下载的是node-v0.10.28-x86.msi,如下图: 第二步:安装nodejs 下载完成之后,双击"node-v0.10.28-x86.msi",开始安装nodejs,自定义安装在D:\dev\nodejs下面. 在cmd控制台输入:node -v,控制台将打印出:v0.10.28,出现版本提示表示安装成功. 该引导步

  • 在WIN命令提示符下mysql 用户新建、授权、删除,密码修改

    首先要声明一下:一般情况下,修改MySQL密码,授权,是需要有mysql里的root权限的. 注:本操作是在WIN命令提示符下,phpMyAdmin同样适用. 用户:phplamp 用户数据库:phplampDB 1.新建用户 //登录MYSQL @>mysql -u root -p @>密码 //创建用户 mysql> insert into mysql.user(Host,User,Password) values("localhost","phplam

  • JDK 7U15在 Windows x86平台下的安装方法

    这里以JDK 7U15在 Windows x86平台下的安装为例,其他平台安装与此类同. 下载JDK请查看:JDK最新下载地址[含下载方法] ①JDK 7U15下载完成后,是一个可执行文件,如图所示: ②双击运行该安装程序,出现如下界面: ③点击"下一步",出现如下界面: ④可以看到,JDK包含了Java开发工具.源代码(基础类库)和公共JRE,这三项都是默认安装的,是Java开发所必须的,缺一不可.这里,可以更改JDK的安装目录.选择好安装目录,点击"下一步",进

随机推荐