Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtmultimedia-building-FFmpeg-ios.qdoc
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5\page qtmultimedia-building-ffmpeg-ios.html
6\title Building FFmpeg from source for iOS on macOS
7\brief This document describes how to build FFmpeg from source code.
8
9\include building-FFmpeg-contents.qdocinc {ios}
10\include building-FFmpeg-source.qdocinc {ios}
11\include building-FFmpeg-prerequisites.qdocinc {ios}
12\include building-FFmpeg-configure.qdocinc {ios}
13
14\section1 Creating iOS frameworks from FFmpeg libraries
15
16To work in iOS applications, FFmpeg dynamic libraries have to
17be converted into frameworks and embedded into application bundles.
18A framework is a hierarchical directory that encapsulates resources
19such as a dynamic library, image files, localized strings, header files,
20and reference documentation in a single package. In our case, FFmpeg frameworks
21only contain dynamic libraries and corresponding Info.plist files.
22For example, libavcodec converted to framework becomes \c libavcodec.framework
23directory with these contents:
24
25\list
26\li Info.plist (containing the description of the framework)
27\li libavcodec (dynamic library)
28\endlist
29
30Unlike dynamic libraries we built in the previous step, dynamic libraries
31inside iOS frameworks are unversioned and have no 'dylib' extensions. This requires
32fixing library identification names and dependencies in our dynamic libraries.
33The \c otool utility helps us to find such names. For example:
34
35\badcode
36otool -L ../installed/lib/libavcodec.dylib
37\endcode
38
39gives us these names (we only show FFmpeg-related names):
40
41\badcode
42@rpath/libavcodec.61.dylib (compatibility version 61.0.0, current version 61.19.100)
43@rpath/libswresample.5.dylib (compatibility version 5.0.0, current version 5.3.100)
44@rpath/libavutil.59.dylib (compatibility version 59.0.0, current version 59.39.100)
45\endcode
46
47 To fix these names, use the \c install_name_tool utility. The utility options are:
48
49 \list
50 \li \c {-id} - allows changing the shared library identification name.
51 \li \c {-change} - allows changing the dependent shared library install name.
52 \endlist
53
54This script converts the previously built dynamic libraries to frameworks. The code assumes
55that you run it from the \c build directory and the frameworks are located in
56\c{~/ffmpeg/installed/framework}:
57
58\badcode
59#!/usr/bin/env bash
60
61# Creates an Info.plist file for a given framework:
62build_info_plist() {
63 local file_path="$1"
64 local framework_name="$2"
65 local framework_id="$3"
66
67 # Minimum version must be the same we used when building FFmpeg.
68 local minimum_version_key="MinimumOSVersion"
69 local minimum_os_version="16.0"
70
71 local supported_platforms="iPhoneOS"
72
73 info_plist="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
74<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
75<plist version=\"1.0\">
76<dict>
77 <key>CFBundleDevelopmentRegion</key>
78 <string>en</string>
79 <key>CFBundleExecutable</key>
80 <string>${framework_name}</string>
81 <key>CFBundleIdentifier</key>
82 <string>${framework_id}</string>
83 <key>CFBundleInfoDictionaryVersion</key>
84 <string>6.0</string>
85 <key>CFBundleName</key>
86 <string>${framework_name}</string>
87 <key>CFBundlePackageType</key>
88 <string>FMWK</string>
89 <key>CFBundleShortVersionString</key>
90 <string>9.0.1</string>
91 <key>CFBundleVersion</key>
92 <string>9.0.1</string>
93 <key>CFBundleSignature</key>
94 <string>????</string>
95 <key>${minimum_version_key}</key>
96 <string>${minimum_os_version}</string>
97 <key>CFBundleSupportedPlatforms</key>
98 <array>
99 <string>${supported_platforms}</string>
100 </array>
101 <key>NSPrincipalClass</key>
102 <string></string>
103</dict>
104</plist>"
105 echo $info_plist | tee ${file_path} 1>/dev/null
106}
107
108dylib_regex="^@rpath/.*\.dylib$"
109
110# Creates framework from a dylib file:
111create_framework() {
112 local framework_name="$1"
113 local ffmpeg_library_path="../installed"
114 local framework_complete_path="${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"
115
116 # Create framework directory and copy dylib file to this directory:
117 mkdir -p "${ffmpeg_library_path}/framework/${framework_name}.framework"
118 cp "${ffmpeg_library_path}/lib/${framework_name}.dylib" "${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"
119
120 # Change the shared library identification name, removing version number and 'dylib' extension;
121 # \c Frameworks part of the name is needed since this is where frameworks will be installed in
122 # an application bundle:
123 install_name_tool -id @rpath/Frameworks/${framework_name}.framework/${framework_name} "${framework_complete_path}"
124
125 # Add Info.plist file into the framework directory:
126 build_info_plist "${ffmpeg_library_path}/framework/${framework_name}.framework/Info.plist" "${framework_name}" "io.qt.ffmpegkit."${framework_name}
127 otool -L "$framework_complete_path" | awk '/\t/ {print $1}' | egrep "$dylib_regex" | while read -r dependency_path; do
128 found_name=$(tmp=${dependency_path/*\/}; echo ${tmp/\.*})
129 if [ "$found_name" != "$framework_name" ]
130 then
131 # Change the dependent shared library install name to remove version number and 'dylib' extension:
132 install_name_tool -change "$dependency_path" @rpath/Frameworks/${found_name}.framework/${found_name} "${framework_complete_path}"
133 fi
134 done
135}
136
137ffmpeg_libs="libavcodec libavformat libavutil libswresample libswscale"
138
139for name in $ffmpeg_libs; do
140 create_framework $name
141done
142
143\endcode
144
145\section1 Creating a multiplatform binary framework bundle
146
147An XCFramework bundle is a package that includes frameworks and libraries
148necessary to build for multiple platforms, for example, iOS and iOS simulator.
149To create such a framework, use the \c xcodebuild utility. For example, if
150you have frameworks for iOS and simulator located in \c {~/ffmpeg/installed/arm64}
151and \c {~/ffmpeg/installed/arm64-simulator} directories, the utility arguments look
152like follows:
153
154\badcode
155xcodebuild -create-xcframework -framework ../installed/arm64/libavcodec.framework -framework ../installed/arm64-simulator/libavcodec.framework -output ../installed/framework/libavcodec.xcframework
156\endcode
157
158\section1 Embedding frameworks
159
160Embed the FFmpeg frameworks into an application bundle. For information on how to
161embed frameworks using XCode, refer to
162
163\l{https://developer.apple.com/library/archive/technotes/tn2435/_index.html}{Embedding Frameworks In An App}.
164
165*/