老生常谈 -- Android FFmpeg 动态库的编译问题轻松搞定 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
glumess
V2EX    Android

老生常谈 -- Android FFmpeg 动态库的编译问题轻松搞定

  •  
  •   glumess 2021-10-30 13:35:53 +08:00 12522 次点击
    这是一个创建于 1441 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前几天发了一篇 FFmpeg 调用 Android MediaCodec 进行硬解码 的文章,这里面的技术点不算太难,也还是调用 FFmpeg 的常用接口操作,但重点在于FFmpeg 的版本选择以及编译选项要开启 MediaCodec 才行。

    关于 FFmpeg 的编译,是个老生常谈的话题了,很多初学者都会卡在怎么编译动态库 so 的问题上,这其实也是 Android 开发转音视频的一大拦路虎,一行 FFmpeg 代码都没来得及写呢,就得先折腾好久编译问题。

    当然了,编译麻烦肯定是 FFmpeg 的锅。因为它的不断升级,从早期 2.x 版本到现在的 4.x 版本,调用接口发生了变化,编译选项也调整了不少,但网上的各种 Android so 动态库编译文章可没有对应更新哦,有的教程还停留在 2.x 版本上,如果你照着去编译了,这里面肯定会有兼容性问题的。

    举几个例子:

    • FFmpeg 源码里面的文件要修改吗?

    早期的编译版本还要在 FFmpeg 里面修改一些源码才行,最常见的就是下面的代码:

    SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' LIB_INSTALL_EXTRA_CMD='?(RANLIB)"$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)' 

    以前需要修改编译后库名字的连接方式,但是在最新版本中是不用了(最新版指的是 ffmpeg 的 release/4.4 分支版本)。

    另外,在实际编译中也不需要修改任何 FFmpeg 源码的。

    • Android NDK 要用哪个版本?

    这也是个常见的兼容性问题。

    选择 NDK 版本实际上是在选择编译器,早先编译可能用的是 GCC 编译,后来 Google 在 NDK r18b 版本移除了 GCC 编译工具,具体可以参考如下链接:

    NDK 修订历史记录

    所以现在最新的动态库编译都是用 Clang 进行操作的,为了跟上时代步伐,也就不要用之前的 NDK 版本了,直接上最新的。


    为了避免大家把精力消耗在 FFmpeg 的编译上,直接就给出一个 Github Repo ,将编译脚本都放在这个仓库上了。

    地址如下:

    https://github.com/glumes/ffmpeg_android

    FFmpeg 编译

    其中 FFmpeg 源码是作为该仓库的一个子模块 Submodules 的形式加载进来的,在下载时要注意一下:

    git clone --recursive https://github.com/glumes/ffmpeg_android 

    下载后,进入到 build_android.sh 文件中,将 NDK 替换成你自己的路径,最好也用 r20b 版本的,保持一致。

    #!/bin/bash #你的 NDK 路径 NDK=/Users/glumes/Downloads/android-ndk-r20b TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64 API=21 

    替换后,给脚本可执行权限就能运行了,编译后的动态库在 ffmpeg_library 文件夹中,目前仅编译了 armeabi-v7a 架构的。

    android 文件夹内对应加载 so 的 Android 工程,也是 FFmpeg 调用 Android MediaCodec 的源码。

    这个工程目录也是不需要修改 FFmpeg 的,并且关于 FFmpeg 的很多编译选项开关放在了 config-env.sh 目录中,有需要可以在文件内做修改,不影响主的编译脚本运行。

    顺便贴一下源码:

    这里是具体执行编译的函数,函数用到的一些参数要在外面定义好:

    function build_android { echo "Compiling FFmpeg for $CPU" ./configure \ --prefix=$PREFIX \ --libdir=$LIB_DIR \ --enable-shared \ --disable-static \ --enable-jni \ --disable-doc \ --disable-symver \ --disable-programs \ --target-os=android \ --arch=$ARCH \ --cpu=$CPU \ --cc=$CC \ --cxx=$CXX \ --enable-cross-compile \ --sysroot=$SYSROOT \ --extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \ --extra-ldflags="$ADDI_LDFLAGS" \ --disable-asm \ # 这些编译参数在 config-env.sh 文件中定义了 $COMMON_FF_CFG_FLAGS make clean make -j8 # 这里是定义用几个 CPU 编译 make install echo "The Compilation of FFmpeg for $CPU is completed" } 

    接下来定义好相关参数,就可以执行了:

    // 编译的 configure 可执行文件在 ffmpeg 源码目录中,要先进入到目录里 cd ffmpeg // 定义好编译的架构 OUTPUT_FOLDER="armeabi-v7a" ARCH="arm" CPU="armv7-a" TOOL_CPU_NAME=armv7a TOOL_PREFIX="$TOOLCHAIN/bin/arm-linux-androideabi" CC="$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang" CXX="$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++" SYSROOT="$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot" PREFIX="${PWD}/../ffmpeg_library/android/$OUTPUT_FOLDER" LIB_DIR="${PWD}/../ffmpeg_library/android/libs/$OUTPUT_FOLDER" OPTIMIZE_CFLAGS="-march=$CPU" build_android 

    由于我们的编译脚本不放在 FFmpeg 源码目录中,所以要对路径做一些修改,这样可以绝对地不改动任何 FFmpeg 内容了。

    通过上述的参数设定,应该就可以编译出正确的 Android 动态库了,如果你在编译过程中有任何问题,欢迎加我微信 ezglumes 联系我,及时调整保证轻松搞定编译过程。

    6 条回复    2021-11-01 10:17:18 +08:00
    771007147
        1
    771007147  
       2021-10-30 16:41:37 +08:00
    正好做音视频,关注了
    glumess
        2
    glumess  
    OP
       2021-10-30 22:44:36 +08:00
    @771007147 感谢老铁
    waruqi
        3
    waruqi  
       2021-10-31 13:34:22 +08:00 via Android
    直接用 xrepo install -p android --ndk=/xx/android-ndk-r20b ffmpeg 就行了

    或者直接走 xmake 的 add_requires("ffmpeg") 一键编译集成 ffmpeg 库
        4
    glumess  
    OP
       2021-10-31 20:51:40 +08:00
    @waruqi 我擦,现在都这么流弊了哇,太进步了,一键搞定啊
    glumess
    Cassius
        5
    Cassius  
       2021-11-01 00:31:17 +08:00 via Android
    话说硬编码的有没有相关文章,目前在学习这部分内容,各版本编码问题简直一把泪
    happyhou
        6
    happyhou  
       2021-11-01 10:17:18 +08:00
    点赞
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1211 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 19ms UTC 17:25 PVG 01:25 LAX 10:25 JFK 13:25
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86