前几天发了一篇FFmpeg调用Android MediaCodec进行硬解码的文章。 上面的技术点并不算太难,调用FFmpeg依然是常见的socket操作,但关键点是FFmpeg版本选择和编译选项必须开启MediaCodec。 好的。
关于FFmpeg的编译,是老生常谈的话题了。 很多初学者都会卡在如何编译so的动态库上。 这似乎是 Android 开发转换音频和视频的主要绊脚石。 我什至没有时间写一行 FFmpeg 代码。 编译问题得折腾好久。
当然,编译问题肯定是FFmpeg的错。 由于其不断升级,从最初的2.x版本到现在的4.x版本,调用socket发生了变化,编译选项也调整了不少。 不过网上各种Android so动态库编译文章还没有相应更新。 ,有些教程还是2.x版本,如果按照说明编译的话,肯定会出现兼容性问题。
举几个例子:
早期编译版本需要更改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源代码。
这也是一个常见的兼容性问题。
选择NDK版本实际上就是选择编译器。 早期的编译可能使用了GCC编译。 后来Google在NDK r18b版本中删除了GCC编译工具。 详情请参考以下链接:
NDK 修订历史
因此,今天最新的动态库编译是使用Clang进行的。 为了与时俱进,没必要使用以前的NDK版本,直接使用最新的。
为了避免你把精力花在编译FFmpeg上,直接给出了一个Github Repo,所有的编译脚本都放在这个仓库里。
地址如下:
github.com/glumes/ffmp…
其中,FFmpeg源代码作为仓库的子模块加载进来。 下载时请注意:
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目录下。 如有必要ffmpeg源码怎么编译,您可以在该文件中进行更改,而不会影响主编译脚本的运行。
顺便贴一下源码:
这里是专门执行编译的函数。 函数使用的一些参数应该在外部定义:
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动态库了。 如果编译过程中遇到问题ffmpeg源码怎么编译,请在评论区留言联系我,及时调整,保证编译过程轻松完成。