This fork builds FFmpegKit for iOS and macOS with a Swift API and a minimal C bridge to FFmpeg.
- Swift Package provides the public API (
Sources/) Frameworks/ships XCFrameworks;Package.swiftlinks them automatically — no manual framework dragging in Xcode- Build scripts can rebuild native libraries and refresh
Frameworks/
- iOS device:
arm64 - iOS simulator:
arm64,x86_64 - macOS:
arm64,x86_64
Mac Catalyst, tvOS, Android, Linux, Flutter and React Native are not included.
The public API keeps the original FFmpegKit class names and method style, including FFmpegKit, FFprobeKit, sessions, callbacks, logs, statistics, cancellation and media information. The previous Objective-C implementation has been removed.
- macOS with Xcode and the Xcode command-line tools
autoconf,automake,libtool,pkg-config,curl,git,cmake,nasmmesonwhen using--fullbuilds- Network access for downloading FFmpeg and optional library sources
Run every command from the repository root.
Add this repository as a Swift Package dependency. The eight XCFrameworks in Frameworks/ are linked automatically.
import ffmpegkit
let session = FFmpegKit.execute("-i input.mp4 output.mov")
if ReturnCode.isSuccess(session.getReturnCode()) {
print(session.getOutput())
}
FFmpegKit.executeAsync("-i input.mp4 output.mov") { session in
print(session.getReturnCode() as Any)
}
let information = FFprobeKit.getMediaInformation("input.mp4").getMediaInformation()Validate the Swift API:
swift testRebuild when you change native C code in apple/src/, upgrade FFmpeg, or enable optional codecs. Sync the output into Frameworks/ and commit.
./ios.sh → prebuilt/bundle-apple-xcframework-ios/
./macos.sh → prebuilt/bundle-apple-xcframework-macos/
./apple.sh → prebuilt/bundle-apple-xcframework/
↓
copy to Frameworks/ → commit
./tools/clean.shRemoves prebuilt/, .tmp/, src/*, build.log, and compile artifacts. Does not affect Sources/ or Frameworks/.
Default build (FFmpeg core only, LGPL):
./ios.sh
./macos.sh
./apple.shFull build (all optional libraries including GPL codecs; iOS and macOS must use matching external-library flags):
./ios.sh --full --enable-gpl
./macos.sh --full --enable-gpl
./apple.shSee ./ios.sh --help and ./macos.sh --help for more options.
cp -R prebuilt/bundle-apple-xcframework/*.xcframework Frameworks/Expect eight xcframeworks: ffmpegkit, libavcodec, libavdevice, libavfilter, libavformat, libavutil, libswresample, libswscale.
swift build && swift test
git add Frameworks/
git commit -m "Update XCFrameworks after native rebuild"./ios.sh && ./macos.sh && ./apple.sh && \
cp -R prebuilt/bundle-apple-xcframework/*.xcframework Frameworks/ && \
swift build && swift test| Question | Answer |
|---|---|
./apple.sh fails to find frameworks |
Ensure ios.sh and macos.sh both succeeded with matching library options |
| Update a single library only | Not supported; rerun the full three-step build |
What is src/? |
Downloaded FFmpeg and dependency sources during build; safe to delete |
prebuilt/ vs Frameworks/ |
prebuilt/ is local build output (gitignored); Frameworks/ is committed for SPM |
Changed apple/src/*.c |
Rerun steps 2–4 |
| Apple built-in flags | Use --enable-macos-* on macOS and --enable-ios-* on iOS; do not mix prefixes |
Use this when shipping both iOS and macOS video or audio conversion apps. Enables x264 (H.264 software encoding), common audio codecs via --full (lame, opus, vorbis, etc.), and Apple hardware acceleration (VideoToolbox).
| Category | Build flags | Typical usage |
|---|---|---|
| H.264 software encode | --enable-gpl --enable-x264 |
-c:v libx264 |
| H.264 hardware encode/decode | --enable-*-videotoolbox |
-c:v h264_videotoolbox |
| MP3 / Opus / Vorbis, etc. | --full (includes lame, opus, libvorbis, etc.) |
-c:a libmp3lame, -c:a libopus |
| WebP encode/decode | --enable-libwebp (pulls giflib/jpeg/libpng/tiff) |
-c:v libwebp, output.webp |
| System audio/video I/O | --enable-*-audiotoolbox, --enable-*-avfoundation |
Microphone, camera, system audio |
--enable-macos-coreimage,--enable-macos-opencl, and--enable-macos-openglare macOS-only and optional. iOS has no matching flags.
Run from the repository root:
# 1. Optional: clean previous artifacts
./tools/clean.sh
# 2. Build macOS
./macos.sh \
--enable-macos-videotoolbox \
--enable-macos-avfoundation \
--enable-macos-audiotoolbox \
--enable-macos-bzip2 \
--enable-macos-zlib \
--enable-macos-libiconv \
--enable-libvorbis \
--enable-libtheora \
--enable-libwebp \
--enable-opus \
--enable-opencore-amr \
--enable-libvpx \
--enable-speex \
--enable-lame \
--enable-gpl --enable-x264
# 3. Build iOS (same external-library flags; use ios-* for Apple built-ins)
./ios.sh --full --enable-gpl --enable-x264 \
--enable-ios-videotoolbox \
--enable-ios-audiotoolbox \
--enable-ios-avfoundation \
--enable-ios-bzip2 \
--enable-ios-zlib \
--enable-ios-libiconv \
--enable-libvorbis \
--enable-libtheora \
--enable-libwebp \
--enable-opus \
--enable-opencore-amr \
--enable-libvpx \
--enable-speex \
--enable-lame
# 4. Merge into universal XCFrameworks
./apple.sh
# 5. Sync into the SPM directory
cp -R prebuilt/bundle-apple-xcframework/*.xcframework Frameworks/
# 6. Verify
swift build && swift test
# 7. Commit (if updating binaries in the repo)
git add Frameworks/
git commit -m "Update XCFrameworks for video/audio conversion (full + GPL + x264)"The iOS build is usually the longest step (often 1–3+ hours). Keep network access available.
Video to H.264 (software):
FFmpegKit.execute("-i input.mov -c:v libx264 -preset medium -crf 23 -c:a aac output.mp4")Video to H.264 (hardware):
FFmpegKit.execute("-i input.mov -c:v h264_videotoolbox -b:v 5M -c:a aac output.mp4")Audio to MP3:
FFmpegKit.execute("-i input.wav -c:a libmp3lame -b:a 192k output.mp3")Audio to Opus:
FFmpegKit.execute("-i input.wav -c:a libopus -b:a 128k output.opus")Image / frame to WebP:
// Lossy WebP
FFmpegKit.execute("-i input.png -c:v libwebp -quality 80 output.webp")
// Lossless WebP
FFmpegKit.execute("-i input.png -c:v libwebp -lossless 1 output.webp")
// Animated WebP
FFmpegKit.execute("-i input.gif -c:v libwebp -quality 75 -loop 0 output.webp")Remux only (no re-encode, fastest):
FFmpegKit.execute("-i input.mkv -c copy output.mp4")- Add this repository as a Swift Package dependency in both your video and audio conversion apps (same
Frameworks/) import ffmpegkit— no manual XCFramework linking- After updating
Frameworks/, Reset Package Caches in Xcode or bump the dependency
With --enable-gpl and x264 enabled, app distribution must comply with GPL (typically requiring source disclosure or GPL-compliant distribution). If one app cannot accept GPL, build a separate variant without --enable-gpl --enable-x264.
ffmpeg-kit/
├── Package.swift # Swift Package (with binaryTarget)
├── Frameworks/ # Committed XCFrameworks (~70MB+; larger with full builds)
├── README.md / README.zh.md # English / Chinese docs
├── LICENSE
├── ios.sh / macos.sh / apple.sh
│
├── Sources/ # Swift Package source
├── Tests/ # Unit tests
├── apple/ # Native C core (fftools + runtime)
├── scripts/ # Build scripts
├── tools/ # Build helpers
│
├── src/ # Downloaded third-party sources (not committed)
└── prebuilt/ # Local build output (not committed)
| File | Purpose |
|---|---|
Package.swift |
Defines ffmpegkit and CFFmpegBridge; references Frameworks/ via binaryTarget |
ios.sh |
iOS build entry (arm64 device + simulators) |
macos.sh |
macOS build entry (arm64 + x86_64) |
apple.sh |
Merges iOS + macOS into universal XCFrameworks |
.gitignore |
Ignores .build/, .tmp/, prebuilt/, src/*, etc. |
| File | Purpose |
|---|---|
FFmpegKit.swift |
FFmpeg execution: execute, executeAsync, cancel |
FFprobeKit.swift |
FFprobe execution and media information |
FFmpegKitConfig.swift |
Global config, log redirection, session management |
Session.swift |
Session protocol; FFmpegSession, FFprobeSession |
Execution.swift |
Native execution backend |
MediaInformation.swift |
Media info parsing |
Types.swift |
ReturnCode, Log, Statistics, etc. |
Support.swift |
Internal helpers |
CFFmpegBridge/ |
C bridge; calls native symbols via dlsym |
| File | Purpose |
|---|---|
ffmpegkit_runtime.c |
Runtime: session ID, cancel, signal handling, log forwarding |
ffmpegkit_exception.h |
longjmp exception handling |
fftools_ffmpeg.c |
Exports ffmpeg_execute() |
fftools_ffprobe.c |
Exports ffprobe_execute() |
fftools_*.c |
FFmpeg command-line tool sources |
| XCFramework | Purpose |
|---|---|
ffmpegkit.xcframework |
FFmpeg/FFprobe command core |
libavcodec.xcframework |
Codecs |
libavformat.xcframework |
Container formats |
libavutil.xcframework |
Utilities |
libavfilter.xcframework |
Filters |
libavdevice.xcframework |
Device I/O |
libswresample.xcframework |
Audio resampling |
libswscale.xcframework |
Image scaling |
Each XCFramework contains three slices: ios-arm64, ios-arm64_x86_64-simulator, macos-arm64_x86_64.
| File | Purpose |
|---|---|
variable.sh / function.sh |
Global variables and shared functions |
function-ios.sh / function-macos.sh |
Platform-specific compile settings |
main-ios.sh / main-macos.sh |
Per-architecture build pipeline |
source.sh |
Git repos and versions for each library |
apple/*.sh |
Per-library build scripts (ffmpeg.sh, x264.sh, etc.) |
| Path | Purpose |
|---|---|
clean.sh |
Remove build artifacts |
apple/strip-frameworks.sh |
Xcode script to strip extra architectures |
license/, source/ |
GPL compliance files |
patch/ |
Build patches for third-party libraries on Apple platforms |
src/: Downloaded FFmpeg and dependency sources during build; not committedprebuilt/: Local build intermediates and output; not committed — copy toFrameworks/before committing
Swift API → FFmpegKitConfig / Execution → CFFmpegBridge (dlsym)
→ libffmpegkit (ffmpeg_execute) → FFmpeg XCFrameworks
./tools/clean.shFFmpegKit is licensed under LGPL 3.0 by default. Enabling GPL libraries (e.g. x264 via --enable-gpl) changes distribution requirements. See LICENSE and the licenses of enabled dependencies before distribution.