iOS用FFmpegをmacOSでソースからビルドする

このページでは、iOS用FFmpegをフレームワークとして設定・ビルドする方法を説明します。iOS用のコンパイルはクロスコンパイルであり、ホストシステムとしてmacOSを使用することを前提としています。必要な手順は以下の通りです:

  • ビルド環境の準備
  • FFmpegソースコードの入手
  • コマンドラインからFFmpegを設定する
  • ダイナミックライブラリのビルド
  • FFmpegライブラリからiOSフレームワークを作成する
  • XCFrameworksの作成
  • フレームワークの埋め込み

注: 以下のドキュメントは、~/ffmpeg の下で FFmpeg ライブラリとコードを扱うことを前提としています。

ビルド環境の準備

iOSのビルド環境はAppleのXcodeアプリケーションによって提供され、ツールチェーン(コンパイラ、リンカ、およびその他のツール)と、ビルドしてリンクするiOSプラットフォーム-SDK(ヘッダとライブラリ)が含まれています。

FFmpegソースコードの入手

FFmpegのソースコードは以下の方法で入手できます:

  • FFmpegのダウンロードページからダウンロードする。
  • gitからクローンする。例えば、以下のコマンドはバージョン 7.1 の FFmpeg ソースを~/ffmpeg/ffmpeg_src にクローンします。
    % cd ~/ffmpeg/
    % git clone --branch n7.1 https://git.ffmpeg.org/ffmpeg.git ffmpeg_src

注意: Qt Multimedia メインページに記載されているのと同じ FFmpeg バージョンを使用することをお勧めします。

FFmpegの設定とビルド

~/ffmpeg ディレクトリの中にbuildinstalled ディレクトリを作成し、build に移動します:

% mkdir ~/ffmpeg/build
% mkdir ~/ffmpeg/installed
% cd ~/ffmpeg/build

FFmpegを設定するには、以下を実行してください:

% ../ffmpeg_src/configure --disable-programs --disable-doc --enable-network --enable-shared --disable-static \
   --sysroot="$(xcrun --sdk iphoneos --show-sdk-path)" \
   --enable-cross-compile \
   --arch=arm64 \
   --prefix=../installed \
   --cc="xcrun --sdk iphoneos clang -arch arm64" \
   --cxx="xcrun --sdk iphoneos clang++ -arch arm64" \
   --extra-ldflags="-miphoneos-version-min=16.0" \
   --install-name-dir='@rpath' \
   --disable-audiotoolbox

コマンドラインプログラムとドキュメントは必要ありません。共有ライブラリをビルドするので、スタティック・ライブラリは不要です(スタティック・ライブラリをビルドするには、--disable-static を省略します)。--sysroot はクロスビルド・ツリーのルートを指定します。--prefix 引数は、ビルド後にFFmpegライブラリをインストールするパスを指定します。iOSターゲットはmacOSホストでビルドするので、クロスコンパイルを有効にする。--extra-ldflags 、iOSの最小バージョンを設定する。--install-name-dir 、インストール済みターゲットのAppleプラットフォーム上の共有ライブラリの「install_name」フィールドのディレクトリ部分を指定する文字列。FFmpegはiOSでは利用できないAudioToolBoxフレームワークの一部を使用しているため、AudioToolBoxは無効になっています。

注意: 上記の例では、'iphoneos' を 'iphonesimulator' に、'miphoneos-version' を 'mios-simulator-version-min' に置き換えることで、FFmpeg が iOS シミュレータに適したライブラリとしてビルドされるように設定されています。

その他の設定オプションに関するヘルプは、以下を実行してください:

% ../ffmpeg_src/configure --help

設定が完了したら、FFmpegライブラリをビルドします:

% make -j install

FFmpegライブラリからiOSフレームワークを作成する

iOSアプリケーションで動作させるには、FFmpegダイナミックライブラリをフレームワークに変換し、アプリケーションバンドルに組み込む必要があります。フレームワークとは、ダイナミックライブラリ、画像ファイル、ローカライズされた文字列、ヘッダーファイル、リファレンスドキュメントなどのリソースを1つのパッケージにカプセル化した階層ディレクトリのことです。私たちの場合、FFmpegフレームワークには、ダイナミックライブラリと対応するInfo.plistファイルのみが含まれています。例えば、フレームワークに変換されたlibavcodecは、libavcodec.framework ディレクトリになり、以下の内容が含まれます:

  • Info.plist (フレームワークの説明を含む)
  • libavcodec(ダイナミックライブラリ)

前のステップで構築したダイナミック・ライブラリとは異なり、iOSフレームワーク内のダイナミック・ライブラリはバージョン管理されておらず、'dylib'拡張子もありません。このため、ダイナミック・ライブラリのライブラリ識別名と依存関係を修正する必要がある。otool ユーティリティは、そのような名前を見つけるのに役立つ。例えば

