Very confused on how to export a mov file. Keep getting the error:
Error Domain=AVFoundationErrorDomain Code=-11838 "Operation Stopped
At first I started with AVAssets
but that ended up giving me and some other devs trouble when exporting. So I ended up going down the route of using AVMutableComposition
but that didn't work out for me as well. So now below is the code that I hoped would work but currently doesn't.
The URL points to a Firebase asset.
func exportVideo(_ url: URL) async throws -> URL?{
let fileManager = FileManager.default
let item = AVPlayerItem(url: url)
guard try await item.asset.load(.isExportable) else { return nil }
let videoComp = item.videoComposition
guard let exporter = AVAssetExportSession(asset: item.asset, presetName: AVAssetExportPresetHighestQuality),
exporter.supportedFileTypes.contains(AVFileType.mov) else {
return nil
}
// The location in which we will store the video
guard let outputURL = fileManager.containerURL(
forSecurityApplicationGroupIdentifier: "group.example"
)?.appendingPathComponent(currentOutfit + ".mov") else { return nil }
// Check whether the file exists in cache
guard !fileManager.fileExists(atPath: outputURL.path()) else {
return outputURL
}
// Assign the location in where to save the video
exporter.outputURL = outputURL
// export video to mov
exporter.outputFileType = AVFileType.mov
exporter.shouldOptimizeForNetworkUse = true
exporter.videoComposition = videoComp
do {
if #available(iOS 18, *) {
try await exporter.export(to: outputURL, as: AVFileType.mov)
} else {
exporter.exportAsynchronously(completionHandler: {
print("export Status: \(String(describing: exporter.status))")
print("export Error: \(String(describing: exporter.error))")
})
}
// return the newly saved video url location
return outputURL
} catch {
print("export error: \(error)")
}
return nil
}
Try this approach based on Apple example code Exporting video to alternative formats
Make sure your "...forSecurityApplicationGroupIdentifier: group.example
" is registered
with your Apple Developer account
and setup in your "Signing & Capabilities" -> "App Groups capability"
On macOS Sequoia 15.5, using Xcode 16.4, target iOS-18.5, successfully tested on real iOS device and MacCatalyst.
struct ContentView: View {
let url = URL(string: "https://sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4")!
var body: some View {
Text("Exporting Video…")
.task {
do {
let result = try await exportVideo(url)
print("✅ Exported to: \(String(describing: result))")
} catch {
print("❌ Export failed: \(error)")
}
}
}
func exportVideo(_ url: URL) async throws -> URL? {
let currentOutfit = "exportedfile"
guard let outputURL = FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: "group.example"
)?.appendingPathComponent(currentOutfit + ".mov")
else {
return nil
}
let video = AVURLAsset(url: url)
guard await AVAssetExportSession.compatibility(ofExportPreset:
AVAssetExportPresetHighestQuality,
with: video,
outputFileType: AVFileType.mov) else {
print("The ExportPreset can't export the video to the output file type.")
return nil
}
// Create and configure the export session.
guard let exportSession = AVAssetExportSession(asset: video,
presetName: AVAssetExportPresetHighestQuality) else {
print("Failed to create export session.")
return nil
}
exportSession.outputFileType = AVFileType.mov
exportSession.outputURL = outputURL
// Convert the video to the output file type and export it to the output URL.
await exportSession.export()
return outputURL
}
}