为Android编译FFMpeg
2017-09-22 本文已影响199人
思落羽
- 新建:build_android.sh
#!/bin/bash
# NDK途径
export NDK=/Users/lucius/Library/Android/sdk/ndk-bundle
# NDK东西链
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
# 编译平台
export PLATFORM=$NDK/platforms/android-14/arch-arm
# 编译功效输入途径
export PREFIX=/Users/lucius/development/workspaces/target/ffmpeg/optimized
# 设置编译功效运转平台
CPU=arm
ARCH=arm # -marm -mthumb gcc编译器参数
# marm功能优于mthumb百分之10到15,mthumb兼容性更好,可以调试用marm,发版用mthumb ADDI_CFLAGS="-marm"
# 开端编译设置
./configure /
# 设置输入途径
--prefix=$PREFIX /
# 设置编纂功效目的运转零碎
--target-os=android /
# 设置编译效果cpu架构
--arch=$ARCH /
# 设置编译效果运转平台
--sysroot=$PLATFORM /
# 交织编译东西链
--cross-prefix=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi- /
# gcc编译参数
--extra-ldflags="$ADDI_LDFLAGS" /
# 从编译参数
--extra-cflags="-Os -fpic $ADDI_CFLAGS" /
# 紧缩编译 --enable-small /
# 运用GPL,!!!GPL!!!
--enable-gpl /
# 多线程编解码
--enable-pthreads /
# 禁用文档 --disable-doc /
# 禁用ffmpeg下令,android会有本身的出口
--disable-ffmpeg /
# 禁用ffplay下令,android不须要
--disable-ffplay /
# 禁用ffprobe下令,android不须要
--disable-ffprobe /
# 禁用ffserver下令,android不须要
--disable-ffserver /
# 禁用network,android不须要 -
-disable-network /
# 禁用ffplay下令,android不须要
--disable-shared /
# 禁用一切编解码器,今后再按照需求增加编解码器
--disable-encoders /
--disable-decoders /
#编解码传输和谈
--enable-protocols /
# 滤镜处置
--enable-filters /
# 开启mp4音视频相干的编解码器
--enable-decoder=mpeg4 /
--enable-decoder=h264 /
--enable-decoder=mp3 /
--enable-decoder=aac /
--enable-encoder=mpeg4 /
--enable-encoder=libx264 /
--enable-encoder=aac /
# 未知选项
$ADDITIONAL_CONFIGURE_FLAG
# 清空前次编纂
make clean
# 开端四核编译 -j2暗示双核
make -j4
# 输入编译效果到指定目次
make install
# 以下脚本暗示将分离的so库合并成一个libffmpeg.so,详细指令寄义待研究
$PREBUILT/darwin-x86_64/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 /
libavformat/libavformat.a /
libavutil/libavutil.a /
libavfilter/libavfilter.a /
libavdevice/libavdevice.a /
libpostproc/libpostproc.a /
libswresample/libswresample.a /
libswscale/libswscale.a /
-lc
-lm
-lz
-ldl
-llog
--dynamic-linker=/system/bin/linker /
$PREBUILT/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-strip
$PREFIX/libffmpeg.so
- 需要修改下 ffmpeg/configure,使导出的so库文件名称符合NDK的规范
将
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)'
-
编译所有的平台:
ffmpeg + x264编译脚本 -
附:编译fdk-aac脚本:
#!/bin/sh
#!/bin/sh
CPU=armeabi-v7a
PREFIX=$(pwd)/output/$CPU
NDK_HOME=/Users/eraise/Library/Android/ndk
ANDROID_API=android-23
SYSROOT=$NDK_HOME/platforms/$ANDROID_API/arch-arm
ANDROID_BIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/
CROSS_COMPILE=${ANDROID_BIN}arm-linux-androideabi-
ARM_INC=$SYSROOT/usr/include
ARM_LIB=$SYSROOT/usr/lib
LDFLAGS=" -nostdlib -Bdynamic -Wl,--whole-archive -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$NDK_HOME/sources/cxx-stl/gnu-libstdc++/4.9/libs/$CPU -L$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/arm-linux-androideabi/lib -L$ARM_LIB -lc -lgcc -lm -ldl "
FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared"
export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"
export LDFLAGS="$LDFLAGS"
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
./configure $FLAGS \
--prefix=$PREFIX
make clean
make -j4
make install
需要注意,脚本中的./configure 如果分行写,"\"右边不能再有空格,否则报configure: error: /bin/sh build/config.sub failed
- 错误:
error: undefined reference to 'av_register_all()'
error: undefined reference to 'avcodec_register_all()'
error: undefined reference to 'avformat_network_init()'
解决方案是把 ffmpeg 的头文件用extern "C" 包起来
(方案来源:贝壳博客):
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>