FFmpeg在编译成ios库并集成到项目中

想学习FFmpeg 库,可是工欲善其事必先利其器,因此,这里先从基础做起,编译FFmpeg,并集成到ios项目中.

这里从github上找地址(https://github.com/kewlbear/FFmpeg-iOS-build-script) 我测试的环境是xcode10.1 ffmpeg的版本是4.1 .亲自测试好用

该脚本依赖

  • gas-preprocessor
  • yasm

gas-preprocessor 安装 可网上查询
yasm安装
brew install yams

下载脚本.进入该脚本文件夹
运行命令

./build-ffmpeg.sh
经过一段时间 编译结束.
当前文件夹的文件有


ffmpeg结果文件夹

到这里很顺利编译结束.

集成新工程

创建新工程


新工程
添加ffmpeg库
修改搜索头文件

这里需要注意 要是我们路径 $(PROJECT_DIR)/TestFFmpeg/include 模式是 non-recursive. 那么我们引用头文件的格式是#import "libavformat/avformat.h"

添加六个依赖库

脚本解释

#!/bin/sh

# directories
FF_VERSION="4.1"
#FF_VERSION="snapshot-git"
if [[ $FFMPEG_VERSION != "" ]]; then
  FF_VERSION=$FFMPEG_VERSION
fi
SOURCE="ffmpeg-$FF_VERSION"
FAT="FFmpeg-iOS"

SCRATCH="scratch"
# must be an absolute path
THIN=`pwd`/"thin"

# absolute path to x264 library
#X264=`pwd`/fat-x264

#FDK_AAC=`pwd`/../fdk-aac-build-script-for-iOS/fdk-aac-ios

CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \
                 --disable-doc --enable-pic"

if [ "$X264" ]
then
    CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-libx264"
fi

if [ "$FDK_AAC" ]
then
    CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-libfdk-aac --enable-nonfree"
fi

# avresample
#CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-avresample"

ARCHS="arm64 armv7 x86_64 i386"

COMPILE="y"
LIPO="y"

DEPLOYMENT_TARGET="8.0"

if [ "$*" ]
then
    if [ "$*" = "lipo" ]
    then
        # skip compile
        COMPILE=
    else
        ARCHS="$*"
        if [ $# -eq 1 ]
        then
            # skip lipo
            LIPO=
        fi
    fi
fi

if [ "$COMPILE" ]
then
    if [ ! `which yasm` ]
    then
        echo 'Yasm not found'
        if [ ! `which brew` ]
        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` ]
    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 ]
    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" ]
        then
            PLATFORM="iPhoneSimulator"
            CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET"
        else
            PLATFORM="iPhoneOS"
            CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode"
            if [ "$ARCH" = "arm64" ]
            then
                EXPORT="GASPP_FIX_XCODE5=1"
            fi
        fi

        XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
        CC="xcrun -sdk $XCRUN_SDK clang"

        # force "configure" to use "gas-preprocessor.pl" (FFmpeg 3.3)
        if [ "$ARCH" = "arm64" ]
        then
            AS="gas-preprocessor.pl -arch aarch64 -- $CC"
        else
            AS="gas-preprocessor.pl -- $CC"
        fi

        CXXFLAGS="$CFLAGS"
        LDFLAGS="$CFLAGS"
        if [ "$X264" ]
        then
            CFLAGS="$CFLAGS -I$X264/include"
            LDFLAGS="$LDFLAGS -L$X264/lib"
        fi
        if [ "$FDK_AAC" ]
        then
            CFLAGS="$CFLAGS -I$FDK_AAC/include"
            LDFLAGS="$LDFLAGS -L$FDK_AAC/lib"
        fi

        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

        make -j3 install $EXPORT || 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
        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

以上是完整脚本摘录,下面依次解释.

FF_VERSION="4.1"

这个是ffmpeg的realease的版本可以从github地址中查看


image.png
if [[ $FFMPEG_VERSION != "" ]]; then
  FF_VERSION=$FFMPEG_VERSION
fi

判断是否配置了变量FFMPEG_VERSION,配置就赋值给变量FF_VERSION

SOURCE="ffmpeg-$FF_VERSION"
FAT="FFmpeg-iOS"

声明两个变量

SOURCE 源码指向的tag
FAT 代表的最后输出的fat文件所在的文件夹名字

SCRATCH="scratch"
THIN=`pwd`/"thin"

也是两个路径

#X264=`pwd`/fat-x264

#FDK_AAC=`pwd`/../fdk-aac-build-script-for-iOS/fdk-aac-ios

CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \
                 --disable-doc --enable-pic"

if [ "$X264" ]
then
    CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-libx264"
fi

if [ "$FDK_AAC" ]
then
    CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-libfdk-aac --enable-nonfree"
fi

这里的x264 和FDK_AAC 两个变量默认是注释掉的.如果需要库x264 和aac音频.这里需要打开

# avresample
#CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-avresample"

要是需要配置avresample 可以打开该选项

ARCHS="arm64 armv7 x86_64 i386"

编译的结构体

COMPILE="y"
LIPO="y"
DEPLOYMENT_TARGET="8.0"

COMPILE 代表编译
LIPO 代表合并
y 应该是获取yes的首字母,方便记忆吧
DEPLOYMENT_TARGET 编译库的最低版本

if [ "$*" ]
then
    if [ "$*" = "lipo" ]
    then
        # skip compile
        COMPILE=
    else
        ARCHS="$*"
        if [ $# -eq 1 ]
        then
            # skip lipo
            LIPO=
        fi
    fi
fi

脚本名称叫test.sh 入参三个: 1 2 3
运行test.sh 1 2 3后
$为"1 2 3"(一起被引号包住)
$@为"1" "2" "3"(分别被包住)
$#为3(参数数量)
这里因为我们没有传入参数因此,这里$
是空.不会跳入该函数中
传入参数lipo,那么就不需要进行编译
其他的参数就是arch了,要是参数是一个,就不需要lipo命令 了

if [ "$COMPILE" ]
then
  ....
fi

这段是判断是否需要编译

if [ ! `which yasm` ]
    then
        echo 'Yasm not found'
        if [ ! `which brew` ]
        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

依赖yasm ,要是没有安装yasm,那么安装yasm.而yasm依赖brew,没有brew,那么安装brew命令

if [ ! `which gas-preprocessor.pl` ]
    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

同理加载gas-preprocessor.pl 命令

if [ ! -r $SOURCE ]
    then
        echo 'FFmpeg source not found. Trying to download...'
        curl http://www.ffmpeg.org/releases/$SOURCE.tar.bz2 | tar xj \
            || exit 1
    fi

判断是否有源码,没有那么就需要去github下载源码.

-r 是读取当前目录文件
! 取反
tar xj 就是解压文件

CWD=`pwd`

代表当前路径

for ARCH in $ARCHS
    do
.....
done

循环生成所需要的结构体.这中间的内容就是生成结构体

echo "building $ARCH..."
        mkdir -p "$SCRATCH/$ARCH"
        cd "$SCRATCH/$ARCH"
  • 打印当前build的结构体
  • 生成文件夹,路径是$SCRATCH/$ARCH 其实就是scratch/arm64等
  • 进入该路径
    CFLAGS="-arch $ARCH"

编译参数,选择生成的结构体类型

        if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
        then
            PLATFORM="iPhoneSimulator"
            CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET"
        else
            PLATFORM="iPhoneOS"
            CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode"
            if [ "$ARCH" = "arm64" ]
            then
                EXPORT="GASPP_FIX_XCODE5=1"
            fi
        fi

这里是根据结构体类型选择PLATFORM 和 编译参数

i386 和x86_64 是模拟器结构体
arm64 armv7 是真机结构体
-fembed-bitcode bitcode指令

        XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
        CC="xcrun -sdk $XCRUN_SDK clang"

XCRUN_SDK 是编译所需的sdk连接地址 结果是iphonesimulator 和 iphoneos
CC 参数是编译命令

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

声明一个变量AS

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

两个变量

if [ "$X264" ]
        then
            CFLAGS="$CFLAGS -I$X264/include"
            LDFLAGS="$LDFLAGS -L$X264/lib"
        fi
        if [ "$FDK_AAC" ]
        then
            CFLAGS="$CFLAGS -I$FDK_AAC/include"
            LDFLAGS="$LDFLAGS -L$FDK_AAC/lib"
        fi

是否需要变量这两个库

到目前为止.

CC = "xcrun -sdk iphonesimulator clang"
AS = "gas-preprocessor.pl -- $CC"
CXXFLAGS = -arch x86_64 -mios-simulator-version-min=8.0
CFLAGS = -arch x86_64 -mios-simulator-version-min=8.0
LDFLAGS = -arch x86_64 -mios-simulator-version-min=8.0
TMPDIR = /var/folders/xz/ndlv58rj50q3v260h8lnyngh0000gn/T/
CONFIGURE_FLAGS = --enable-cross-compile --disable-debug --disable-programs --disable-doc --enable-pic

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

${TMPDIR/%/} 临时路径 这里其实就是执行ffmpeg的 configure命令

这里我们看看configure的最终结果是啥
configure --target-os=darwin --arch=x86_64 --cc=xcrun -sdk iphonesimulator clang --as=gas-preprocessor.pl -- $CC --enable-cross-compile --disable-debug --disable-programs --disable-doc --enable-pic --extra-cflags= -arch x86_64 -mios-simulator-version-min=8.0 --extra-ldflags= -arch x86_64 -mios-simulator-version-min=8.0 --prefix=./thin/x86_64

make -j3 install $EXPORT || exit 1

安装
cd $CWD
退出到根目录

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
        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

这里就是lipo命令的简单使用

1.首先创建文件夹FFmpeg-iOS/lib
2 设置参数
3.进入 目录thin/x86_64/lib

  1. 依次寻找该目录下的.a 文件

1.跳转到 根目录

  1. 打印lipo 需要执行的命令
    3.lipo 命令执行.(从thin文件夹中找 .a文件,输出到FFmpeg-iOS/lib/中,命名查找的.a文件)
    5.进入根目录
    6.将thin/x86_64/include 的文件拷贝到FFmpeg-iOS/lib/include

编译参数选择

1 生成参数

参数 功能 注释
--arch 编译架构
--help 打印帮助信息
-prefix 安装路径 Linux默认为/usr/local
--libdir 库安装路径 默认PREFIX/lib
--shlibdir 共享库安装路径 默认PREFIX/lib
--incdir 头文件安装路径 默认PREFIX/include/ffmpeg
--mandir 指定man page路径 默认PREFIX/man
--cc 指定编译器 默认gcc
--make 指定何种make
--source-path 源码路径
--pkg-config 指定pkg-config 默认pkg-config
--pkg-config-flags 指定pkg-config参数 默认--static
--extra-cflags 添加额外的CFLAG ECFLAGS
--extra-ldflags 添加额外的LDFLAG ELDFLAGS
--extra-libs 添加额外的LIB ELIBS
--cpu 指定最小的CPU版本
--nm 指定NM工具
--ar 指定AR工具
--as 指定汇编工具
--ld 指定LD链接器

2 交叉参数

参数 功能 注释
-cross-prefix 指定编译工具 交叉编译
--cross-compile 假定使用交叉编译
--target-os 目标系统
--sysroot 交叉编译树的根 libc
--sysinclude 交叉编译头文件
--target-exec 目标系统上的运行命令
--target-path 目标系统上的模拟构建路径

3 性能参数
以下参数使用--enable-foo启用或使用--disable-foo禁用时使用--e/d-代替。

参数 功能 注释
--e/d-debug 是否调试 enable时可指定level
--e/d-optimizations 编译器优化
--samples 制定测试示例位置
--e/d-stripping 是否剥离可执行程序与共享库
--e/d-asm 汇编优化
--e/d-yasm 是否使用yasm汇编器

其他的可更改优化方案:AltiVec、3DNow! 、MMX、MMX2、SSE、SSE3、armv5te、armv6、armv6t2、ARM VFP、iwmmxt、MMI、neon、VIS

4 功能选项
使用--enable-foo启用或使用--disable-foo禁用需要的功能插件,使用--e/d-代替。某些部件(如decoder)enable时需要明确指明,例:--enable-decoder=libdavs2。

参数 功能 注释
--e/d-static 静态库构建 默认:no
--e/d-shared 共享库构建 默认:no
--e/d-pic 代码非位置依赖 默认:no
--e/d-gpl GPL代码使用
--e/d-nonfree 非免费得代码使用 默认:no
--e/d-doc 文档构造 默认:yes
--e/d-pthreads pthreads 默认:yes
--disable-decoder 禁用所有解码器 同理其他
--enable-decoder=DEC 打开某个解码器 同理其他
--enable-libdavs2 启用avs2解码器 同理其他

注:打开与启用非等同
其他默认开启但可以关闭的部分:ffmpeg、ffprobe、ffplay、ffserver、avdevice、avcodec、avcore、avformat、swscale、特定部件(如某个编解码器等)
可选择禁用的编码:AAN DCT、DCT、Golomb、FFT、Golomb、LPC、MDCT、RDFT、VAAPI、VDPAU、DXVA2

查看./configure 的参数,我们可以通过 ./configure --help 查看

参数编译
ffmpeg-github
kxmovie
官方文档
脚本地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容