The front facing camera on iPhone 16 (and every model previous) gives the following values for AVCaptureDevice.RotationCoordinator.videoRotationAngleForHorizonLevelCapture:
- 90 degrees portrait
- 180 degrees landscape left
- 270 degrees for upside-down
- 0 degrees for landscape right
Using these values a transform is calculated:
var transform: CGAffineTransform {
let degrees = rotationCoordinator.videoRotationAngleForHorizonLevelCapture
let radians = degrees * .pi / 180.0
return CGAffineTransform(rotationAngle: radians)
}
And then applied to the AVAssetInput:
videoInput = AVAssetWriterInput(mediaType: .video,
outputSettings: videoSettings,
sourceFormatHint: videoFormatDescription)
videoInput.transform = transform
And this ensures the correct transform is added to the metadata so that the recorded video plays in the correct orientation.
However, with the iPhone 17 Pro and iPhone 17 Pro Max front facing cameras, AVCaptureDevice.RotationCoordinator.videoRotationAngleForHorizonLevelCapture return the different values:
- 0 degrees portrait
- 90 degrees landscape left
- 180 degrees for upside-down
- 270 degrees for landscape right
So this approach breaks down, and the video orientation is incorrect. How is this intended to be handled?
Hi there shimanopower, The difference in rotation angle is expected on iPhone 17 due to a different sensor rotation. Looks like your 2nd line in the first code block is not taking into consideration any video rotation already being applied in the AVCaptureConnection to your output.
Here's some sample code:
let videoRotationAngle = self.videoRotationAngle
let videoConnectionVideoRotationAngle = self.videoOutputConnection!.videoRotationAngle
// Subtract how much we should apply (videoRotationAngle) by how much is already applied (videoConnectionVideoRotationAngle)
let rotationAngleToApply = videoRotationAngle - videoConnectionVideoRotationAngle
var videoRotationTransform = CGAffineTransform(rotationAngle: rotationAngleToApply * .pi / 180.0) // Convert from degrees to radians
To achieve best performance, set your video rotation angle on your video data output's connection to 0 — which will result in unrotated video from the source. But be aware that the source might come from a different sensor rotation with respect to the phone.