A downloaded video chosen from the Photos App seems to rotate fine but when it is a video that has been taken using the iPhone's native Camera app, the rotation keeps its original portrait position instead of rotating to landscape which the downloaded videos do successfully. It seems that for recorded videos, AVMutableVideoComposition does not seem to transform the video for some reason. The following is my code in Swift 5.
func rotateVideo(completion: @escaping (_ outputURL: URL?) -> Void) {
let asset = AVAsset(url: videoURL)
let track = asset.tracks(withMediaType: AVMediaType.video).first! as AVAssetTrack
let size = track.naturalSize
var transform = track.preferredTransform
transform = transform.translatedBy(x: size.height, y: 0)
transform = transform.rotated(by: .pi / 2)
let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: track)
transformer.setTransform(transform, at: .zero)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(start: .zero, duration: .positiveInfinity)
instruction.layerInstructions = [transformer]
let composition = AVMutableVideoComposition()
composition.frameDuration = CMTime(value: 1, timescale: 30)
var newWidth = Int(size.height)
var newHeight = Int(size.width)
if (newWidth % 2 != 0) {
newWidth = newWidth + 1
}
if (newHeight % 2 != 0) {
newHeight = newHeight + 1
}
composition.renderSize = CGSize(width: newWidth, height: newHeight)
composition.instructions = [instruction]
exportAsset(asset: asset, videoComposition: composition, filename: "rotate", completion: completion)
}
func exportAsset(asset: AVAsset, videoComposition: AVVideoComposition, filename: String, completion: @escaping (_ outputURL: URL) -> Void) {
let outputURL = URL(fileURLWithPath: NSHomeDirectory() + "/Documents/\(filename).mp4")
let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality)!
exporter.videoComposition = videoComposition
exporter.outputFileType = AVFileType.mov
exporter.outputURL = outputURL
do {
try FileManager.default.removeItem(at: outputURL)
} catch {
print("Failed to delete file at \(outputURL)")
}
exporter.exportAsynchronously(completionHandler: { () -> Void in
DispatchQueue.main.async(execute: {
completion(outputURL)
})
})
}
Read more here: https://stackoverflow.com/questions/66271754/avmutablevideocomposition-fails-to-rotate-video-recorded-using-ios-camera-in-swi
Content Attribution
This content was originally published by Purple Lights at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.