开发环境

FFmpeg源码地址:https://github.com/FFmpeg/FFmpeg
编译环境:

  • macOS Mojava(10.14.2)
  • FFmpeg(tag:n3.4)
  • ndk-r10e

NDK配置
vim ~/.bash_profile
export ANDROID_NDK=/Users/zhouxiang/Library/Android/sdk/android-ndk-r10e
export PATH=$ANDROID_NDK:$PATH

修改configure文件

因为FFmpeg默认编译出来的so的版本号在.so之后(如libavcodec.so.5.100.1),而Android中并不能识别这种格式,
打开configure文件,所以我们修改下面的配置文件。

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)'

替换成

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'SLIB_INSTALL_LINKS='$(SLIBNAME)'

编写编译脚本

在FFmpeg目录下创建build_android.sh脚本,并赋予可执行的权限。
注意脚本中的TMPDIR以及NDK路径,并且需要保证TMPDIR目录是可写入的

#!/bin/bashmake clean# NDK的路径,根据自己的安装位置进行设置export TMPDIR=/code/FFmpeg/ffmpeg_compileexport NDK=/Users/zhouxiang/Library/Android/sdk/android-ndk-r10eexport SYSROOT=$NDK/platforms/android-21/arch-arm/export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64export CPU=armexport PREFIX=$(pwd)/android/$CPUexport ADDI_CFLAGS="-marm"function build_one{./configure \    --prefix=$PREFIX \    --target-os=linux \    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \    --arch=arm \    --sysroot=$SYSROOT \    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \    --extra-ldflags="$ADDI_LDFLAGS" \    --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \    --nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \    --enable-shared \    --enable-runtime-cpudetect \    --enable-gpl \    --enable-small \    --enable-cross-compile \    --disable-debug \    --disable-static \    --disable-doc \    --disable-asm \    --disable-ffmpeg \    --disable-ffplay \    --disable-ffprobe \    --disable-ffserver \    --enable-postproc \    --enable-avdevice \    --disable-symver \    --disable-stripping \$ADDITIONAL_CONFIGURE_FLAGsed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.hsed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.hsed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.hsed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.hsed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.hsed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.hsed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.hsed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.hmake clean# 这里是定义用几个CPU编译,我用4个,一般在5分钟之内编译完成make -j4make install}build_one

其中:

  • TMPDIR为编译生成的临时文件存放的目录
  • SYSROOT为so文件支持的最低Android版本的平台目录
  • CPU为指定so文件支持的平台
  • PREFIX为生成的so文件存放目录
  • TOOLCHAIN为编译所使用的工具链目录
  • cross-prefix为编译所使用的工具链文件
  • enable和disable指定了需要编译的项
  • target-os为目标操作系统;

执行编译脚本

./build_android.sh

如果一切正常,将会在FFmpeg/android/arm/lib目录下看到生成的so文件。

常见错误

libavcodec/aaccoder.c: In function 'search_for_ms':libavcodec/aaccoder.c:803:25: error: expected identifier or '(' before numeric constant                     int B0 = 0, B1 = 0;                         ^libavcodec/aaccoder.c:865:28: error: lvalue required as left operand of assignment                         B0 += b1+b2;                            ^libavcodec/aaccoder.c:866:25: error: 'B1' undeclared (first use in this function)                         B1 += b3+b4;                         ^libavcodec/aaccoder.c:866:25: note: each undeclared identifier is reported only once for each function it appears inmake: *** [libavcodec/aaccoder.o] Error 1

解决办法:https://blog.csdn.net/hyjwan/article/details/80384916
略坑

编译生成单个so文件

上面的脚本编译出来的是8个so文件,如果需要使用ffmpeg,就需要把so文件拷贝进去,这也太麻烦了。我们可以打包成一个so,这样引入时将更加方便。具体步骤如下,下面每一个字都是非常重要的,说多了都是泪,网上很多教程都是复制粘贴,根本没有验证!

Step1还原configure文件

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'SLIB_INSTALL_LINKS='$(SLIBNAME)'

还原成

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)'

Step2修改上面创建的build_android.sh,主要有以下两点:

  • 需要将disable-static enable-shared 修改成 enable-static disable-shared
  • 在make install之后添加打包脚本

具体脚本如下:

#!/bin/bashmake clean# NDK的路径,根据自己的安装位置进行设置export TMPDIR=/Users/zhouxiang/Desktopexport NDK=/Users/zhouxiang/Library/Android/sdk/android-ndk-r10eexport SYSROOT=$NDK/platforms/android-21/arch-arm/export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64export CPU=armv7-aexport PREFIX=$(pwd)/android/$CPUexport ADDI_CFLAGS="-marm"function build_one{./configure_before \    --prefix=$PREFIX \    --target-os=linux \    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \    --arch=arm \    --sysroot=$SYSROOT \    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \    --extra-ldflags="$ADDI_LDFLAGS" \    --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \    --nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \    --disable-shared \    --enable-runtime-cpudetect \    --enable-gpl \    --enable-small \    --enable-cross-compile \    --disable-debug \    --enable-static \    --disable-doc \    --disable-asm \    --disable-ffmpeg \    --disable-ffplay \    --disable-ffprobe \    --disable-ffserver \    --enable-postproc \    --enable-avdevice \    --disable-symver \    --disable-stripping \$ADDITIONAL_CONFIGURE_FLAGsed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.hsed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.hsed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.hsed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.hsed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.hsed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.hsed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.hsed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.hmake clean# 这里是定义用几个CPU编译,我用4个,一般在5分钟之内编译完成make -j4make install#打包$TOOLCHAIN/bin/arm-linux-androideabi-ld \    -rpath-link=$SYSROOT/usr/lib \    -L$SYSROOT/usr/lib \    -L$PREFIX/lib \    -soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \    $PREFIX/libffmpeg.so \    libavcodec/libavcodec.a \    libavdevice/libavdevice.a \    libavfilter/libavfilter.a \    libavformat/libavformat.a \    libavutil/libavutil.a \    libpostproc/libpostproc.a \    libswresample/libswresample.a \    libswscale/libswscale.a \    -lc -lm -lz -ldl -llog --dynamic-linker=system/bin/linker \    $TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9/libgcc.a#strip 精简文件$TOOLCHAIN/bin/arm-linux-androideabi-strip $PREFIX/libffmpeg.soecho "编译结束"}build_one

Step3执行脚本

编译完成之后会在android-armv7-a目录下生成libffmpeg.so文件


Mac编译FFmpeg(Android版本)_第1张图片

更多相关文章

  1. Dealing with Asset Compression in Android Apps(避免asset目录
  2. Intent打开各种类型的文件
  3. Android生成PDF文件
  4. android保存Bitmap图片到指定文件夹示例
  5. android studio恢复误删文件
  6. Android SD 卡文件浏览器
  7. Android 获取文件的缩略图
  8. Android 文件相关总结

随机推荐

  1. Android Goldfish详解之一
  2. Android截屏截图方法所有方法汇总(包括Act
  3. Android 自定义权限 ( )
  4. android LocationManager的使用
  5. Sqlite3常用简单指令
  6. Android Tasks、ActivityStack和Activity
  7. Kotlin 中Butterknife 和Android 中使用b
  8. Android解析ActivityManagerService(二)Act
  9. Activity的生命周期
  10. 13-6-3 android 自定义tabhost在底部与框