想學習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
經過一段時間 編譯結束.
當前文件夾的文件有
到這里很順利編譯結束.
集成新工程
創(chuàng)建新工程
這里需要注意 要是我們路徑 $(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地址中查看
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
- 依次尋找該目錄下的.a 文件
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 查看