I faced with misunderstanding of preferredTransform property of AVAssetTrack. In my app I am extracting video frames and trying to display them but I don't understand how the frame data is laid out and what means preferredTransform property (if this transform which I must apply to the frame data then image must be displayed correctly but it is not visible at all; if this transform is already applied to the image then overused must return the image back to the normal state but it is also don't work).
In some tutorials I saw this code to fix transform
extension AVAssetTrack {
var orientation: (orientation: UIImage.Orientation, isPortrait: Bool) {
let transform = self.preferredTransform
var assetOrientation = UIImage.Orientation.up
var isPortrait = false
if transform.a == 0 && transform.b == 1.0 && transform.c == -1.0 && transform.d == 0 {
assetOrientation = .right
isPortrait = true
} else if transform.a == 0 && transform.b == -1.0 && transform.c == 1.0 && transform.d == 0 {
assetOrientation = .left
isPortrait = true
} else if transform.a == 1.0 && transform.b == 0 && transform.c == 0 && transform.d == 1.0 {
assetOrientation = .up
} else if transform.a == -1.0 && transform.b == 0 && transform.c == 0 && transform.d == -1.0 {
assetOrientation = .down
}
return (assetOrientation, isPortrait)
}
var fixedVideoTransform: CGAffineTransform {
let videoOrientation = self.orientation
var resultTransform = CGAffineTransform.identity
// Now we need fully discard all video transforms and show video as it was in preview
switch videoOrientation.orientation {
case .down:
let rotationFix = CGAffineTransform.identity.translatedBy(x: videoAssetTrack.naturalSize.width - videoAssetTrack.preferredTransform.tx, y: videoAssetTrack.naturalSize.height - videoAssetTrack.preferredTransform.ty)
resultTransform = videoAssetTrack.preferredTransform.concatenating(rotationFix)
case .right:
let rotationFix = CGAffineTransform.identity.translatedBy(x: videoAssetTrack.naturalSize.height - videoAssetTrack.preferredTransform.tx, y: -videoAssetTrack.preferredTransform.ty)
resultTransform = videoAssetTrack.preferredTransform.concatenating(rotationFix)
case .left:
let rotationFix = CGAffineTransform.identity.translatedBy(x: -videoAssetTrack.preferredTransform.tx, y: videoAssetTrack.naturalSize.width - videoAssetTrack.preferredTransform.ty)
resultTransform = videoAssetTrack.preferredTransform.concatenating(rotationFix)
default:
resultTransform = videoAssetTrack.preferredTransform // default landscape orientation nothing need to do there
}
return resultTransform
}
}
This looks OK but what if video rotation is not equal to 90 180, -90 or -180 degrees.
Thank you for your answers.