FFMpeg 3.2移植到android遇到的各种坑,再一次总结

故事很长,慢慢看!


首先我又一个需求,一张jpg加上gif后,变成一个gif动图。如果你用命令ffmpeg -i  test.jpg -vf 'movie=test.gif[wm];[in][wm]overlay=0:0[out]' out.gif命令的话,我假设你的ffmpeg -version是3.2,那么恭喜,这个需求你很容易搞定。


不幸的是,我的android项目是2.8版本,用上面这个命令,很遗憾,只出来两帧!2 frame。(我当初还以为我编译的2.8版本有问题,于是从新git clone 一下2.8分支,编译,成功,./ffmpeg 命令一敲,对不起,就是2帧。)


后来我还下载超级古老的版本0.1版本的ffmpeg,编译后上面的命令,只出来一帧。


幸好!3.2版本很完美支持了这个需求。


于是下载了3.2版本,下载了libfaac,x264源码,统统编译好。

因为这篇是总结,所以直接说坑了。


第一个坑,其实3.2版本不支持libfaac了。嘿嘿。


第二个坑,x264编译的时候,一定要和ffmpeg的platform是一样的,否则发现不了。即使你-I -L各种加,都没用。

mac下的编译脚本:

cd x264
export NDK=/Users/nillu/Documents/Androidndk/android-ndk-r13b
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
export PLATFORM=$NDK/platforms/android-9/arch-arm
export PREFIX=../android-lib/x264/

./configure --prefix=$PREFIX \
--enable-static \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi- \
--sysroot=$PLATFORM

make
make install

cd ..


第三个坑,NDK版本千万不要用Android L。这个东西你编译处理,发现又一个strcpy是没办法用的,在android手机4.4.4上没办法运行!所以版本最好19以下,21以上,悲剧掉坑。

类似如下:

export NDK=/Users/nillu/Documents/Androidndk/android-ndk-r13b
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
export PLATFORM=$NDK/platforms/android-9/arch-arm
android_9最好不过了,如果你是21,估计要悲剧。



确认3个都没问题了,我们成功的编译出so库来了。FFMPEG默认编译出的so后面带版本号,有木有办法libavcodec_47.so的方式?有,修改configure里面的。差不多修改如下:

#ffmpeg默认编译出的是so加版本好,修改后变成xx_version.so
#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)'


SO出来后!就可以放到Android项目去编译了。

出来的东西差不多这样子:

FFMpeg 3.2移植到android遇到的各种坑,再一次总结_第1张图片


弄到以前的android项目后,就能运行了吗?So naive!


仔细想想,2.8为啥不能实现我们的需求,而3.2可以?其实原因就是API接口变了,你现在用2.8的 ffmpeg.c完全不能运行的,于是需要复制现在的ffmpeg.c,ffmpeg.h,cmdutils.h等一些文件放到android目录。需要编译jni和修改这些ffmpeg文件,为什么?


因为ffmpeg.c这些文件,不是针对android开发,是针对linux,mac系统开发的,现在在andriod项目include的头文件,其实是ffmpeg框架中很小的一部分而已。所以ffmepg.c引入的文件,你编译出的so以及include里面是没有的,我们需要修改。


修改吧,修改吧。吧exit_program return吧,不要exit(1)了。

把main方法改下吧,exit_program的都return 了。否则一运行就崩溃。把一些自己写的函数重新折腾进去吧~~~ 一天就这么过去了啊·~~~~


以为修改好就能运行了吗?


it too simple! 最后查了config.h和以前一对比,发现很多开关都是0!我草,是不是编译的so库有问题啊?没包括一些解码库啊?


cd 3.2

make clean

export NDK=/Users/nillu/Documents/Androidndk/android-ndk-r13b
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
export PLATFORM=$NDK/platforms/android-9/arch-arm
export PREFIX=out_ffmpeg_android_lib_full
build_one(){
  ./configure --target-os=linux --prefix=$PREFIX \
--enable-cross-compile \
--enable-runtime-cpudetect \
--disable-asm \
--arch=arm \
--cc=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi- \
--disable-stripping \
--nm=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--enable-gpl --enable-shared --disable-static --enable-nonfree --enable-version3 --enable-small --disable-vda --disable-iconv \
--enable-libx264 --enable-encoder=libx264 \
--enable-zlib --disable-ffprobe --disable-ffplay --disable-ffmpeg --disable-ffserver --disable-debug \
--extra-cflags="-I ../android-lib/x264/include -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a" \
--extra-ldflags="-L ../android-lib/x264/lib"

}

build_one

make
make install

cd ..


最后运行,OK,搞定!




你可能感兴趣的:(FFmpeg)