%otool -L ../installed/lib/libavcodec.dylib

はこれらの名前を教えてくれます(FFmpeg 関連の名前のみを表示します):

@rpath/libavcodec.61.dylib (compatibility version 61.0.0, current version 61.19.100)
@rpath/libswresample.5.dylib (compatibility version 5.0.0, current version 5.3.100)
@rpath/libavutil.59.dylib (compatibility version 59.0.0, current version 59.39.100)

これらの名前を修正するには、install_name_tool ユーティリティを使用します。ユーティリティのオプションは次のとおりです:

  • -id - 共有ライブラリの識別名を変更できます。
  • -change - 依存する共有ライブラリのインストール名を変更できます。

このスクリプトは、以前にビルドされたダイナミック・ライブラリをフレームワークに変換します。このコードは、build ディレクトリから実行し、フレームワークが~/ffmpeg/installed/framework にあることを前提としています:

#!/usr/bin/env bash

# Creates an Info.plist file for a given framework:
build_info_plist() {
    local file_path="$1"
    local framework_name="$2"
    local framework_id="$3"

    # Minimum version must be the same we used when building FFmpeg.
    local minimum_version_key="MinimumOSVersion"
    local minimum_os_version="16.0"

    local supported_platforms="iPhoneOS"

    info_plist="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleExecutable</key>
    <string>${framework_name}</string>
    <key>CFBundleIdentifier</key>
    <string>${framework_id}</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${framework_name}</string>
    <key>CFBundlePackageType</key>
    <string>FMWK</string>
    <key>CFBundleShortVersionString</key>
    <string>7.0.2</string>
    <key>CFBundleVersion</key>
    <string>7.0.2</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>${minimum_version_key}</key>
    <string>${minimum_os_version}</string>
    <key>CFBundleSupportedPlatforms</key>
    <array>
        <string>${supported_platforms}</string>
    </array>
    <key>NSPrincipalClass</key>
    <string></string>
</dict>
</plist>"
    echo $info_plist | tee ${file_path} 1>/dev/null
}

dylib_regex="^@rpath/.*\.dylib$"

# Creates framework from a dylib file:
create_framework() {
    local framework_name="$1"
    local ffmpeg_library_path="../installed"
    local framework_complete_path="${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"

    # Create framework directory and copy dylib file to this directory:
    mkdir -p "${ffmpeg_library_path}/framework/${framework_name}.framework"
    cp "${ffmpeg_library_path}/lib/${framework_name}.dylib" "${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"

    # Change the shared library identification name, removing version number and 'dylib' extension;
    # \c Frameworks part of the name is needed since this is where frameworks will be installed in
    # an application bundle:
    install_name_tool -id @rpath/Frameworks/${framework_name}.framework/${framework_name} "${framework_complete_path}"

    # Add Info.plist file into the framework directory:
    build_info_plist "${ffmpeg_library_path}/framework/${framework_name}.framework/Info.plist" "${framework_name}" "io.qt.ffmpegkit."${framework_name}
    otool -L "$framework_complete_path" | awk '/\t/ {print $1}' | egrep "$dylib_regex" | while read -r dependency_path; do
        found_name=$(tmp=${dependency_path/*\/}; echo ${tmp/\.*})
        if [ "$found_name" != "$framework_name" ]
        then
            # Change the dependent shared library install name to remove version number and 'dylib' extension:
            install_name_tool -change "$dependency_path" @rpath/Frameworks/${found_name}.framework/${found_name} "${framework_complete_path}"
        fi
    done
}

ffmpeg_libs="libavcodec libavformat libavutil libswresample libswscale"

for name in $ffmpeg_libs; do
    create_framework $name
done

マルチプラットフォーム・バイナリー・フレームワーク・バンドルの作成

XCFramework バンドルは、iOS や iOS シミュレータなど、複数のプラットフォーム用にビルドするのに必要なフレームワークやライブラリを含むパッケージです。このようなフレームワークを作成するには、xcodebuild ユーティリティを使用します。例えば、iOS用とシミュレータ用のフレームワークが~/ffmpeg/installed/arm64~/ffmpeg/installed/arm64-simulator ディレクトリにある場合、ユーティリティの引数は次のようになります:

%xcodebuild -create-xcframework -framework ../installed/arm64/libavcodec.framework -framework ../installed/arm64-simulator/libavcodec.framework -output ../installed/framework/libavcodec.xcframework

フレームワークの埋め込み

FFmpeg フレームワークをアプリケーションバンドルに埋め込みます。XCodeを使ってフレームワークを埋め込む方法については、以下を参照してください。

アプリにフレームワークを埋め込む」を参照してください。

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.