FFmpeg aus dem Quellcode für iOS unter macOS erstellen

Diese Seite erklärt, wie man FFmpeg für iOS als Frameworks konfiguriert und baut. Die Kompilierung für iOS ist eine Cross-Kompilierung und setzt die Verwendung von macOS als Host-System voraus. Die erforderlichen Schritte sind:

  • Vorbereiten der Build-Umgebung
  • Beschaffung des FFmpeg-Quellcodes
  • Konfigurieren von FFmpeg über die Befehlszeile
  • Dynamische Bibliotheken erstellen
  • Erstellen von iOS-Frameworks aus FFmpeg-Bibliotheken
  • XCFrameworks erstellen
  • Einbetten von Frameworks

Hinweis: Die folgende Dokumentation geht davon aus, dass Sie mit FFmpeg-Bibliotheken und -Code unter ~/ffmpeg arbeiten.

Vorbereiten der Build-Umgebung

Die Build-Umgebung für iOS wird von Apples Xcode-Anwendung bereitgestellt, die die Toolchain (Compiler, Linker und andere Tools) und das iOS-Plattform-SDK (Header und Bibliotheken) enthält, gegen die Sie bauen und linken.

Beschaffung des FFmpeg-Quellcodes

Sie können den FFmpeg-Quellcode auf folgende Weise erhalten:

  • Herunterladen von der FFmpeg Download-Seite.
  • Klonen von git. Zum Beispiel klonen diese Befehle die Version 7.1 der FFmpeg-Quellen nach ~/ffmpeg/ffmpeg_src.
    % cd ~/ffmpeg/
    % git clone --branch n7.1 https://git.ffmpeg.org/ffmpeg.git ffmpeg_src

Hinweis: Es wird empfohlen, die gleiche FFmpeg-Version zu verwenden, wie sie auf der HauptseiteQt Multimedia dokumentiert ist.

Konfigurieren und Erstellen von FFmpeg

Erstellen Sie die Verzeichnisse build und installed innerhalb des Verzeichnisses ~/ffmpeg und navigieren Sie zu build:

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

Um FFmpeg zu konfigurieren, führen Sie aus:

% ../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

Die Befehlszeilenprogramme und die Dokumentation werden nicht benötigt; die Netzwerkfunktionen sollten aktiviert sein. Wir erstellen gemeinsam genutzte Bibliotheken und benötigen keine statischen Bibliotheken (lassen Sie --disable-static weg, um statische Bibliotheken zu erstellen). --sysroot gibt die Wurzel des Cross-Build-Baums an. Das Argument --prefix gibt einen Pfad an, in dem die FFmpeg-Bibliotheken nach der Erstellung installiert werden. Wir bauen auf dem macOS-Host für das iOS-Ziel, so dass wir die Cross-Kompilierung aktivieren. --extra-ldflags legt die Mindestversion von iOS fest. --install-name-dir ist eine Zeichenkette, die den Verzeichnisteil des Feldes "install_name" der gemeinsam genutzten Bibliotheken auf Apple-Plattformen für installierte Ziele angibt. AudioToolBox ist deaktiviert, da FFmpeg Teile des AudioToolBox-Frameworks verwendet, die unter iOS nicht verfügbar sind.

Hinweis: Wenn Sie im obigen Beispiel "iphoneos" durch "iphonesimulator" und "miphoneos-version" durch "mios-simulator-version-min" ersetzen, wird FFmpeg so konfiguriert, dass es die für den iOS-Simulator geeigneten Bibliotheken verwendet.

Um Hilfe zu anderen Konfigurationsoptionen zu erhalten, führen Sie aus:

% ../ffmpeg_src/configure --help

Nachdem die Konfiguration abgeschlossen ist, bauen Sie die FFmpeg-Bibliotheken:

% make -j install

Erstellen von iOS-Frameworks aus FFmpeg-Bibliotheken

Um in iOS-Anwendungen zu funktionieren, müssen die dynamischen FFmpeg-Bibliotheken in Frameworks umgewandelt und in Anwendungspakete eingebettet werden. Ein Framework ist ein hierarchisches Verzeichnis, das Ressourcen wie eine dynamische Bibliothek, Bilddateien, lokalisierte Strings, Header-Dateien und Referenzdokumentation in einem einzigen Paket kapselt. In unserem Fall enthalten FFmpeg-Frameworks nur dynamische Bibliotheken und entsprechende Info.plist-Dateien. Zum Beispiel wird libavcodec, das in ein Framework konvertiert wurde, zum Verzeichnis libavcodec.framework mit diesem Inhalt:

  • Info.plist (enthält die Beschreibung des Frameworks)
  • libavcodec (dynamische Bibliothek)

Im Gegensatz zu den dynamischen Bibliotheken, die wir im vorherigen Schritt erstellt haben, sind die dynamischen Bibliotheken in iOS-Frameworks nicht versioniert und haben keine "dylib"-Erweiterungen. Daher müssen wir die Namen der Bibliothekskennungen und Abhängigkeiten in unseren dynamischen Bibliotheken festlegen. Das Dienstprogramm otool hilft uns, solche Namen zu finden. Zum Beispiel:

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

gibt uns diese Namen (wir zeigen nur FFmpeg-bezogene Namen):

@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)

Um diese Namen zu korrigieren, verwenden Sie das Dienstprogramm install_name_tool. Die Optionen des Dienstprogramms sind:

  • -id - erlaubt die Änderung des Identifikationsnamens der Shared Library.
  • -change - erlaubt die Änderung des Installationsnamens der abhängigen Shared Library.

Dieses Skript konvertiert die zuvor erstellten dynamischen Bibliotheken in Frameworks. Der Code geht davon aus, dass Sie es aus dem Verzeichnis build ausführen und die Frameworks sich in ~/ffmpeg/installed/framework befinden:

#!/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

Erstellen eines Multiplattform-Binär-Framework-Bundles

Ein XCFramework-Bundle ist ein Paket, das Frameworks und Bibliotheken enthält, die zum Erstellen für mehrere Plattformen erforderlich sind, z. B. iOS und iOS-Simulator. Um ein solches Framework zu erstellen, verwenden Sie das Dienstprogramm xcodebuild. Wenn Sie beispielsweise Frameworks für iOS und Simulator in den Verzeichnissen ~/ffmpeg/installed/arm64 und ~/ffmpeg/installed/arm64-simulator haben, sehen die Argumente des Dienstprogramms wie folgt aus:

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

Einbetten von Frameworks

Betten Sie die FFmpeg-Frameworks in ein Anwendungsbündel ein. Informationen über das Einbetten von Frameworks mit XCode finden Sie unter

Einbetten von Frameworks in eine Anwendung.

© 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.