视频编码学习之路FFmpegiOS-FFmpeg音视频开发

FFmpeg iOS 编译笔记

2018-11-27  本文已影响11人  团不慌

在经历了Linux、Windows、Android之后,终于迎来了MacOS下的编译体验。由于笔者并没有Mac下和XCode的开发经验,本篇笔记主要为使用他人脚本的编译过程。【原脚本仓库地址


环境配置

VMware 12 Pro
MacOS 10.13
XCode 10(不支持libstdc++,暂时不影响)
FFmpeg 4.0.3


编译

使用方式:

  1. 默认编译-全平台:
$ ./build-ffmpeg.sh
  1. 选择编译-指定平台:
$ ./build-ffmpeg.sh armv7 x86_64
  1. 跳过编译-只打包:
$ ./build-ffmpeg.sh lipo

检测

  1. 查看库支持的平台(libavcodec.a为例)
$ lipo -info libavcodec.a
  1. 查看是否支持bitcodelibavcodec.a为例)结果非0则支持bitcode
$ otool -arch armv7 -l xxxx.a | grep __bitcode | wc -l

脚本注释版(有修改)

#!/bin/sh

# 目标FFmpeg版本
FF_VERSION="4.0.3"
# 使用最新版本
#FF_VERSION="snapshot-git"
if [[ $FFMPEG_VERSION != "" ]]; then
  FF_VERSION=$FFMPEG_VERSION
fi
# 待编译源码,命名方式 ffmpeg-版本号
SOURCE="ffmpeg-$FF_VERSION"
# 输出FAT文件的路径
# 按成各个平台分别编译成库,最终合成一个FAT库
FAT="FFmpeg-iOS"

# 各平台的精简代码
# 存储编译过程中的一些文件,如在configure过程出现的问题将被记录于此
# configure日志路径: scratch/$ARCH/ffbuild/config.log
SCRATCH="scratch"

# 各平台编译输出,必须是绝对路径
THIN=`pwd`/"thin"

# 如需单独链接外部库赖,引入方式
#XXXLIB=/absolute/path/to/the/fat-path

# FFmpeg Configure 参数
CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \
                 --disable-doc --enable-pic"

# 需要支持的目标平台(未设置参数时的默认开启范围)
ARCHS="arm64 armv7 x86_64 i386"

# 是否进行编译
COMPILE="y"
# 是否合并成FAT
LIPO="y"

DEPLOYMENT_TARGET="8.0"

# 处理输入参数
if [ "$*" ]
then
    if [ "$*" = "lipo" ]
    then
        # skip compile
        COMPILE=
    else
        ARCHS="$*"
        if [ $# -eq 1 ]
        then
            # 只有一个平台的情况下不需要打包
            LIPO=
        fi
    fi
fi

# 备份变量
BASE_PKG_CONFIG_PATH=PKG_CONFIG_PATH

# 编译准备
if [ "$COMPILE" ]
then
    if [ ! `which yasm` ]        # 检查YASM
    then
        echo 'Yasm not found'
        if [ ! `which brew` ]        # 检查HomeBrew
        then
            echo 'Homebrew not found. Trying to install...'
                        ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" \
                || exit 1
        fi
        echo 'Trying to install Yasm...'
        brew install yasm || exit 1
    fi
    if [ ! `which gas-preprocessor.pl` ]    # 检查gas-preprocessor,一个Perl写的编译工具
    then
        echo 'gas-preprocessor.pl not found. Trying to install...'
        (curl -L https://github.com/libav/gas-preprocessor/raw/master/gas-preprocessor.pl \
            -o /usr/local/bin/gas-preprocessor.pl \
            && chmod +x /usr/local/bin/gas-preprocessor.pl) \
            || exit 1
    fi

    if [ ! -r $SOURCE ]        # 检查ffmpeg-x.x源码是否存在,不存在则下载
    then
        echo 'FFmpeg source not found. Trying to download...'
        curl http://www.ffmpeg.org/releases/$SOURCE.tar.bz2 | tar xj \
            || exit 1
    fi

    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" ]        # x86_64/i386平台下编译虚拟机
        then
            PLATFORM="iPhoneSimulator"
            CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET"
        else                                                  # ARM平台下编译实体机
            PLATFORM="iPhoneOS"
            # -fembed-bitcode是编译bitcode的开关,看需求添加
            CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode"
            if [ "$ARCH" = "arm64" ]
            then
                EXPORT="GASPP_FIX_XCODE5=1"
            fi
        fi

        # 使用XCode SDK中对应ARCH的编译器
        XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
        CC="xcrun -sdk $XCRUN_SDK clang"

        #  强制使用gas-preprocessor.pl
        if [ "$ARCH" = "arm64" ]
        then
            AS="gas-preprocessor.pl -arch aarch64 -- $CC"
        else
            AS="gas-preprocessor.pl -- $CC"
        fi

        CXXFLAGS="$CFLAGS"
        LDFLAGS="$CFLAGS"

        # 添加外部库的头文件及库
        if [ "$XXXLIB" ]
        then
            CFLAGS="$CFLAGS -I$XXXLIB/include"
            LDFLAGS="$LDFLAGS -L$XXXLIB/lib"
        fi

        # 对于使用pkg-config配置的外部库可以使用以下方式(注意使用$ARCH)
        # XXXLIB_THIN=/absolute/path/to/the/lib-build-path/$ARCH/lib
        # export PKG_CONFIG_PATH=$BASE_PKG_CONFIG_PATH:$XXXLIB_THIN/pkgconfig

        # 进行编译,TMPDIR-临时文件路径
        TMPDIR=${TMPDIR/%\/} $CWD/$SOURCE/configure \
            --target-os=darwin \
            --arch=$ARCH \
            --cc="$CC" \
            --as="$AS" \
            $CONFIGURE_FLAGS \
            --extra-cflags="$CFLAGS" \
            --extra-ldflags="$LDFLAGS" \
            --prefix="$THIN/$ARCH" \
        || exit 1
        # 根据实际配置可以修改使用的线程数(如改为-j16)
        make -j3 install $EXPORT || exit 1
        cd $CWD
    done
fi

# 打包成FAT库
if [ "$LIPO" ]
then
    echo "building fat binaries..."
    mkdir -p $FAT/lib
    set - $ARCHS
    CWD=`pwd`
    # $1是在读取set - $ARCHS的值
    cd $THIN/$1/lib
    for LIB in *.a
    do
        cd $CWD
        echo lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB 1>&2
        lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB || exit 1
    done

    cd $CWD
    cp -rf $THIN/$1/include $FAT
fi

echo Done

对FFmpeg 3.4版本出现问题的记录

在编译FFmpeg 3.4时出现

No rule to make target `libavcodec/parsers.c`, needed by `ffbuild/.config`. Stop.

解决方法:
使用update for 3.4的版本(commit 92e0663e230ea0c21c3948aaededadd833ac1c3e),同时在非arm64环境下也使用gas-preprocessor.pl,顺利编译完成。

if [ "$ARCH" = "arm64" ]
then
    AS="gas-preprocessor.pl -arch aarch64 -- $CC"
else
    AS="gas-preprocessor.pl $CC"
fi
上一篇下一篇

猜你喜欢

热点阅读