diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..b3a42efe --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: [kewlbear] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..ba521c4a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,13 @@ +name: CI + +on: [push] + +jobs: + build: + + runs-on: macOS-latest + + steps: + - uses: actions/checkout@v1 + - name: build + run: ./build-ffmpeg.sh 2>.stderr diff --git a/.gitignore b/.gitignore index 05533205..e05f2795 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ scratch* thin* fat* +FFmpeg.framework +FFmpeg-* +.DS_Store diff --git a/.travis.yml b/.travis.yml index 87525ca6..c0e3d1d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,13 @@ env: - TARBALL=ffmpeg-ios-$TRAVIS_BRANCH.tar.bz2 after_success: - - tar cjf $TARBALL FFmpeg-iOS .stderr scratch/*/config.log ffmpeg/LICENSE ffmpeg/COPYING.* + - tar cjf $TARBALL FFmpeg-iOS .stderr scratch/*/config.log ffmpeg*/LICENSE.md ffmpeg*/COPYING.* README.md - openssl aes-256-cbc -k "$secret" -in .sf -d -a -out id_sf - chmod 600 id_sf - scp -i id_sf -o 'StrictHostKeyChecking no' $TARBALL koolbear@frs.sourceforge.net:/home/frs/project/ffmpeg-ios after_failure: cat .stderr + +osx_image: xcode8.3 + +sudo: false diff --git a/README.md b/README.md index ee653790..33648895 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,27 @@ # FFmpeg iOS build script -[![Build Status](https://travis-ci.org/kewlbear/FFmpeg-iOS-build-script.png?branch=master)](https://travis-ci.org/kewlbear/FFmpeg-iOS-build-script) +See the following repository for Swift package, .xcframeworks and more: -This is a shell script to build FFmpeg libraries for iOS apps. +https://github.com/kewlbear/FFmpeg-iOS + +[![Build Status](https://travis-ci.org/kewlbear/FFmpeg-iOS-build-script.svg?branch=master)](https://travis-ci.org/kewlbear/FFmpeg-iOS-build-script) + +This is a shell script to build FFmpeg libraries for iOS and tvOS apps. Tested with: -* FFmpeg http://git.videolan.org/?p=ffmpeg.git;a=commit;h=f29cdbe1b59a0d997733b507041e15ec68cef00c -* Xcode 5.0.2 -* https://github.com/libav/gas-preprocessor (support arm64) +* FFmpeg 4.3.1 +* Xcode 12.2 + +## Requirements + +* https://github.com/libav/gas-preprocessor +* yasm 1.2.0 ## Usage +Use build-ffmpeg-tvos.sh for tvOS. + * To build everything: ./build-ffmpeg.sh @@ -30,10 +40,12 @@ Tested with: ## Download -https://downloads.sourceforge.net/project/ffmpeg-ios/ffmpeg-ios.tar.bz2 +You can download a binary for FFmpeg 4.3.1 release at https://downloads.sourceforge.net/project/ffmpeg-ios/ffmpeg-ios-master.tar.bz2 -Currently, arm64 architecture is not included in the download. +## External libraries -## Influences +You should link your app with -* https://github.com/bbcallen/ijkplayer/blob/fc70895c64cbbd20f32f1d81d2d48609ed13f597/ios/tools/do-compile-ffmpeg.sh#L7 +* libz.dylib +* libbz2.dylib +* libiconv.dylib diff --git a/build-ffmpeg-iOS-framework.sh b/build-ffmpeg-iOS-framework.sh new file mode 100755 index 00000000..56e2be6b --- /dev/null +++ b/build-ffmpeg-iOS-framework.sh @@ -0,0 +1,191 @@ +#!/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 +#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 < $OUTPUT_INFO_PLIST_FILE < + + + + BuildMachineOSBuild + $OS_BUILD_VERSION + CFBundleDevelopmentRegion + en + CFBundleExecutable + $FRAMEWORK_NAME + CFBundleIdentifier + $BUNDLE_ID + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $FRAMEWORK_NAME + CFBundlePackageType + FMWK + CFBundleShortVersionString + $FFMPEG_VERSION + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + iPhoneOS + + CFBundleVersion + 1 + DTCompiler + $DTCompiler + DTPlatformBuild + $DTPlatformBuild + DTPlatformName + iphoneos + DTPlatformVersion + $DEFAULT_iOS_SDK_VERSION + DTSDKBuild + $DTSDKBuild + DTSDKName + iphoneos$DEFAULT_iOS_SDK_VERSION + DTXcode + $DTXcode + DTXcodeBuild + $DTXcodeBuild + MinimumOSVersion + 8.0 + UIDeviceFamily + + 1 + 2 + + + +EOF +} + +CompileSource +CreateFramework +MergeStaticLibrary +RenameHeader +CreateModulemapAndUmbrellaHeader +CopyInttype +CreateInfoPlist diff --git a/build-ffmpeg-tvos.sh b/build-ffmpeg-tvos.sh new file mode 100755 index 00000000..7717bfda --- /dev/null +++ b/build-ffmpeg-tvos.sh @@ -0,0 +1,156 @@ +#!/bin/sh + +# directories +SOURCE="ffmpeg-3.1.1" +FAT="FFmpeg-tvOS" + +SCRATCH="scratch-tvos" +# must be an absolute path +THIN=`pwd`/"thin-tvos" + +# absolute path to x264 library +#X264=`pwd`/../x264-ios/x264-iOS + +#FDK_AAC=`pwd`/fdk-aac/fdk-aac-ios + +CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \ + --disable-doc --enable-pic --disable-indev=avfoundation" + +if [ "$X264" ] +then + CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-libx264" +fi + +if [ "$FDK_AAC" ] +then + CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-libfdk-aac" +fi + +# avresample +#CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-avresample" + +ARCHS="arm64 x86_64" + +COMPILE="y" +LIPO="y" + +DEPLOYMENT_TARGET="9.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" = "x86_64" ] + then + PLATFORM="AppleTVSimulator" + CFLAGS="$CFLAGS -mtvos-simulator-version-min=$DEPLOYMENT_TARGET" + else + PLATFORM="AppleTVOS" + CFLAGS="$CFLAGS -mtvos-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" + AR="xcrun -sdk $XCRUN_SDK ar" + 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" \ + --ar="$AR" \ + $CONFIGURE_FLAGS \ + --extra-cflags="$CFLAGS" \ + --extra-ldflags="$LDFLAGS" \ + --prefix="$THIN/`basename $PWD`" \ + || exit 1 + + xcrun -sdk $XCRUN_SDK 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 diff --git a/build-ffmpeg.sh b/build-ffmpeg.sh index 09e46c43..319fadbe 100755 --- a/build-ffmpeg.sh +++ b/build-ffmpeg.sh @@ -1,7 +1,12 @@ #!/bin/sh # directories -SOURCE="ffmpeg-2.2" +FF_VERSION="4.3.1" +#FF_VERSION="snapshot-git" +if [[ $FFMPEG_VERSION != "" ]]; then + FF_VERSION=$FFMPEG_VERSION +fi +SOURCE="ffmpeg-$FF_VERSION" FAT="FFmpeg-iOS" SCRATCH="scratch" @@ -9,7 +14,9 @@ SCRATCH="scratch" THIN=`pwd`/"thin" # absolute path to x264 library -#X264=`pwd`/fat_x264 +#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" @@ -19,15 +26,20 @@ 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 armv7s armv7 x86_64 i386" +ARCHS="arm64 armv7 x86_64 i386" COMPILE="y" LIPO="y" -DEPLOYMENT_TARGET="6.0" +DEPLOYMENT_TARGET="8.0" if [ "$*" ] then @@ -53,7 +65,7 @@ then if [ ! `which brew` ] then echo 'Homebrew not found. Trying to install...' - ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)" \ + ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" \ || exit 1 fi echo 'Trying to install Yasm...' @@ -62,7 +74,7 @@ then if [ ! `which gas-preprocessor.pl` ] then echo 'gas-preprocessor.pl not found. Trying to install...' - (curl -3L https://github.com/libav/gas-preprocessor/raw/master/gas-preprocessor.pl \ + (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 @@ -71,7 +83,7 @@ then if [ ! -r $SOURCE ] then echo 'FFmpeg source not found. Trying to download...' - curl http://www.ffmpeg.org/releases/ffmpeg-2.2.tar.bz2 | tar xj \ + curl http://www.ffmpeg.org/releases/$SOURCE.tar.bz2 | tar xj \ || exit 1 fi @@ -89,7 +101,7 @@ then CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET" else PLATFORM="iPhoneOS" - CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET" + CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode" if [ "$ARCH" = "arm64" ] then EXPORT="GASPP_FIX_XCODE5=1" @@ -98,6 +110,15 @@ then 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" ] @@ -105,14 +126,19 @@ 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 - $CWD/$SOURCE/configure \ + TMPDIR=${TMPDIR/%\/} $CWD/$SOURCE/configure \ --target-os=darwin \ --arch=$ARCH \ --cc="$CC" \ + --as="$AS" \ $CONFIGURE_FLAGS \ --extra-cflags="$CFLAGS" \ - --extra-cxxflags="$CXXFLAGS" \ --extra-ldflags="$LDFLAGS" \ --prefix="$THIN/$ARCH" \ || exit 1 diff --git a/build-x264.sh b/build-x264.sh deleted file mode 100755 index c94b7cbc..00000000 --- a/build-x264.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/sh - -CONFIGURE_FLAGS="--enable-static --enable-pic --disable-cli --disable-asm" - -ARCHS="arm64 armv7s x86_64 i386 armv7" - -# directories -SOURCE="x264" -FAT="fat-x264" - -SCRATCH="scratch-x264" -# must be an absolute path -THIN=`pwd`/"thin-x264" - -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" - AS="$CWD/$SOURCE/extras/gas-preprocessor.pl $CC" - CFLAGS="-arch $ARCH $SIMULATOR" - CXXFLAGS="$CFLAGS" - LDFLAGS="$CFLAGS" - - CC=$CC $CWD/$SOURCE/configure \ - $CONFIGURE_FLAGS \ - $HOST \ - $CPU \ - --extra-cflags="$CFLAGS" \ - --extra-ldflags="$LDFLAGS" \ - --prefix="$THIN/$ARCH" - - make -j3 install - 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 - lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB - done - - cd $CWD - cp -rf $THIN/$1/include $FAT -fi