ffmpeg build iOS script


build ffmpeg .a

#!/bin/sh

# directories
FF_VERSION="4.0.3"
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 --disable-encoders --disable-decoders \
                 --disable-network --disable-muxers --disable-demuxers --disable-filters \
                 --disable-protocols --disable-parsers \
                 --enable-decoder=h264 --enable-demuxer=h264 \
                 --enable-parser=h264 --enable-encoder=aac \
                 --enable-decoder=aac --enable-pthreads --enable-asm \
                 --enable-runtime-cpudetect --enable-optimizations --enable-stripping"

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"

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 https://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


build ffmpeg framework

#!/bin/sh

# directories
SCRATCH=`pwd`/"scratch"
ARCHS="arm64 armv7 i386 x86_64"

FFMPEG_VERSION="3.4"
export FFMPEG_VERSION
HEADER_SUFFIX=".h"
CURRENT_FOLDER=`pwd`
FRAMEWORK_NAME="FFmpeg"
FRAMEWORK_EXT=".framework"
FRAMEWORK="$FRAMEWORK_NAME$FRAMEWORK_EXT"
BUILD_FOLDER="$CURRENT_FOLDER/FFmpeg-iOS"
BUILD_THIN_FOLDER="$CURRENT_FOLDER/thin"
BUILD_INCLUDE_FOLDER="$BUILD_FOLDER/include"
BUILD_LIB_FOLDER="$BUILD_FOLDER/lib"
OUTPUT_FOLDER="$CURRENT_FOLDER/$FRAMEWORK"
OUTPUT_INFO_PLIST_FILE="$OUTPUT_FOLDER/Info.plist"
OUTPUT_HEADER_FOLDER="$OUTPUT_FOLDER/Headers"
OUTPUT_UMBRELLA_HEADER="$OUTPUT_HEADER_FOLDER/ffmpeg.h"
OUTPUT_MODULES_FOLDER="$OUTPUT_FOLDER/Modules"
OUTPUT_MODULES_FILE="$OUTPUT_MODULES_FOLDER/module.modulemap"
VERSION_NEW_NAME="Version.h"
BUNDLE_ID="org.ffmpeg.FFmpeg"

function CreateFramework() {
     
  rm -rf $OUTPUT_FOLDER
  mkdir -p $OUTPUT_HEADER_FOLDER $OUTPUT_MODULES_FOLDER
}

function CompileSource() {
     
  ./build-ffmpeg.sh $ARCHS
  ./build-ffmpeg.sh lipo
}

function MergeStaticLibrary() {
     
  local files=""

  for ARCH in $ARCHS; do
    folder="$SCRATCH/$ARCH"
    name="$FRAMEWORK_NAME$ARCH.a"
    ar cru $name $(find $folder -name "*.o")
    files="$files $name"
  done

  lipo -create $files -output FFmpeg

  for file in $files; do
    rm -rf $file
  done
  mv $FRAMEWORK_NAME $OUTPUT_FOLDER
}

