转帖地址:http://www.ihubin.com/blog/android-ffmpeg-demo-3/
==================================================================================
编译环境
- Mac OS X Capitan 10.11.3
- NDK-r10e (64-bit)
- FFmpeg 3.0
简介
在看完了第一篇Android最简单的基于FFmpeg的例子(一)—编译FFmpeg类库的基础上再看这一篇,在前一文中,
编译FFmpeg生成了六个SO文件,如图:
由于数目繁多,直接使用这些类库还是比较麻烦的. 因此可以将它们合并为一个类库 libffmpeg.so .
操作步骤
与前文记录的脚本不同,这个脚本不再需要修改Configure的内容(生成的是.a而不是.so,并没有涉及到版本号问题)
前文记录的脚本里面Configure的时候是“–enable-shared –disable-static”,这个脚本里面Configure的时候设置的是“–enable-static –disable-shared”。
- 编译完成后生成的是:
- libavcodec.a
- libavfilter.a
- libswresample.a
- libavformat.a
- libavutil.a
- libswscale.a
该脚本运行完后,会把上述的*.a文件打包为一个so文件:
- libffmpeg.so
合并后的类库使用起来和合并前的类库使用方法没有区别。
修改后的脚本文件为:
build_android.sh
#!/bin/bash export TMPDIR=/Users/hubin/Desktop/ffmpeg-3.0/ffmpegtemp #这句很重要,不然会报错 unable to create temporary file in # NDK的路径,根据自己的安装位置进行设置 NDK=~/Applications/android-sdk/ndk-bundle # 编译针对的平台,可以根据自己的需求进行设置 # 这里选择最低支持android-14, arm架构,生成的so库是放在 # libs/armeabi文件夹下的,若针对x86架构,要选择arch-x86 PLATFORM=$NDK/platforms/android-14/arch-arm # 工具链的路径,根据编译的平台不同而不同 # arm-linux-androideabi-4.9与上面设置的PLATFORM对应,4.9为工具的版本号, # 根据自己安装的NDK版本来确定,一般使用最新的版本 TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 function build_one { ./configure \ --prefix=$PREFIX \ --target-os=linux \ --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \ --arch=arm \ --sysroot=$PLATFORM \ --extra-cflags="-I$PLATFORM/usr/include" \ --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 \ --disable-postproc \ --disable-avdevice \ --disable-symver \ --disable-stripping \ $ADDITIONAL_CONFIGURE_FLAG sed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h sed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h sed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h sed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h sed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h sed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h sed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h sed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h make clean make -j4 make install $TOOLCHAIN/bin/arm-linux-androideabi-ld \ -rpath-link=$PLATFORM/usr/lib \ -L$PLATFORM/usr/lib \ -L$PREFIX/lib \ -soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \ $PREFIX/libffmpeg.so \ libavcodec/libavcodec.a \ libavfilter/libavfilter.a \ libswresample/libswresample.a \ libavformat/libavformat.a \ libavutil/libavutil.a \ libswscale/libswscale.a \ -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \ $TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a \ } # arm v7vfp CPU=armv7-a OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU " PREFIX=./android/$CPU-vfp ADDITIONAL_CONFIGURE_FLAG= build_one # CPU=armv # PREFIX=$(pwd)/android/$CPU # ADDI_CFLAGS="-marm" # build_one #arm v6 #CPU=armv6 #OPTIMIZE_CFLAGS="-marm -march=$CPU" #PREFIX=./android/$CPU #ADDITIONAL_CONFIGURE_FLAG= #build_one #arm v7vfpv3 # CPU=armv7-a # OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU " # PREFIX=./android/$CPU # ADDITIONAL_CONFIGURE_FLAG= # build_one #arm v7n #CPU=armv7-a #OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8" #PREFIX=./android/$CPU #ADDITIONAL_CONFIGURE_FLAG=--enable-neon #build_one #arm v6+vfp #CPU=armv6 #OPTIMIZE_CFLAGS="-DCMP_HAVE_VFP -mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU" #PREFIX=./android/${CPU}_vfp #ADDITIONAL_CONFIGURE_FLAG= #build_one
执行build_android.sh:
1
|
$ chmod +x build_android.sh
|
1
|
$ ./build_android.sh
|
等待一会,编译成功以后就可以看到单个库版的FFmpeg了.
在 ffmpeg-3.0/android 目录下就能找到编译好的文件:
测试单个库版的FFmpeg
在Android最简单的基于FFmpeg的例子(二)—测试编译好的SO库的基础上,稍加修改就可以.
替换src/main/jni目录中的SO文件
替换前:
替换后:
修改Android.mk文件
修改前:
LOCAL_PATH := $(call my-dir) # FFmpeg library include $(CLEAR_VARS) LOCAL_MODULE := avcodec LOCAL_SRC_FILES := libavcodec-57.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avfilter LOCAL_SRC_FILES := libavfilter-6.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avformat LOCAL_SRC_FILES := libavformat-57.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avutil LOCAL_SRC_FILES := libavutil-55.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := swresample LOCAL_SRC_FILES := libswresample-2.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := swscale LOCAL_SRC_FILES := libswscale-4.so include $(PREBUILT_SHARED_LIBRARY) # Program include $(CLEAR_VARS) LOCAL_MODULE := ffmpegdemo LOCAL_SRC_FILES := ffmpegdemo.c LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_LDLIBS := -llog -lz LOCAL_SHARED_LIBRARIES := avcodec avfilter avformat avutil swresample swscale include $(BUILD_SHARED_LIBRARY)
修改后:
LOCAL_PATH := $(call my-dir) # FFmpeg library include $(CLEAR_VARS) LOCAL_MODULE := ffmpeg LOCAL_SRC_FILES := libffmpeg.so include $(PREBUILT_SHARED_LIBRARY) # Program include $(CLEAR_VARS) LOCAL_MODULE := ffmpegdemo LOCAL_SRC_FILES := ffmpegdemo.c LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_LDLIBS := -llog -lz LOCAL_SHARED_LIBRARIES := ffmpeg include $(BUILD_SHARED_LIBRARY)
修改MainActivity.java 加载SO库的代码
修改前:
static { System.loadLibrary("avcodec-57"); System.loadLibrary("avfilter-6"); System.loadLibrary("avformat-57"); System.loadLibrary("avutil-55"); System.loadLibrary("swresample-2"); System.loadLibrary("swscale-4"); System.loadLibrary("ffmpegdemo"); }
修改后:
static { System.loadLibrary("ffmpeg"); System.loadLibrary("ffmpegdemo"); }
Module:FFmpeg-Single-SO
Demo APK下载地址:https://www.pgyer.com/FFmpegSingleSO
参考: