轉帖地址:http://www.ihubin.com/blog/android-ffmpeg-demo-3/java
==================================================================================linux
- Mac OS X Capitan 10.11.3
- NDK-r10e (64-bit)
- FFmpeg 3.0
在看完了第一篇Android最簡單的基於FFmpeg的例子(一)—編譯FFmpeg類庫的基礎上再看這一篇,在前一文中,
編譯FFmpeg生成了六個SO文件,如圖:android
因爲數目繁多,直接使用這些類庫仍是比較麻煩的. 所以能夠將它們合併爲一個類庫 libffmpeg.so .api
與前文記錄的腳本不一樣,這個腳本再也不須要修改Configure的內容(生成的是.a而不是.so,並無涉及到版本號問題)bash
前文記錄的腳本里面Configure的時候是「–enable-shared –disable-static」,這個腳本里面Configure的時候設置的是「–enable-static –disable-shared」。架構
該腳本運行完後,會把上述的*.a文件打包爲一個so文件:ide
合併後的類庫使用起來和合並前的類庫使用方法沒有區別。工具
修改後的腳本文件爲:post
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
1
|
$ chmod +x build_android.sh
|
1
|
$ ./build_android.sh
|
等待一會,編譯成功之後就能夠看到單個庫版的FFmpeg了.
在 ffmpeg-3.0/android 目錄下就能找到編譯好的文件:
在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
參考: