最簡單的基於FFmpeg的移動端樣例:IOS HelloWorld
=====================================================
最簡單的基於FFmpeg的移動端樣例系列文章列表:
最簡單的基於FFmpeg的移動端樣例:Android HelloWorld
最簡單的基於FFmpeg的移動端樣例:Android 視頻解碼器
最簡單的基於FFmpeg的移動端樣例:Android 視頻解碼器-單個庫版
最簡單的基於FFmpeg的移動端樣例:Android 推流器
最簡單的基於FFmpeg的移動端樣例:Android 視頻轉碼器
最簡單的基於FFmpeg的移動端樣例附件:Android 自帶播放器
最簡單的基於FFmpeg的移動端樣例附件:SDL Android HelloWorld
最簡單的基於FFmpeg的移動端樣例:IOS HelloWorld
最簡單的基於FFmpeg的移動端樣例:IOS 視頻解碼器
最簡單的基於FFmpeg的移動端樣例:IOS 推流器
最簡單的基於FFmpeg的移動端樣例:IOS 視頻轉碼器
最簡單的基於FFmpeg的移動端樣例附件:IOS自帶播放器
最簡單的基於FFmpeg的移動端樣例:Windows Phone HelloWorld
=====================================================
本文記錄IOS平臺下基於FFmpeg的HelloWorld程序。該演示樣例C語言的源碼來自於《最簡單的基於FFMPEG的Helloworld程序》。
相關的概念就不再反復記錄了。
IOS程序使用FFmpeg類庫的說明
IOS應用程序使用FFmpeg類庫的流程例如以下所看到的。
1. 編譯FFmpeg類庫
編譯IOS的FFmpeg類庫須要支持5種架構:armv7、armv7s、arm64、i386、x86_64。當中前面3個是給真機使用的。後面2個是給模擬器使用的。本文記錄的FFmpeg類庫還支持第三方類庫libx264和libfaac。所以在編譯之前還要先編譯libx264和libfaac的源碼。
整體說來。IOS下的類庫須要編譯成兩個版本號:thin和fat。
每種架構相應一個thin版本號的類庫,將這些不同架構thin版本號的類庫合成起來之後。就形成了fat版本號的類庫。以下簡單記錄一下編譯步驟。編譯過程中IOS SDK版本號為8.3。FFmpeg版本號為2.7.1。faac和x264分別使用了最新版本號的源碼。
(1) 第三方庫libx264的編譯
這一步用於生成支持armv7、armv7s、arm64、i386、x86_64幾種架構的fat版本號的libx264.a。以下這個腳本能夠首先編譯生成上面5種架構的thin版本號的libx264.a,分成5個目錄存儲於thin-x264目錄中;然後將這些類庫合並成為1個fat版本號的libx264.a,存儲於fat-x264目錄中。
build_x264.sh#!/bin/sh # LXH,MXY # # directories SOURCE="x264" FAT="fat-x264" SCRATCH="scratch-x264" # must be an absolute path THIN=`pwd`/"thin-x264" #This is decided by your SDK version. SDK_VERSION="8.3" cd ./x264 #============== simulator =============== PLATFORM="iPhoneSimulator" #i386 ARCHS="i386" export DEVROOT=/Applications/Xcode.app/Contents/Developer/Platforms/${PLATFORM}.platform/Developer export SDKROOT=$DEVROOT/SDKs/${PLATFORM}${SDK_VERSION}.sdk export CC=$DEVROOT/usr/bin/gcc export LD=$DEVROOT/usr/bin/ld export CXX=$DEVROOT/usr/bin/g++ export LIBTOOL=$DEVROOT/usr/bin/libtool export HOST=i386-apple-darwin COMMONFLAGS="-pipe -gdwarf-2 -no-cpp-precomp -isysroot ${SDKROOT} -fPIC" export LDFLAGS="${COMMONFLAGS} -fPIC" export CFLAGS="${COMMONFLAGS} -fvisibility=hidden" for ARCH in $ARCHS; do echo "Building $ARCH ......" make clean ./configure --host=i386-apple-darwin --sysroot=$SDKROOT --prefix="$THIN/$ARCH" --extra-cflags="-arch $ARCH -miphoneos-version-min=6.0" --extra-ldflags="-L$SDKROOT/usr/lib/system -arch $ARCH -miphoneos-version-min=6.0" --enable-pic --enable-static --disable-asm make && make install && make clean echo "Installed: $DEST/$ARCH" done #x86_64 ARCHS="x86_64" unset DEVROOT unset SDKROOT unset CC unset LD unset CXX unset LIBTOOL unset HOST unset LDFLAGS unset CFLAGS make clean for ARCH in $ARCHS; do echo "Building $ARCH ......" ./configure --prefix="$THIN/$ARCH" --enable-pic --enable-static --disable-asm make && make install && make clean echo "Installed: $DEST/$ARCH" done #================ iphone ================== export PLATFORM="iPhoneOS" ARCHS="arm64 armv7 armv7s " export DEVROOT=/Applications/Xcode.app/Contents/Developer export SDKROOT=$DEVROOT/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK_VERSION}.sdk #DEVPATH=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDK_VERSION}.sdk export CC=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang export AS=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/as COMMONFLAGS="-pipe -gdwarf-2 -no-cpp-precomp -isysroot ${SDKROOT} -marm -fPIC" export LDFLAGS="${COMMONFLAGS} -fPIC" export CFLAGS="${COMMONFLAGS} -fvisibility=hidden" export CXXFLAGS="${COMMONFLAGS} -fvisibility=hidden -fvisibility-inlines-hidden" for ARCH in $ARCHS; do echo "Building $ARCH ......" ./configure --host=arm-apple-darwin --sysroot=$DEVPATH --prefix="$THIN/$ARCH" --extra-cflags="-arch $ARCH" --extra-ldflags="-L$DEVPATH/usr/lib/system -arch $ARCH" --enable-pic --enable-static --disable-asm make && make install && make clean echo "Installed: $DEST/$ARCH" done cd .. #================ fat lib =================== ARCHS="armv7 armv7s i386 x86_64 arm64" 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
(2) 第三方庫libfaac的編譯
這一步用於生成支持armv7、armv7s、arm64、i386、x86_64幾種架構的fat版本號的libfaac.a。以下這個腳本能夠首先編譯生成上面5種架構的thin版本號的libfaac.a,分成5個目錄存儲於fat-faac中;然後將這些類庫合並成為1個fat版本號的libfaac.a。存儲於fat-faac中。
build_faac.sh
#!/bin/sh cd ./faac make distclean cd .. CONFIGURE_FLAGS="--enable-static --with-pic" ARCHS="arm64 armv7s x86_64 i386 armv7" # directories SOURCE="faac" FAT="fat-faac" SCRATCH="scratch-faac" # must be an absolute path THIN=`pwd`/"thin-faac" COMPILE="y" LIPO="y" if [ "$*" ] then if [ "$*" = "lipo" ] then # skip compile 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" if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ] then PLATFORM="iPhoneSimulator" CPU= if [ "$ARCH" = "x86_64" ] then SIMULATOR="-mios-simulator-version-min=7.0" HOST= else SIMULATOR="-mios-simulator-version-min=5.0" HOST="--host=i386-apple-darwin" fi else PLATFORM="iPhoneOS" if [ $ARCH = "armv7s" ] then CPU="--cpu=swift" else CPU= fi SIMULATOR= HOST="--host=arm-apple-darwin" 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="/usr/local/bin/gas-preprocessor.pl $CC" CFLAGS="-arch $ARCH $SIMULATOR" CXXFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" CC=$CC CFLAGS=$CXXFLAGS LDFLAGS=$LDFLAGS CPPFLAGS=$CXXFLAGS CXX=$CC CXXFLAGS=$CXXFLAGS $CWD/$SOURCE/configure $CONFIGURE_FLAGS $HOST --prefix="$THIN/$ARCH" --disable-shared --without-mp4v2 make clean && make && make install-strip cd $CWD done fi #================ fat lib =================== 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
(3) 編譯armv7版本號FFmpeg類庫
這一步用於生成支持armv7架構的thin版本號的FFmpeg類庫,存儲於thin-ffmpeg/armv7目錄中。腳本例如以下所看到的。
build_ffmpeg_demo_armv7.sh#!/bin/sh # LXH,MXY modified cd ffmpeg PLATFORM="iPhoneOS" INSTALL="thin-ffmpeg" SDK_VERSION="8.3" # libx264 export X264ROOT=../thin-x264/armv7 export X264LIB=$X264ROOT/lib export X264INCLUDE=$X264ROOT/include # libfaac export FAACROOT=../thin-faac/armv7 export FAACLIB=$FAACROOT/lib export FAACINCLUDE=$FAACROOT/include export DEVROOT=/Applications/Xcode.app/Contents/Developer export SDKROOT=$DEVROOT/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK_VERSION}.sdk export CC=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang export AS=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/as COMMONFLAGS="-pipe -gdwarf-2 -no-cpp-precomp -isysroot ${SDKROOT} -marm -fPIC" export LDFLAGS="${COMMONFLAGS} -fPIC" export CFLAGS="${COMMONFLAGS} -fvisibility=hidden" export CXXFLAGS="${COMMONFLAGS} -fvisibility=hidden -fvisibility-inlines-hidden" echo "Building armv7..." make clean ./configure --cpu=cortex-a9 --extra-cflags=‘-I$X264INCLUDE -I$FAACINCLUDE -arch armv7 -miphoneos-version-min=5.0 -mthumb‘ --extra-ldflags=‘-L$X264LIB -L$FAACLIB -arch armv7 -miphoneos-version-min=5.0‘ --enable-cross-compile --arch=arm --disable-iconv --target-os=darwin --cc=${CC} --disable-asm --sysroot=${SDKROOT} --prefix=../${INSTALL}/armv7 --enable-gpl --enable-nonfree --enable-version3 --disable-bzlib --enable-small --disable-vda --disable-encoders --enable-libx264 --enable-libfaac --enable-encoder=libx264 --enable-encoder=libfaac --disable-muxers --enable-muxer=flv --enable-muxer=mov --enable-muxer=ipod --enable-muxer=mpegts --enable-muxer=psp --enable-muxer=mp4 --enable-muxer=avi --disable-decoders --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=h264 --enable-decoder=mpeg4 --disable-demuxers --enable-demuxer=flv --enable-demuxer=h264 --enable-demuxer=mpegts --enable-demuxer=avi --enable-demuxer=mpc --enable-demuxer=mov --disable-parsers --enable-parser=aac --enable-parser=ac3 --enable-parser=h264 --disable-protocols --enable-protocol=file --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=udp --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --disable-devices --disable-debug --disable-ffmpeg --disable-ffprobe --disable-ffplay --disable-ffserver --disable-debug make make install cd ..
(4) 編譯armv7s版本號FFmpeg類庫
這一步用於生成支持armv7s架構的thin版本號的FFmpeg類庫,存儲於thin-ffmpeg/armv7s目錄中。腳本例如以下所看到的。
build_ffmpeg_demo_armv7s.sh#!/bin/sh # LXH,MXY modified cd ffmpeg PLATFORM="iPhoneOS" INSTALL="thin-ffmpeg" SDK_VERSION="8.3" # libx264 export X264ROOT=../thin-x264/armv7s export X264LIB=$X264ROOT/lib export X264INCLUDE=$X264ROOT/include # libfaac export FAACROOT=../thin-faac/armv7s export FAACLIB=$FAACROOT/lib export FAACINCLUDE=$FAACROOT/include export DEVROOT=/Applications/Xcode.app/Contents/Developer export SDKROOT=$DEVROOT/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK_VERSION}.sdk export CC=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang export AS=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/as COMMONFLAGS="-pipe -gdwarf-2 -no-cpp-precomp -isysroot ${SDKROOT} -marm -fPIC" export LDFLAGS="${COMMONFLAGS} -fPIC" export CFLAGS="${COMMONFLAGS} -fvisibility=hidden" export CXXFLAGS="${COMMONFLAGS} -fvisibility=hidden -fvisibility-inlines-hidden" echo "Building armv7s..." make clean ./configure --cpu=cortex-a9 --extra-cflags=‘-I$X264INCLUDE -I$FAACINCLUDE -arch armv7s -miphoneos-version-min=5.0 -mthumb‘ --extra-ldflags=‘-L$X264LIB -L$FAACLIB -arch armv7s -miphoneos-version-min=5.0‘ --enable-cross-compile --arch=arm --disable-iconv --target-os=darwin --cc=${CC} --disable-asm --sysroot=${SDKROOT} --prefix=../${INSTALL}/armv7s --enable-gpl --enable-nonfree --enable-version3 --disable-bzlib --enable-small --disable-vda --disable-encoders --enable-libx264 --enable-libfaac --enable-encoder=libx264 --enable-encoder=libfaac --disable-muxers --enable-muxer=flv --enable-muxer=mov --enable-muxer=ipod --enable-muxer=mpegts --enable-muxer=psp --enable-muxer=mp4 --enable-muxer=avi --disable-decoders --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=h264 --enable-decoder=mpeg4 --disable-demuxers --enable-demuxer=flv --enable-demuxer=h264 --enable-demuxer=avi --enable-demuxer=mpegts --enable-demuxer=mpc --enable-demuxer=mov --disable-parsers --enable-parser=aac --enable-parser=ac3 --enable-parser=h264 --disable-protocols --enable-protocol=file --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=udp --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --disable-devices --disable-debug --disable-ffmpeg --disable-ffprobe --disable-ffplay --disable-ffserver --disable-debug make make install cd ..
(5) 編譯arm64版本號FFmpeg類庫
這一步用於生成支持arm64架構的thin版本號的FFmpeg類庫,存儲於thin-ffmpeg/arm64目錄中。
腳本例如以下所看到的。
build_ffmpeg_demo_arm64.sh#!/bin/sh # LXH,MXY modified cd ffmpeg PLATFORM="iPhoneOS" INSTALL="thin-ffmpeg" SDK_VERSION="8.3" # libx264 export X264ROOT=../thin-x264/arm64 export X264LIB=$X264ROOT/lib export X264INCLUDE=$X264ROOT/include # libfaac export FAACROOT=../thin-faac/arm64 export FAACLIB=$FAACROOT/lib export FAACINCLUDE=$FAACROOT/include export DEVROOT=/Applications/Xcode.app/Contents/Developer export SDKROOT=$DEVROOT/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK_VERSION}.sdk export CC=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang export AS=$DEVROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/as COMMONFLAGS="-pipe -gdwarf-2 -no-cpp-precomp -isysroot ${SDKROOT} -marm -fPIC" export LDFLAGS="${COMMONFLAGS} -fPIC" export CFLAGS="${COMMONFLAGS} -fvisibility=hidden" export CXXFLAGS="${COMMONFLAGS} -fvisibility=hidden -fvisibility-inlines-hidden" echo "Building arm64..." make clean ./configure --extra-cflags=‘-I$X264INCLUDE -I$FAACINCLUDE -arch arm64 -miphoneos-version-min=5.0 -mthumb‘ --extra-ldflags=‘-L$X264LIB -L$FAACLIB -arch arm64 -miphoneos-version-min=5.0‘ --enable-cross-compile --arch=arm --disable-iconv --target-os=darwin --cc=${CC} --disable-asm --sysroot=${SDKROOT} --prefix=../${INSTALL}/arm64 --enable-gpl --enable-nonfree --enable-version3 --disable-bzlib --enable-small --disable-vda --disable-encoders --enable-libx264 --enable-libfaac --enable-encoder=libx264 --enable-encoder=libfaac --disable-muxers --enable-muxer=flv --enable-muxer=mov --enable-muxer=ipod --enable-muxer=mpegts --enable-muxer=psp --enable-muxer=mp4 --enable-muxer=avi --disable-decoders --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=h264 --enable-decoder=mpeg4 --disable-demuxers --enable-demuxer=flv --enable-demuxer=h264 --enable-demuxer=avi --enable-demuxer=mpegts --enable-demuxer=mpc --enable-demuxer=mov --disable-parsers --enable-parser=aac --enable-parser=ac3 --enable-parser=h264 --disable-protocols --enable-protocol=file --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=udp --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --disable-devices --disable-debug --disable-ffmpeg --disable-ffprobe --disable-ffplay --disable-ffserver --disable-debug make make install cd ..
(6) 編譯i386版本號FFmpeg類庫
這一步用於生成支持i386架構的thin版本號的FFmpeg類庫。存儲於thin-ffmpeg/i386目錄中。
腳本例如以下所看到的。
build_ffmpeg_demo_i386.sh#!/bin/sh # LXH,MXY modified cd ffmpeg PLATFORM="iPhoneSimulator" INSTALL="thin-ffmpeg" SDK_VERSION="8.3" # libx264 export X264ROOT=../thin-x264/i386 export X264LIB=$X264ROOT/lib export X264INCLUDE=$X264ROOT/include # libfaac export FAACROOT=../thin-faac/i386 export FAACLIB=$FAACROOT/lib export FAACINCLUDE=$FAACROOT/include export DEVROOT=/Applications/Xcode.app/Contents/Developer/Platforms/${PLATFORM}.platform/Developer export SDKROOT=$DEVROOT/SDKs/${PLATFORM}${SDK_VERSION}.sdk export CC=$DEVROOT/usr/bin/gcc export LD=$DEVROOT/usr/bin/ld export CXX=$DEVROOT/usr/bin/g++ export LIBTOOL=$DEVROOT/usr/bin/libtool COMMONFLAGS="-pipe -gdwarf-2 -no-cpp-precomp -isysroot ${SDKROOT} -fPIC" export LDFLAGS="${COMMONFLAGS} -fPIC" export CFLAGS="${COMMONFLAGS} -fvisibility=hidden" echo "Building i386..." make clean ./configure --cpu=i386 --extra-cflags=‘-I$X264INCLUDE -I$FAACINCLUDE -arch i386 -miphoneos-version-min=5.0‘ --extra-ldflags=‘-L$X264LIB -L$FAACLIB -arch i386 -miphoneos-version-min=5.0‘ --enable-cross-compile --arch=i386 --disable-iconv --target-os=darwin --cc=${CC} --sysroot=${SDKROOT} --prefix=../${INSTALL}/i386 --enable-gpl --enable-nonfree --enable-version3 --disable-bzlib --enable-small --disable-vda --disable-encoders --enable-libx264 --enable-libfaac --enable-encoder=libx264 --enable-encoder=libfaac --disable-muxers --enable-muxer=flv --enable-muxer=mov --enable-muxer=mpegts --enable-muxer=ipod --enable-muxer=psp --enable-muxer=mp4 --enable-muxer=avi --disable-decoders --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=h264 --enable-decoder=mpeg4 --disable-demuxers --enable-demuxer=flv --enable-demuxer=h264 --enable-demuxer=mpegts --enable-demuxer=avi --enable-demuxer=mpc --enable-demuxer=mov --disable-parsers --enable-parser=aac --enable-parser=ac3 --enable-parser=h264 --disable-protocols --enable-protocol=file --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=udp --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --disable-devices --disable-debug --disable-ffmpeg --disable-ffprobe --disable-ffplay --disable-ffserver --disable-debug make make install cd ..
(7) 編譯x86_64版本號FFmpeg類庫
這一步用於生成支持x86_64架構的thin版本號的FFmpeg類庫。存儲於thin-ffmpeg/x86_64目錄中。腳本例如以下所看到的。
build_ffmpeg_demo_x86_64.sh#!/bin/sh # LXH,MXY modified cd ./ffmpeg INSTALL="thin-ffmpeg" # libx264 export X264ROOT=../thin-x264/x86_64 export X264LIB=$X264ROOT/lib export X264INCLUDE=$X264ROOT/include # libfaac export FAACROOT=../thin-faac/x86_64 export FAACLIB=$FAACROOT/lib export FAACINCLUDE=$FAACROOT/include unset DEVROOT unset SDKROOT unset CC unset LD unset CXX unset LIBTOOL unset HOST unset LDFLAGS unset CFLAGS echo "Building x86_64..." make clean ./configure --extra-cflags=‘-I$X264INCLUDE -I$FAACINCLUDE‘ --extra-ldflags=‘-L$X264LIB -L$FAACLIB‘ --disable-iconv --disable-asm --prefix=../${INSTALL}/x86_64 --enable-gpl --enable-nonfree --enable-version3 --disable-bzlib --enable-small --disable-vda --disable-encoders --enable-libx264 --enable-libfaac --enable-encoder=libx264 --enable-encoder=mpeg2video --enable-encoder=libfaac --disable-muxers --enable-muxer=flv --enable-muxer=mov --enable-muxer=ipod --enable-muxer=mpegts --enable-muxer=psp --enable-muxer=mp4 --enable-muxer=avi --disable-decoders --enable-decoder=aac --enable-decoder=mpeg2video --enable-decoder=aac_latm --enable-decoder=h264 --enable-decoder=mpeg4 --disable-demuxers --enable-demuxer=flv --enable-demuxer=h264 --enable-demuxer=avi --enable-demuxer=mpegts --enable-demuxer=mpc --enable-demuxer=mov --disable-parsers --enable-parser=aac --enable-parser=ac3 --enable-parser=h264 --disable-protocols --enable-protocol=file --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=udp --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --disable-devices --disable-debug --disable-ffmpeg --disable-ffprobe --disable-ffplay --disable-ffserver --disable-debug make make install cd ..
(8) 打包類庫
這一步用於將上述步驟中生成的5個版本號的FFmpeg打包生成fat版本號的FFmpeg類庫。這一步驟執行完成後,將thin-ffmpeg中幾個thin版本號的類庫合並為一個fat版本號的類庫。並存儲於fat-ffmpeg目錄中。
腳本例如以下所看到的。
build_ffmpeg_fat.sh#!/bin/sh # directories THIN=`pwd`/"thin-ffmpeg" FAT=`pwd`/"fat-ffmpeg" CWD=`pwd` # must be an absolute path ARCHS="armv7s i386 armv7 arm64 x86_64" echo "building fat binaries..." mkdir -p $FAT/lib set - $ARCHS cd thin-ffmpeg/$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
生成完fat版本號的類庫後,能夠在命令行使用lipo命令查看類庫的架構,例如以下所看到的。
lipo -info libavcodec.a
2. 編寫IOS程序
編寫包括FFmpeg類庫支持的IOS程序分成兩步:配置Xcode環境,編寫C語言代碼。
(1) 配置Xcode環境
以下以Xcode的IOS中的Single View Application為例。記錄一下配置步驟:
(a) 拷貝頭文件所在的include目錄和fat版本號的FFmpeg類庫(包括libavformat.a, libavcodec.a, libavutil.a, libavdevice.a, libavfilter.a。 libpostproc.a。 libswresample.a, libswscale.a;以及第三方fat版本號類庫libx264.a, libfaac.a)至項目目錄。並將它們加入至項目中。
(b) 項目屬性->Build Settings中配置以下3個選項。
Linking->Other Linker Flags中加入以下內容:
-lavformat -lavcodec -lavutil -lavdevice -lavfilter -lpostproc -lswresample -lswscale -lx264 -lfaacSearch Paths->Header Search Paths加入以下內容
$(PROJECT_DIR)/includeSearch Paths->Library Search Paths加入以下內容
$(PROJECT_DIR)其他的一些配置。這些配置隨著FFmpeg版本號的不同而有稍微的不同(在某些情況下也可能不須要配置)。
我眼下使用的2.7.1版本號的FFmpeg須要配置以下的選項。
項目屬性->General->Linked Frameworks and Libraries中加入兩個類庫:AVFoundation.framework和libz.dylib。
(2) 編寫C語言代碼
做好上面配置後。就能夠在項目中編寫代碼測試一下FFmpeg是否正確配置了。因為IOS使用的Objective-C是兼容C語言的。所以能夠直接寫C語言代碼調用FFmpeg。能夠在ViewController.m中的viewDidLoad()函數中加入一行printf()代碼打印FFmpeg類庫的版本號信息。例如以下所看到的。
#import "ViewController.h" #include <libavcodec/avcodec.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. printf("%s",avcodec_configuration()); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
假設類庫編譯無誤。啟動IOS程序的時候會在控制臺打印版本號信息。
源碼
項目的目錄結構如圖所看到的。C代碼位於ViewController.m文件裏。內容例如以下所看到的。
/** * 最簡單的基於FFmpeg的HelloWorld程序 - IOS * Simplest FFmpeg Helloworld - IOS * * 雷霄驊 Lei Xiaohua * [email protected] * 中國傳媒大學/數字電視技術 * Communication University of China / Digital TV Technology * http://blog.csdn.net/leixiaohua1020 * * 本程序能夠獲得FFmpeg類庫相關的信息。 * This software can get information about FFmpeg libraries. * */ #import "ViewController.h" #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavfilter/avfilter.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. av_register_all(); char info[10000] = { 0 }; printf("%s\n", avcodec_configuration()); sprintf(info, "%s\n", avcodec_configuration()); NSString * info_ns = [NSString stringWithFormat:@"%s", info]; self.content.text=info_ns; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)clickProtocolButton:(id)sender { //Alert /* UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"Title" message:@"This is content" delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil]; [alter show]; */ char info[40000]={0}; av_register_all(); struct URLProtocol *pup = NULL; //Input struct URLProtocol **p_temp = &pup; avio_enum_protocols((void **)p_temp, 0); while ((*p_temp) != NULL){ sprintf(info, "%s[In ][%10s]\n", info, avio_enum_protocols((void **)p_temp, 0)); } pup = NULL; //Output avio_enum_protocols((void **)p_temp, 1); while ((*p_temp) != NULL){ sprintf(info, "%s[Out][%10s]\n", info, avio_enum_protocols((void **)p_temp, 1)); } //printf("%s", info); NSString * info_ns = [NSString stringWithFormat:@"%s", info]; self.content.text=info_ns; } - (IBAction)clickAVFormatButton:(id)sender { char info[40000] = { 0 }; av_register_all(); AVInputFormat *if_temp = av_iformat_next(NULL); AVOutputFormat *of_temp = av_oformat_next(NULL); //Input while(if_temp!=NULL){ sprintf(info, "%s[In ]%10s\n", info, if_temp->name); if_temp=if_temp->next; } //Output while (of_temp != NULL){ sprintf(info, "%s[Out]%10s\n", info, of_temp->name); of_temp = of_temp->next; } //printf("%s", info); NSString * info_ns = [NSString stringWithFormat:@"%s", info]; self.content.text=info_ns; } - (IBAction)clickAVCodecButton:(id)sender { char info[40000] = { 0 }; av_register_all(); AVCodec *c_temp = av_codec_next(NULL); while(c_temp!=NULL){ if (c_temp->decode!=NULL){ sprintf(info, "%s[Dec]", info); } else{ sprintf(info, "%s[Enc]", info); } switch (c_temp->type){ case AVMEDIA_TYPE_VIDEO: sprintf(info, "%s[Video]", info); break; case AVMEDIA_TYPE_AUDIO: sprintf(info, "%s[Audio]", info); break; default: sprintf(info, "%s[Other]", info); break; } sprintf(info, "%s%10s\n", info, c_temp->name); c_temp=c_temp->next; } //printf("%s", info); NSString * info_ns = [NSString stringWithFormat:@"%s", info]; self.content.text=info_ns; } - (IBAction)clickAVFilterButton:(id)sender { char info[40000] = { 0 }; avfilter_register_all(); AVFilter *f_temp = (AVFilter *)avfilter_next(NULL); while (f_temp != NULL){ sprintf(info, "%s[%10s]\n", info, f_temp->name); } //printf("%s", info); NSString * info_ns = [NSString stringWithFormat:@"%s", info]; self.content.text=info_ns; } - (IBAction)clickConfigurationButton:(id)sender { char info[10000] = { 0 }; av_register_all(); sprintf(info, "%s\n", avcodec_configuration()); //printf("%s", info); //self.content.text=@"Lei Xiaohua"; NSString * info_ns = [NSString stringWithFormat:@"%s", info]; self.content.text=info_ns; } @end
執行結果
App在手機上執行後的結果例如以下圖所看到的。單擊不同的button,能夠得到類庫不同方面的信息。單擊“Protocol”button內容例如以下所看到的。
單擊“AVFormat”button內容例如以下所看到的。
單擊“AVCodec”button內容例如以下所看到的。
單擊“Configure”button即為程序開始執行時候的內容。
下載
simplest ffmpeg mobile
項目主頁
Github:https://github.com/leixiaohua1020/simplest_ffmpeg_mobile
開源中國:https://git.oschina.net/leixiaohua1020/simplest_ffmpeg_mobile
SourceForge:https://sourceforge.net/projects/simplestffmpegmobile/
本解決方式包括了使用FFmpeg在移動端處理多媒體的各種樣例:
[Android]
simplest_android_player: 基於安卓接口的視頻播放器
simplest_ffmpeg_android_helloworld: 安卓平臺下基於FFmpeg的HelloWorld程序
simplest_ffmpeg_android_decoder: 安卓平臺下最簡單的基於FFmpeg的視頻解碼器
simplest_ffmpeg_android_decoder_onelib: 安卓平臺下最簡單的基於FFmpeg的視頻解碼器-單庫版
simplest_ffmpeg_android_streamer: 安卓平臺下最簡單的基於FFmpeg的推流器
simplest_ffmpeg_android_transcoder: 安卓平臺下移植的FFmpeg命令行工具
simplest_sdl_android_helloworld: 移植SDL到安卓平臺的最簡單程序
[IOS]
simplest_ios_player: 基於IOS接口的視頻播放器
simplest_ffmpeg_ios_helloworld: IOS平臺下基於FFmpeg的HelloWorld程序
simplest_ffmpeg_ios_decoder: IOS平臺下最簡單的基於FFmpeg的視頻解碼器
simplest_ffmpeg_ios_streamer: IOS平臺下最簡單的基於FFmpeg的推流器
simplest_ffmpeg_ios_transcoder: IOS平臺下移植的ffmpeg.c命令行工具
simplest_sdl_ios_helloworld: 移植SDL到IOS平臺的最簡單程序
最簡單的基於FFmpeg的移動端樣例:IOS HelloWorld