I am trying to compress an AVAsset
to lower quality and then export it as an mp4. The input asset could be any type of video that the camera roll allows.
The problem I am running into is that when I try to export an asset to AVAssetExportPresetMediumQuality
it fails at the first guard statement when the input is a mp4 file originally. However if I change it to AVAssetExportPresetPassthrough
it works but doesn't compress the file. Is there a one way solution to compressing/encoding an asset that could be a .mov or .mp4 originally?
func encodeVideo(asset: AVAsset, completionHandler: @escaping (URL?, String?) -> ()) {
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
completionHandler(nil, nil)
return
}
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
let filePath = documentsDirectory.appendingPathComponent("compressed-video.mp4")
if FileManager.default.fileExists(atPath: filePath.path) {
do {
try FileManager.default.removeItem(at: filePath)
} catch {
completionHandler(nil, nil)
}
}
exportSession.outputURL = filePath
exportSession.outputFileType = .mp4
exportSession.shouldOptimizeForNetworkUse = true
let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
let range = CMTimeRangeMake(start: start, duration: asset.duration)
exportSession.timeRange = range
exportSession.exportAsynchronously {
switch exportSession.status {
case .failed:
print("Conversion Failed")
completionHandler(nil, exportSession.error?.localizedDescription)
case .cancelled:
print("Conversion Cancelled")
completionHandler(nil, exportSession.error?.localizedDescription)
case .completed:
completionHandler(exportSession.outputURL, nil)
default: break
}
}
}