Swift 5 version of @MilanPatel answer, that i found very useful :
func splitSecondVideo() {
guard did<splitdivide else {return}
guard let videourl = URL(string: "YOUR_VIDEO_URL_HERE") else {return}
let asset = AVURLAsset(url: videourl, options: nil)
let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality)
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).map(\.path)
let documentsDirectory = paths[0]
var myPathDocs: String?
var starttime: CMTime
var duration: CMTime
myPathDocs = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("SplitFinalVideo\(did).mov").path
let endt = CMTimeGetSeconds(asset.duration)
print("All Duration : \(endt)")
let divide = CMTimeGetSeconds(asset.duration) / splitdivide
print("All Duration : \(divide)")
starttime = CMTimeMakeWithSeconds(Float64(divide * did), preferredTimescale: 1)
duration = CMTimeMakeWithSeconds(Float64(divide), preferredTimescale: 1)
let fileManager = FileManager()
var error: Error?
if fileManager.fileExists(atPath: myPathDocs ?? "") == true {
do {
try fileManager.removeItem(atPath: myPathDocs ?? "")
} catch {
}
}
exportSession?.outputURL = URL(fileURLWithPath: myPathDocs ?? "")
exportSession?.shouldOptimizeForNetworkUse = true
exportSession?.outputFileType = .mov
// Trim to half duration
let secondrange = CMTimeRangeMake(start: starttime, duration: duration)
exportSession?.timeRange = secondrange
exportSession?.exportAsynchronously(completionHandler: { [self] in
exportDidFinish(exportSession)
did += 1
self.splitSecondVideo()
})
}
func exportDidFinish(_ session: AVAssetExportSession?) {
if session?.status == .completed {
let outputURL = session?.outputURL
print("Before Exported")
saveVideoAtPath(with: outputURL)
}
}
Another update:
session?.status was always coming failed. To solve this issue,
I added:
asset.resourceLoader.setDelegate(self, queue: .main)
and conform to AVAssetResourceLoaderDelegate protocol and it start working. Thanks to this answer by @panychyk.dima