camera: use videoRotationAngle on macOS 14+ to pin photo to landscape
Setting `videoOrientation = .landscapeRight` had no effect on macOS 14+ — Apple deprecated it in favour of `videoRotationAngle` (a `CGFloat` in degrees) and the old setter is silently ignored in newer versions. The captured JPEG stayed rotated 90° CW even with our previous fix. Try `videoRotationAngle = 0` first (macOS 14+) — that's "no rotation from the sensor's natural orientation", which is landscape on desktop cameras. Fall back to `videoOrientation = .landscapeRight` for macOS 13 and older. Same `applyUxCaptureOrientation` entry point — no caller changes. iOS extension untouched; iOS still uses the per-snapshot `videoOrientation` set (deprecated on iOS 17+ too, but still functions there).
This commit is contained in:
@@ -2,19 +2,26 @@ import AVFoundation
|
|||||||
|
|
||||||
/// macOS counterpart of `AVCaptureConnection+iOS.swift`.
|
/// macOS counterpart of `AVCaptureConnection+iOS.swift`.
|
||||||
///
|
///
|
||||||
/// macOS desktop cameras are physically fixed landscape. AVFoundation
|
/// macOS desktop cameras are physically fixed landscape, but
|
||||||
/// initialises `connection.videoOrientation` to `.portrait` by
|
/// `AVCapturePhotoOutput`'s connection defaults to a setting that
|
||||||
/// default though — same as iOS — which on macOS *also* rotates the
|
/// rotates the captured JPEG 90° CW. We pin the connection to
|
||||||
/// sensor frame 90° CW (manifested as a 90° CW selfie photo + a
|
/// landscape (or 0° rotation, depending on the available API) so
|
||||||
/// rotated preview). So we *do* set the orientation on macOS, but
|
/// the JPEG matches what the preview shows.
|
||||||
/// pin it to `.landscapeRight` regardless of the snapshot Flutter
|
///
|
||||||
/// passes (which is always `portraitUp` on macOS — desktops don't
|
/// `videoOrientation` was deprecated in macOS 14 / iOS 17 in favour
|
||||||
/// rotate). That tells AVFoundation "leave the sensor frame alone";
|
/// of `videoRotationAngle` (a `CGFloat` in degrees). On macOS 14+
|
||||||
/// captured JPEG ends up landscape with EXIF orientation = 1 (no
|
/// `videoOrientation` may be silently ignored — that's exactly the
|
||||||
/// rotation), and preview data-output buffers flow at the sensor's
|
/// symptom we hit ("photo still rotated 90° CW even after setting
|
||||||
/// native aspect.
|
/// videoOrientation = .landscapeRight"). Prefer the new API where
|
||||||
|
/// available, fall back to the deprecated one for older macOS.
|
||||||
extension AVCaptureConnection {
|
extension AVCaptureConnection {
|
||||||
func applyUxCaptureOrientation(_ orientation: DeviceOrientationFlutter) {
|
func applyUxCaptureOrientation(_ orientation: DeviceOrientationFlutter) {
|
||||||
|
if #available(macOS 14.0, *) {
|
||||||
|
if isVideoRotationAngleSupported(0) {
|
||||||
|
videoRotationAngle = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
if isVideoOrientationSupported {
|
if isVideoOrientationSupported {
|
||||||
videoOrientation = .landscapeRight
|
videoOrientation = .landscapeRight
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user