fileprivate func rotateTrack(for track: AVAssetTrack, orientation: Orientation) -> CGAffineTransform {
let size = track.naturalSize
var transform: CGAffineTransform = .identity
//get scale factor of resized video
var scaleFactor: CGFloat = CGFloat(track.naturalSize.width / track.naturalSize.height)
// get blank Space At Bottom after rotation and scaling
var blankSpaceAtBottom = 0
//update x translation according to scaling factor
var x_translation: CGFloat = 0
//increase y translation according to scaling factor
var y_translation: CGFloat = 0
var defaultRotated = false
if size.width > size.height {
defaultRotated = true
scaleFactor = CGFloat(track.naturalSize.height / track.naturalSize.width)
}
let rotate_90: (CGFloat, CGFloat, CGFloat) = (.pi/2, 0, -size.height)
let rotate_180: (CGFloat, CGFloat, CGFloat) = (.pi, -size.width, -size.height)
let rotate_270: (CGFloat, CGFloat, CGFloat) = ((3 * .pi) / 2, -size.width, 0)
let rotate_360: (CGFloat, CGFloat, CGFloat) = (2 * .pi, 0, 0)
var transformValue: (CGFloat, CGFloat, CGFloat) = (0, 0, 0)
switch orientation {
case .upside:
transformValue = defaultRotated ? rotate_90 : rotate_360
if defaultRotated {
blankSpaceAtBottom = Int(track.naturalSize.height - CGFloat(scaleFactor) * track.naturalSize.width)
x_translation = track.naturalSize.height
y_translation = CGFloat(blankSpaceAtBottom / 2) / scaleFactor
}
scaleFactor = 1
case .left:
transformValue = defaultRotated ? rotate_360 : rotate_270
if defaultRotated {
scaleFactor = 1
} else {
blankSpaceAtBottom = Int(track.naturalSize.height + CGFloat(scaleFactor) * track.naturalSize.width)
x_translation = 0
y_translation = CGFloat(blankSpaceAtBottom / 2) / scaleFactor
}
case .upsideDown:
transformValue = defaultRotated ? rotate_270 : rotate_180
if defaultRotated {
blankSpaceAtBottom = Int(track.naturalSize.height + CGFloat(scaleFactor) * track.naturalSize.width)
x_translation = 0
y_translation = CGFloat(blankSpaceAtBottom / 2) / scaleFactor
} else {
x_translation = track.naturalSize.width
y_translation = track.naturalSize.height
}
scaleFactor = 1
case .right:
transformValue = defaultRotated ? rotate_180 : rotate_90
if defaultRotated {
scaleFactor = 1
x_translation = track.naturalSize.width
y_translation = track.naturalSize.height
} else {
blankSpaceAtBottom = Int(track.naturalSize.height - CGFloat(scaleFactor) * track.naturalSize.width)
x_translation = track.naturalSize.height
y_translation = CGFloat(blankSpaceAtBottom / 2) / scaleFactor
}
}
print(x_translation, y_translation)
transform = applyTransformValue(transformValue.0, transformValue.1, transformValue.2)
let scaleTransform = CGAffineTransform(scaleX: CGFloat(scaleFactor), y: CGFloat(scaleFactor))
let translationTransform = CGAffineTransform(translationX: x_translation, y: CGFloat(y_translation))
var finalTransform = transform.concatenating(translationTransform)
finalTransform = finalTransform.concatenating(scaleTransform)
return finalTransform
}
private func applyTransformValue(_ rotation: CGFloat, _ xValue: CGFloat, _ yValue: CGFloat) -> CGAffineTransform {
var transform: CGAffineTransform = .identity
transform = transform.rotated(by: rotation)
return transform
}