由于项目需要使用到FFmpeg,在自己摸索后,将FFmpeg编译成iOS可使用静态库,下面是流程及错误处理,写给自己,也写个遇到同样问题的你们。
在目前的网络共享环境下,可以在github上找到很多脚本,帮助你一键编译,推荐两个好用的脚本地址:
专门为iOS写的FFmpeg编译脚本,非常好用
支持多个平台FFmpeg编译脚本:
由于我目前仅需要编译iOS的静态库,所以选用第一个,先下载下来脚本 然后在使用终端:cd 到脚本目录下执行:./build-ffmpeg.sh 然后等待就可以了,这个脚本默认是使用FFmpeg中的默认配置,如果需要其他功能,可自己在CONFIGURE_FLAGS中添加,编译成功后,就可以看到想要的FFmpeg库在FFmpeg-iOS目录下了,是不是很简单。
如果有需要使用到x264的小伙伴,则需要先提前编译好x264的库,然后放到脚本同级目录下,记住要按照脚本的路径名称(fat-x264)命名文件哦
下面是x264下载地址和编译脚本
git clone https://code.videolan.org/videolan/x264.git
脚本:
CONFIGURE_FLAGS="--enable-static --enable-pic --disable-cli --disable-shared"
# 指定架构平台
ARCHS="arm64 armv7"
#源码位置
SOURCE="x264-master"
FAT="x264-iOS"
SCRATCH="scratch-x264"
THIN=`pwd`/"thin-x264"
COMPILE="y"
LIPO="y"
if [ "$*" ]
then
if [ "$*" = "lipo" ]
then
COMPILE=
else
ARCHS="$*"
if [ $# -eq 1 ]
then
LIPO=
fi
fi
fi
if [ "$COMPILE" ]
then
CWD=`pwd`
for ARCH in $ARCHS
do
echo "building $ARCH..."
mkdir -p "$SCRATCH/$ARCH"
cd "$SCRATCH/$ARCH"
CFLAGS="-arch $ARCH"
ASFLAGS=
if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
then
PLATFORM="iPhoneSimulator"
CPU=
if [ "$ARCH" = "x86_64" ]
then
CFLAGS="$CFLAGS -mios-simulator-version-min=9.0"
HOST=
else
CFLAGS="$CFLAGS -mios-simulator-version-min=9.0"
HOST="--host=i386-apple-darwin"
fi
else
PLATFORM="iPhoneOS"
if [ $ARCH = "arm64" ]
then
HOST="--host=aarch64-apple-darwin"
XARCH="-arch aarch64"
else
HOST="--host=arm-apple-darwin"
XARCH="-arch arm"
fi
CFLAGS="$CFLAGS -fembed-bitcode -mios-version-min=9.0"
ASFLAGS="$CFLAGS"
fi
XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
CC="xcrun -sdk $XCRUN_SDK clang"
if [ $PLATFORM = "iPhoneOS" ]
then
export AS="$CWD/$SOURCE/tools/gas-preprocessor.pl $XARCH -- $CC"
else
export -n AS
fi
CXXFLAGS="$CFLAGS"
LDFLAGS="$CFLAGS"
CC=$CC $CWD/$SOURCE/configure \
$CONFIGURE_FLAGS \
$HOST \
--extra-cflags="$CFLAGS" \
--extra-asflags="$ASFLAGS" \
--extra-ldflags="$LDFLAGS" \
--prefix="$THIN/$ARCH" || exit 1
make -j8 install || exit 1
cd $CWD
done
fi
if [ "$LIPO" ]
then
echo "building fat binaries..."
mkdir -p $FAT/lib
set - $ARCHS
CWD=`pwd`
cd $THIN/$1/lib
for LIB in *.a
do
cd $CWD
lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB
done
cd $CWD
cp -rf $THIN/$1/include $FAT
fi
同样如果需要添加aac的小伙伴,使用用下面的的地址下载源码然后同级目录下执行脚本 : FDK-AAC下载地址
脚本:
CONFIGURE_FLAGS="--enable-static --with-pic=yes --disable-shared"
#指定编译平台
ARCHS="arm64 armv7"
# 源码位置
SOURCE="fdk-aac-2.0.2"
FAT="fdk-aac-ios"
SCRATCH="scratch"
# must be an absolute path
THIN=`pwd`/"thin"
COMPILE="y"
LIPO="y"
if [ "$*" ]
then
if [ "$*" = "lipo" ]
then
COMPILE=
else
ARCHS="$*"
if [ $# -eq 1 ]
then
# skip lipo
LIPO=
fi
fi
fi
if [ "$COMPILE" ]
then
CWD=`pwd`
for ARCH in $ARCHS
do
echo "building $ARCH..."
mkdir -p "$SCRATCH/$ARCH"
cd "$SCRATCH/$ARCH"
CFLAGS="-arch $ARCH"
if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
then
PLATFORM="iPhoneSimulator"
CPU=
if [ "$ARCH" = "x86_64" ]
then
CFLAGS="$CFLAGS -mios-simulator-version-min=7.0"
HOST="--host=x86_64-apple-darwin"
else
CFLAGS="$CFLAGS -mios-simulator-version-min=7.0"
HOST="--host=i386-apple-darwin"
fi
else
PLATFORM="iPhoneOS"
if [ $ARCH = arm64 ]
then
HOST="--host=aarch64-apple-darwin"
else
HOST="--host=arm-apple-darwin"
fi
CFLAGS="$CFLAGS -fembed-bitcode"
fi
XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
CC="xcrun -sdk $XCRUN_SDK clang -Wno-error=unused-command-line-argument-hard-error-in-future"
AS="$CWD/$SOURCE/extras/gas-preprocessor.pl $CC"
CXXFLAGS="$CFLAGS"
LDFLAGS="$CFLAGS"
$CWD/$SOURCE/configure \
$CONFIGURE_FLAGS \
$HOST \
$CPU \
CC="$CC" \
CXX="$CC" \
CPP="$CC -E" \
AS="$AS" \
CFLAGS="$CFLAGS" \
LDFLAGS="$LDFLAGS" \
CPPFLAGS="$CFLAGS" \
--prefix="$THIN/$ARCH" || exit 1
make -j8 install || exit 1
cd $CWD
done
fi
#合并各个架构平台的库文件
if [ "$LIPO" ]
then
echo "building fat binaries..."
mkdir -p $FAT/lib
set - $ARCHS
CWD=`pwd`
cd $THIN/$1/lib
for LIB in *.a
do
cd $CWD
lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB
done
cd $CWD
cp -rf $THIN/$1/include $FAT
fi
编译后将需要的库放到脚本同级下就行了,然后执行脚本就能得到相要的FFmpeg库了,记得要改成脚本上路径名称哦
最后,本文的重点来啦 不管是用第一个还是第二个脚本,在编译FFmpeg4.4.1版本都会报错,具体报错内容前段为
src/libavdevice/audiotoolbox.m:78:5: error: unknown type name 'AudioDeviceID'; did you mean 'AudioFileID'?\
AudioDeviceID *devices;
林林总总的大概二十几个错误,大概原因是由于支持音频硬解码时和系统本身的AudioToolBox框架冲突的,那么该怎么处理,改ffmpeg源码?做不到啊,目前给出两种方案
1、推荐使用4.3.1的FFmpeg框架进行编译 2、使用4.4.1的编译在CONFIGURE_FLAGS中添加--disable-audiotoolbox
这样在音频硬解码时可能存在问题,这个时候在音频硬解的时候,再使用原生AudioToolBox库手动的去解码了,目前暂无其他好办法
最后,将编译好的库导入到项目中去,可能还会报错
不要慌,这个错误可能是用于FFmpeg中枚举命名和系统的命名冲突了,在FFmpeg中找到对应的头文件,再自己修改命名就可以了
最后:自勉-“遇到问题不要慌,脑子是个好东西”
更新一个查看编译后的库支持的架构命令:
lipo -info xxx.framework/xxxxFramework