如何在Swift开发的iOS应用中集成使用FFmpeg
Swift iOS环境下接入FFmpeg可行方案
首选方案:ffmpeg-kit + OC桥接(稳定性最高、集成成本最低)
ffmpeg-kit仅提供OC API的问题,通过Swift原生的OC桥接能力即可零额外成本解决,不需要写大量封装代码,具体操作:
- 依赖集成:支持CocoaPods、Swift Package Manager、手动导入框架三种集成方式,根据需求选择对应编解码器版本即可。例如需要全量编解码能力,在Podfile中添加
pod 'ffmpeg-kit-ios-full'后执行pod install完成集成。闭源商业应用注意选择LGPL许可的构建版本,规避App Store审核及版权风险。 - 桥接配置:Xcode项目中新建OC头文件,命名规则为
[项目名]-Bridging-Header.h,在项目Build Settings的Objective-C Bridging Header配置项中填入该文件的相对路径,随后在头文件中引入ffmpeg-kit核心头文件:
#import <FFmpegKit/FFmpegKit.h> #import <FFmpegKit/FFprobeKit.h> #import <FFmpegKit/ReturnCode.h>
- 接口调用:桥接完成后所有ffmpeg-kit接口可直接在Swift代码中调用,完全支持自定义FFmpeg命令执行,示例代码:
// 沙盒路径拼接注意必须使用绝对路径 let docPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] let inputURL = URL(fileURLWithPath: docPath).appendingPathComponent("input.mp4") let outputURL = URL(fileURLWithPath: docPath).appendingPathComponent("output.mp4") let command = "-i \(inputURL.path) -c:v h264_videotoolbox -b:v 2M \(outputURL.path)" // 异步执行命令,避免阻塞主线程 FFmpegKit.executeAsync(command) { session in guard let code = session?.getReturnCode() else { return } switch code { case let c where ReturnCode.isSuccess(c): // 执行成功逻辑 break case let c where ReturnCode.isCancel(c): // 任务取消逻辑 break default: // 执行失败,可通过session?.getAllLogs()获取全量日志排查问题 break } }
避坑提示:禁止在主线程调用同步执行方法
FFmpegKit.execute(),会直接卡住UI;所有传入命令的文件路径必须传沙盒绝对路径,相对路径会触发文件读写失败。
次选方案:适配iOS平台的SwiftFFmpeg(适合纯Swift技术栈需求)
SwiftFFmpeg实际是支持iOS运行的,之前无法运行是因为缺少系统依赖配置:
- 集成后在Target的「Link Binary With Libraries」中手动添加依赖库:
libz.tbd、libbz2.tbd、libiconv.tbd,同时添加系统框架CoreMedia、VideoToolbox、AudioToolbox、AVFoundation即可正常编译运行。 - 该库仅封装了FFmpeg底层C接口,没有直接提供自定义命令执行能力,如果需要跑原生FFmpeg命令,可以将FFmpeg源码中
ffmpeg.c的入口函数重命名避免冲突后集成进项目,自行封装命令调用逻辑即可。该方案适配成本较高,需要自行处理编译配置、内存管理问题,仅推荐有深度定制FFmpeg逻辑需求的场景使用。
不推荐方案
- 已停止维护的MobileFFmpeg:在iOS 16+版本存在硬编解码兼容、沙盒权限适配bug,无官方修复,线上故障排查成本极高,不建议使用。
内容的提问来源于stack exchange,提问作者Xavi Font
相关产品推荐
相关产品推荐