function RenameHeader() {
     
  local include_folder="$(pwd)/FFmpeg-iOS/include"
  local need_replace_version_folder=""
  for folder in "$include_folder"/*; do
    local folder_name=`basename $folder`
    local verstion_file_name="$folder_name$VERSION_NEW_NAME"
    for header in "$folder"/*; do
			local header_name=`basename $header`

			local dst_name=$header_name
			if [ $header_name == "version.h" ]; then
				dst_name=$verstion_file_name
			fi

			local dst_folder=$OUTPUT_HEADER_FOLDER
			local file_name="$folder/$header_name"
			local dst_file_name="$dst_folder/$dst_name"
			cp $file_name $dst_file_name
			find "$dst_folder" -name "$dst_name" -type f -exec sed -i '' "s/\"version.h\"/\"$verstion_file_name\"/g" {
     } \;
		done
    need_replace_version_folder="$need_replace_version_folder $folder_name"
  done

  for folder_name in $need_replace_version_folder; do
    local verstion_file_name="$folder_name$VERSION_NEW_NAME"
    find $OUTPUT_HEADER_FOLDER -type f -exec sed -i '' "s/\"$folder_name\/version.h\"/\"$verstion_file_name\"/g" {
     } \;
  done
  find $OUTPUT_HEADER_FOLDER -type f -exec sed -i '' "s/libavformat\///g" {
     } \;
  find $OUTPUT_HEADER_FOLDER -type f -exec sed -i '' "s/libavutil\///g" {
     } \;
	find $OUTPUT_HEADER_FOLDER -type f -exec sed -i '' "s/libavcodec\///g" {
     } \;
}

# COPY MISSING inttypes.h
function CopyInttype() {
     
  local file="$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/clang/include/inttypes.h"
	cp $file $OUTPUT_HEADER_FOLDER
	find $OUTPUT_HEADER_FOLDER -type f -exec sed -i '' "s//\"inttypes.h\"/g" {
     } \;
}

function CreateModulemapAndUmbrellaHeader() {
     
  #create ffmpeg.h
  cat > $OUTPUT_UMBRELLA_HEADER <#import 
#import 
#import 
#include "avcodec.h"
#include "avdevice.h"
#include "avfilter.h"
#include "avformat.h"
#include "avutil.h"
#include "swscale.h"
#include "swresample.h"
double FFmpegVersionNumber = $FFMPEG_VERSION;
EOF

  cat > $OUTPUT_MODULES_FILE <$FRAMEWORK_NAME {
     
  umbrella header "ffmpeg.h"

  export *
  module * {
      export * }
}
EOF
}

function CreateInfoPlist() {
     
  DEFAULT_iOS_SDK_VERSION=`defaults read $(xcode-select -p)/Platforms/iPhoneOS.platform/version CFBundleShortVersionString`
  DTCompiler=`defaults read $(xcode-select -p)/../info DTCompiler`
  DTPlatformBuild=`defaults read $(xcode-select -p)/../info DTPlatformBuild`
  DTSDKBuild=`defaults read $(xcode-select -p)/../info DTSDKBuild`
  DTXcode=`defaults read $(xcode-select -p)/../info DTXcode`
  DTXcodeBuild=`defaults read $(xcode-select -p)/../info DTXcodeBuild`
  OS_BUILD_VERSION=$(sw_vers -buildVersion)
  cat > $OUTPUT_INFO_PLIST_FILE <"1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  "1.0">
  
          BuildMachineOSBuild</key>
          $OS_BUILD_VERSION</string>
          CFBundleDevelopmentRegion</key>
          en</string>
          CFBundleExecutable</key>
          $FRAMEWORK_NAME</string>
          CFBundleIdentifier</key>
          $BUNDLE_ID</string>
          CFBundleInfoDictionaryVersion</key>
          6.0</string>
          CFBundleName</key>
          $FRAMEWORK_NAME</string>
          CFBundlePackageType</key>
          FMWK</string>
          CFBundleShortVersionString</key>
          $FFMPEG_VERSION</string>
          CFBundleSignature</key>
          ????</string>
          CFBundleSupportedPlatforms</key>
          
          iPhoneOS</string>
          </array>
          CFBundleVersion</key>
          1</string>
          DTCompiler</key>
          $DTCompiler</string>
          DTPlatformBuild</key>
          $DTPlatformBuild</string>
          DTPlatformName</key>
          iphoneos</string>
          DTPlatformVersion</key>
          $DEFAULT_iOS_SDK_VERSION</string>
          DTSDKBuild</key>
          $DTSDKBuild</string>
          DTSDKName</key>
          iphoneos$DEFAULT_iOS_SDK_VERSION</string>
          DTXcode</key>
          $DTXcode</string>
          DTXcodeBuild</key>
          $DTXcodeBuild</string>
          MinimumOSVersion</key>
          8.0</string>
          UIDeviceFamily</key>
          
          1</integer>
          2</integer>
          </array>
  </dict>
  </plist>
EOF
}

CompileSource
CreateFramework
MergeStaticLibrary
RenameHeader
CreateModulemapAndUmbrellaHeader
CopyInttype
CreateInfoPlist