故事很长,慢慢看!
首先我又一个需求,一张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项目去编译了。
出来的东西差不多这样子:
弄到以前的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,搞定!