FFmpeg在編譯成ios庫并集成到項目中

想學習FFmpeg 庫,可是工欲善其事必先利其器,因此,這里先從基礎做起,編譯FFmpeg,并集成到ios項目中.

這里從github上找地址(https://github.com/kewlbear/FFmpeg-iOS-build-script) 我測試的環(huán)境是xcode10.1 ffmpeg的版本是4.1 .親自測試好用

該腳本依賴

  • gas-preprocessor
  • yasm

gas-preprocessor 安裝 可網上查詢
yasm安裝
brew install yams

下載腳本.進入該腳本文件夾
運行命令

./build-ffmpeg.sh
經過一段時間 編譯結束.
當前文件夾的文件有


ffmpeg結果文件夾

到這里很順利編譯結束.

集成新工程

創(chuàng)建新工程


新工程
添加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

循環(huán)生成所需要的結構體.這中間的內容就是生成結構體

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/%/} 臨時路徑 這里其實就是執(zhí)行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.首先創(chuàng)建文件夾FFmpeg-iOS/lib
2 設置參數
3.進入 目錄thin/x86_64/lib

  1. 依次尋找該目錄下的.a 文件

1.跳轉到 根目錄

  1. 打印lipo 需要執(zhí)行的命令
    3.lipo 命令執(zhí)行.(從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 目標系統(tǒng)
--sysroot 交叉編譯樹的根 libc
--sysinclude 交叉編譯頭文件
--target-exec 目標系統(tǒng)上的運行命令
--target-path 目標系統(tǒng)上的模擬構建路徑

3 性能參數
以下參數使用--enable-foo啟用或使用--disable-foo禁用時使用--e/d-代替班缰。

參數 功能 注釋
--e/d-debug 是否調試 enable時可指定level
--e/d-optimizations 編譯器優(yōu)化
--samples 制定測試示例位置
--e/d-stripping 是否剝離可執(zhí)行程序與共享庫
--e/d-asm 匯編優(yōu)化
--e/d-yasm 是否使用yasm匯編器

其他的可更改優(yōu)化方案: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 靜態(tài)庫構建 默認: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閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姐浮,死亡現場離奇詭異,居然都是意外死亡葬馋,警方通過查閱死者的電腦和手機卖鲤,發(fā)現死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畴嘶,“玉大人蛋逾,你說我怎么就攤上這事〈懊酰” “怎么了区匣?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蒋院。 經常有香客問我亏钩,道長莲绰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任姑丑,我火速辦了婚禮蛤签,結果婚禮上,老公的妹妹穿的比我還像新娘栅哀。我一直安慰自己震肮,他們只是感情好,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布昌屉。 她就那樣靜靜地躺著钙蒙,像睡著了一般茵瀑。 火紅的嫁衣襯著肌膚如雪间驮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天马昨,我揣著相機與錄音竞帽,去河邊找鬼。 笑死鸿捧,一個胖子當著我的面吹牛屹篓,可吹牛的內容都是我干的。 我是一名探鬼主播匙奴,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼堆巧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泼菌?” 一聲冷哼從身側響起谍肤,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哗伯,沒想到半個月后荒揣,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡焊刹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年系任,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虐块。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡俩滥,死狀恐怖,靈堂內的尸體忽然破棺而出贺奠,到底是詐尸還是另有隱情举农,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布敞嗡,位于F島的核電站颁糟,受9級特大地震影響航背,放射性物質發(fā)生泄漏。R本人自食惡果不足惜棱貌,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一玖媚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧婚脱,春花似錦今魔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至篮洁,卻和暖如春涩维,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背袁波。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工瓦阐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人篷牌。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓睡蟋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枷颊。 傳聞我的和親對象是個殘疾皇子戳杀,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內容