下載ffmpeg庫,本文以ffmpeg-4.2.3爲例。
編譯工具鏈
對於C/C++的編譯,通常有兩個工具 GCC 和 CLANG 。這兩個庫的區別就不介紹了,感興趣的同學自行查閱相關資料。
Google在 ndk 17 以後,把 GCC 移除了,全面推行使用 CLANG 。所以各位同學一定要注意自己的ndk環境。
編譯、交叉編譯工具目錄
編譯工具鏈目錄:
android-ndk-r17c/toolchains/llvm/prebuilt/darwin-x86_64/bin
交叉編譯環境目錄:
android-ndk-r17c/sysroot
有意思的是ndk 17之後的版本中toolchains/llvm/prebuilt/darwin-x86_64路徑下也有sysroot文件夾。
1)toolchains目錄結構
2)sysroot目錄結構
該目錄右側列出來支持的不同CPU架構及編輯版本,我們選擇 CPU 架構 armv7a,Android版本 21爲例
armv7a-linux-androideabi21-clang
armv7a-linux-androideabi21-clang++
使用 GCC 編譯FFmpeg
下載 NDK r17c庫
編譯腳本
打開ffmpeg-4.2.3文件夾,創建腳本文件build_gcc_arm.sh,編輯腳本內容
CPU=armv7-a
API=21
ARCH=arm
NDK=/Users/liuhongshuo/AnroidPro/ffmpeg/android-ndk-r17c
SYSROOT=$NDK/platforms/android-$API/arch-arm
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/arm-linux-androideabi
# 要保存動態庫的目錄,這裏保存在源碼根目錄下的android/armv7-a
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
$ADDITIONAL_CONFIGURE_FLAG
function build_android
{
echo -e "\033[32m build start \033[0m"
./configure \
--target-os=android \
--prefix=$PREFIX \
--arch=$ARCH \
--cpu=$CPU \
--enable-cross-compile \
--enable-static \
--disable-shared \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
--sysroot=$SYSROOT \
--extra-cflags="-I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=$API -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -Wno-deprecated -mfloat-abi=softfp -marm" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j16
make install
echo -e "\033[32m build successful \033[0m"
}
function merge
{
echo -e "\033[32m package start \033[0m"
# 打包
$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 \
libavfilter/libavfilter.a \
libavformat/libavformat.a \
libavutil/libavutil.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.x/libgcc.a
# strip 精簡文件
$TOOLCHAIN/bin/arm-linux-androideabi-strip $PREFIX/libffmpeg.so
echo -e "\033[32m package successful \033[0m"
}
build_android
merge
編譯配置詳解答
設置編譯針對的系統
–target-os=android \
編譯後文件的輸出目錄
–prefix=$PREFIX \
–enable-cross-compile \
編譯動態庫,shared和static的開關是相對的。
–enable-static
–disable-shared \
生成文檔,以及相關的功能模塊
–disable-doc \
禁止編譯可執行文件
–disable-programs
–disable-ffmpeg
–disable-ffplay
–disable-ffprobe
–disable-avdevice
–disable-doc
–disable-symver \
設置交叉編譯器,按照實際路徑修改就可以了。
–cross-prefix=KaTeX parse error: Undefined control sequence: \
at position 38: …x-androideabi- \̲
̲ 設置編譯器
--cc=TOOLCHAIN/bin/arm-linux-androideabi-gcc
–nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
設置編譯so庫的架構,當前設置爲arm,可以根據實際需求修改
–arch=arm \
設置編譯針對的平臺,可以根據實際需求進行設置,當前設置爲最低支持android-21版本,arm架構。
–sysroot=KaTeX parse error: Undefined control sequence: \
at position 9: SYSROOT \̲
̲--extra-cflags=…ASM -isysroot $ISYSROOT -D__ANDROID_API__=21 -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -Wno-deprecated -mfloat-abi=softfp -marm" \
–extra-ldflags="$ADDI_LDFLAGS" \
啓動編譯
打開 命令終端,cd 到ffmpeg-4.2.3目錄,執行 build_gcc_arm.sh,然後喝杯咖啡等待運行結果。
使用 CLANG 編譯FFmpeg
下載NDK最新版本
編譯腳本
打開ffmpeg-4.2.3文件夾,創建腳本文件build_clang_arm.sh,編輯腳本內容
CPU=armv7-a
API=21
ARCH=arm
NDK=/Users/liuhongshuo/AnroidPro/ffmpeg/android-ndk-r20
SYSROOT=$NDK/platforms/android-$API/arch-arm
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/arm-linux-androideabi
# 要保存動態庫的目錄,這裏保存在源碼根目錄下的android/armv7-a
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
$ADDITIONAL_CONFIGURE_FLAG
function build_android
{
echo -e "\033[32m build start \033[0m"
./configure \
--target-os=android \
--prefix=$PREFIX \
--arch=$ARCH \
--cpu=$CPU \
--enable-cross-compile \
--enable-static \
--disable-shared \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--sysroot=$SYSROOT \
--extra-cflags="-I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=$API -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -Wno-deprecated -mfloat-abi=softfp -marm" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j16
make install
echo -e "\033[32m build successful \033[0m"
}
function merge
{
echo -e "\033[32m package start \033[0m"
# 打包
$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 \
libavfilter/libavfilter.a \
libavformat/libavformat.a \
libavutil/libavutil.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.x/libgcc.a
# strip 精簡文件
$TOOLCHAIN/bin/arm-linux-androideabi-strip $PREFIX/libffmpeg.so
echo -e "\033[32m package successful \033[0m"
}
build_android
merge
啓動編譯
打開 命令終端,cd 到ffmpeg-4.2.3目錄,執行 build_clang_arm.sh。