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
9This page explains how to configure and build \l{FFmpeg} for iOS as frameworks.
10Compilation for iOS is a cross-compilation and presumes using macOS as a host system.
11The required steps are:
12
13\list
14\li Preparing build environment
15\li Getting the FFmpeg source code
16\li Configuring FFmpeg from the command line
17\li Building dynamic libraries
18\li Creating iOS frameworks from FFmpeg libraries
19\li Creating XCFrameworks
20\li Embedding frameworks
21\endlist
22
23\note The following documentation assumes that you work with FFmpeg libraries and code
24under \c{~/ffmpeg}.
25
26\section1 Preparing build environment
27
28The build environment for iOS is provided by Apple's Xcode application, which includes
29the toolchain (compiler, linker, and other tools), and the iOS platform-SDK (headers
30and libraries) that you build and link against.
31
32\section1 Getting the FFmpeg source code
33
34You can get the FFmpeg source code in these ways:
35
36\list
37\li Download from the
38\l{https://ffmpeg.org/download.html#get-sources}{FFmpeg download page}.
39\li Clone from git. For example, these commands clone the version \ffmpegversion of the
40FFmpeg sources to \c{~/ffmpeg/ffmpeg_src}.
41\badcode
42cd ~/ffmpeg/
43git clone --branch n7.1.3 https://git.ffmpeg.org/ffmpeg.git ffmpeg_src
44\endcode
45\endlist
46
47\note It is recommended to use the same FFmpeg version as documented in the
48\l{Qt Multimedia}{Qt Multimedia main page}.
49
50\section1 Configuring and building FFmpeg
51
52Create a \c build and \c installed directories inside the \c{~/ffmpeg} directory and
53navigate into \c build:
54
55\badcode
56mkdir ~/ffmpeg/build
57mkdir ~/ffmpeg/installed
58cd ~/ffmpeg/build
59\endcode
60
61To configure FFmpeg, run:
62
63\badcode
64../ffmpeg_src/configure --disable-programs --disable-doc --enable-network --enable-shared --disable-static \
65 --sysroot="$(xcrun --sdk iphoneos --show-sdk-path)" \
66 --enable-cross-compile \
67 --arch=arm64 \
68 --prefix=../installed \
69 --cc="xcrun --sdk iphoneos clang -arch arm64" \
70 --cxx="xcrun --sdk iphoneos clang++ -arch arm64" \
71 --extra-cflags="-miphoneos-version-min=16.0" \
72 --extra-cxxflags="-miphoneos-version-min=16.0" \
73 --extra-objcflags="-miphoneos-version-min=16.0" \
74 --extra-ldflags="-miphoneos-version-min=16.0" \
75 --install-name-dir='@rpath' \
76 --disable-audiotoolbox
77\endcode
78
79The command line programs and documentation are not needed; network features
80should be enabled. We build shared libraries and don't need static libraries (omit
81\c{--disable-static} to build static libraries). \c{--sysroot} specifies the root of cross-build
82tree. The \c{--prefix} argument specifies a path where the FFmpeg libraries are installed
83after building. We build on macOS host for iOS target so we enable cross compilation.
84\c{--extra-ldflags} set the minimum version of iOS.
85\c{--install-name-dir} is a string specifying the directory portion of the "install_name"
86field of shared libraries on Apple platforms for installed targets.
87AudioToolBox is disabled, since FFmpeg is using parts of AudioToolBox
88framework which are not available on iOS.
89
90\note In the example above, replacing 'iphoneos' with 'iphonesimulator',
91and 'miphoneos-version' with 'mios-simulator-version-min', configures
92FFmpeg to be built as libraries suitable for iOS simulator.
93
94To get help on other configuration options, run:
95\badcode
96../ffmpeg_src/configure --help
97\endcode
98
99After configuration is complete, build FFmpeg libraries:
100
101\badcode
102make -j install
103\endcode
104
105\section1 Creating iOS frameworks from FFmpeg libraries
106
107To work in iOS applications, FFmpeg dynamic libraries have to
108be converted into frameworks and embedded into application bundles.
109A framework is a hierarchical directory that encapsulates resources
110such as a dynamic library, image files, localized strings, header files,
111and reference documentation in a single package. In our case, FFmpeg frameworks
112only contain dynamic libraries and corresponding Info.plist files.
113For example, libavcodec converted to framework becomes \c libavcodec.framework
114directory with these contents:
115
116\list
117\li Info.plist (containing the description of the framework)
118\li libavcodec (dynamic library)
119\endlist
120
121Unlike dynamic libraries we built in the previous step, dynamic libraries
122inside iOS frameworks are unversioned and have no 'dylib' extensions. This requires
123fixing library identification names and dependencies in our dynamic libraries.
124The \c otool utility helps us to find such names. For example:
125
126\badcode
127otool -L ../installed/lib/libavcodec.dylib
128\endcode
129
130gives us these names (we only show FFmpeg-related names):
131
132\badcode
133@rpath/libavcodec.61.dylib (compatibility version 61.0.0, current version 61.19.100)
134@rpath/libswresample.5.dylib (compatibility version 5.0.0, current version 5.3.100)
135@rpath/libavutil.59.dylib (compatibility version 59.0.0, current version 59.39.100)
136\endcode
137
138 To fix these names, use the \c install_name_tool utility. The utility options are:
139
140 \list
141 \li \c {-id} - allows changing the shared library identification name.
142 \li \c {-change} - allows changing the dependent shared library install name.
143 \endlist
144
145This script converts the previously built dynamic libraries to frameworks. The code assumes
146that you run it from the \c build directory and the frameworks are located in
147\c{~/ffmpeg/installed/framework}:
148
149\badcode
150#!/usr/bin/env bash
151
152# Creates an Info.plist file for a given framework:
153build_info_plist() {
154 local file_path="$1"
155 local framework_name="$2"
156 local framework_id="$3"
157
158 # Minimum version must be the same we used when building FFmpeg.
159 local minimum_version_key="MinimumOSVersion"
160 local minimum_os_version="16.0"
161
162 local supported_platforms="iPhoneOS"
163
164 info_plist="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
165<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
166<plist version=\"1.0\">
167<dict>
168 <key>CFBundleDevelopmentRegion</key>
169 <string>en</string>
170 <key>CFBundleExecutable</key>
171 <string>${framework_name}</string>
172 <key>CFBundleIdentifier</key>
173 <string>${framework_id}</string>
174 <key>CFBundleInfoDictionaryVersion</key>
175 <string>6.0</string>
176 <key>CFBundleName</key>
177 <string>${framework_name}</string>
178 <key>CFBundlePackageType</key>
179 <string>FMWK</string>
180 <key>CFBundleShortVersionString</key>
181 <string>7.0.2</string>
182 <key>CFBundleVersion</key>
183 <string>7.0.2</string>
184 <key>CFBundleSignature</key>
185 <string>????</string>
186 <key>${minimum_version_key}</key>
187 <string>${minimum_os_version}</string>
188 <key>CFBundleSupportedPlatforms</key>
189 <array>
190 <string>${supported_platforms}</string>
191 </array>
192 <key>NSPrincipalClass</key>
193 <string></string>
194</dict>
195</plist>"
196 echo $info_plist | tee ${file_path} 1>/dev/null
197}
198
199dylib_regex="^@rpath/.*\.dylib$"
200
201# Creates framework from a dylib file:
202create_framework() {
203 local framework_name="$1"
204 local ffmpeg_library_path="../installed"
205 local framework_complete_path="${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"
206
207 # Create framework directory and copy dylib file to this directory:
208 mkdir -p "${ffmpeg_library_path}/framework/${framework_name}.framework"
209 cp "${ffmpeg_library_path}/lib/${framework_name}.dylib" "${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"
210
211 # Change the shared library identification name, removing version number and 'dylib' extension;
212 # \c Frameworks part of the name is needed since this is where frameworks will be installed in
213 # an application bundle:
214 install_name_tool -id @rpath/Frameworks/${framework_name}.framework/${framework_name} "${framework_complete_path}"
215
216 # Add Info.plist file into the framework directory:
217 build_info_plist "${ffmpeg_library_path}/framework/${framework_name}.framework/Info.plist" "${framework_name}" "io.qt.ffmpegkit."${framework_name}
218 otool -L "$framework_complete_path" | awk '/\t/ {print $1}' | egrep "$dylib_regex" | while read -r dependency_path; do
219 found_name=$(tmp=${dependency_path/*\/}; echo ${tmp/\.*})
220 if [ "$found_name" != "$framework_name" ]
221 then
222 # Change the dependent shared library install name to remove version number and 'dylib' extension:
223 install_name_tool -change "$dependency_path" @rpath/Frameworks/${found_name}.framework/${found_name} "${framework_complete_path}"
224 fi
225 done
226}
227
228ffmpeg_libs="libavcodec libavformat libavutil libswresample libswscale"
229
230for name in $ffmpeg_libs; do
231 create_framework $name
232done
233
234\endcode
235
236\section1 Creating a multiplatform binary framework bundle
237
238An XCFramework bundle is a package that includes frameworks and libraries
239necessary to build for multiple platforms, for example, iOS and iOS simulator.
240To create such a framework, use the \c xcodebuild utility. For example, if
241you have frameworks for iOS and simulator located in \c {~/ffmpeg/installed/arm64}
242and \c {~/ffmpeg/installed/arm64-simulator} directories, the utility arguments look
243like follows:
244
245\badcode
246xcodebuild -create-xcframework -framework ../installed/arm64/libavcodec.framework -framework ../installed/arm64-simulator/libavcodec.framework -output ../installed/framework/libavcodec.xcframework
247\endcode
248
249\section1 Embedding frameworks
250
251Embed the FFmpeg frameworks into an application bundle. For information on how to
252embed frameworks using XCode, refer to
253
254\l{https://developer.apple.com/library/archive/technotes/tn2435/_index.html}{Embedding Frameworks In An App}.
255
256*/