iOS FFmpeg 编译静态库

1,209 阅读4分钟

由于项目需要使用到FFmpeg,在自己摸索后,将FFmpeg编译成iOS可使用静态库,下面是流程及错误处理,写给自己,也写个遇到同样问题的你们。

在目前的网络共享环境下,可以在github上找到很多脚本,帮助你一键编译,推荐两个好用的脚本地址:

专门为iOS写的FFmpeg编译脚本,非常好用

iOS 专用FFmpeg 编译脚本

支持多个平台FFmpeg编译脚本:

多平台FFmpeg 编译脚本

由于我目前仅需要编译iOS的静态库,所以选用第一个,先下载下来脚本 然后在使用终端:cd 到脚本目录下执行:./build-ffmpeg.sh 然后等待就可以了,这个脚本默认是使用FFmpeg中的默认配置,如果需要其他功能,可自己在CONFIGURE_FLAGS中添加,编译成功后,就可以看到想要的FFmpeg库在FFmpeg-iOS目录下了,是不是很简单。

如果有需要使用到x264的小伙伴,则需要先提前编译好x264的库,然后放到脚本同级目录下,记住要按照脚本的路径名称(fat-x264)命名文件哦

下面是x264下载地址和编译脚本

访问地址

git地址

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