AVMediaTypeVideo captura la orientación de la image fija

He visto otras casi respuestas a esta pregunta, pero parece que no pueden hacerlo funcionar. Estoy capturando una image de AVMediaTypeVideo y su orientación es siempre UIImageOrientation 3 (no sé qué significa eso en realidad).

He intentado corregirlo usando la orientación de la barra de estado pero eso no parece tener ningún efecto. No necesito save estas imágenes en el rollo de la camera, solo está allí para verificar. No estoy seguro si eso tiene algún efecto sobre la orientación también.

import UIKit import AVFoundation class ViewController: UIViewController { let captureSession = AVCaptureSession() let stillImageOutput = AVCaptureStillImageOutput() var avCaptureVideoPreview : AVCaptureVideoPreviewLayer? var error: NSError? override func viewDidLoad() { super.viewDidLoad() let devices = AVCaptureDevice.devices().filter{ $0.hasMediaType(AVMediaTypeVideo) } if let captureDevice = devices.first as? AVCaptureDevice { captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &error)) captureSession.sessionPreset = AVCaptureSessionPresetMedium captureSession.startRunning() stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG] if captureSession.canAddOutput(stillImageOutput) { captureSession.addOutput(stillImageOutput) } avCaptureVideoPreview = AVCaptureVideoPreviewLayer(session: captureSession) if let previewLayer = avCaptureVideoPreview { previewLayer.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height) previewLayer.position = CGPointMake(view.bounds.midX, view.bounds.midY) previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill let cameraPreview = UIView(frame: CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height)) cameraPreview.layer.addSublayer(previewLayer) cameraPreview.addGestureRecognizer(UITapGestureRecognizer(target: self, action:"saveToCamera:")) view.addSubview(cameraPreview) } } // Add a selfie button if device is capable for device in devices { if device.position == AVCaptureDevicePosition.Front { // Add selfie button println("selfie capable") } } } override func viewWillLayoutSubviews() { if avCaptureVideoPreview != nil { // Orientation if (avCaptureVideoPreview!.connection.supportsVideoOrientation == true) { avCaptureVideoPreview!.connection.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.shanetworkingApplication().statusBarOrientation) } // Frame avCaptureVideoPreview!.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height) avCaptureVideoPreview!.position = CGPointMake(view.bounds.midX, view.bounds.midY) avCaptureVideoPreview!.videoGravity = AVLayerVideoGravityResizeAspectFill } } func interfaceOrientationToVideoOrientation(orientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation { switch orientation { case UIInterfaceOrientation.Portrait: return AVCaptureVideoOrientation.Portrait case UIInterfaceOrientation.PortraitUpsideDown: return AVCaptureVideoOrientation.PortraitUpsideDown case UIInterfaceOrientation.LandscapeLeft: return AVCaptureVideoOrientation.LandscapeLeft case UIInterfaceOrientation.LandscapeRight: return AVCaptureVideoOrientation.LandscapeRight default: return AVCaptureVideoOrientation.Portrait } } func saveToCamera(sender: UITapGestureRecognizer) { if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) { stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) { (imageDataSampleBuffer, error) -> Void in var image = UIImage(data: AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)) // this is not working var orientation : UIImageOrientation? switch UIApplication.shanetworkingApplication().statusBarOrientation.rawValue { case 1: orientation = UIImageOrientation.Up case 3: orientation = UIImageOrientation.Left case 4: orientation = UIImageOrientation.Right default: orientation = UIImageOrientation.Up } let newImage = UIImage(CGImage: image?.CGImage, scale: 1.0, orientation: orientation!) UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil) } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } 

Edición, esto no funciona para las fotos capturadas con la camera frontal, aparecen bien en la aplicación de fotos nativas, pero no cuando se comparten en Fotos en Mac o se cargan desde parse.com.

Gracias a la respuesta de @XJones aquí ¿Por qué los modos de paisaje AVCaptureVideoOrientation resultan en imágenes fijas al revés?

 import UIKit import AVFoundation class ViewController: UIViewController { let captureSession = AVCaptureSession() let stillImageOutput = AVCaptureStillImageOutput() var avCaptureVideoPreview : AVCaptureVideoPreviewLayer? var error: NSError? override func viewDidLoad() { super.viewDidLoad() let devices = AVCaptureDevice.devices().filter{ $0.hasMediaType(AVMediaTypeVideo) } if let captureDevice = devices.first as? AVCaptureDevice { captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &error)) captureSession.sessionPreset = AVCaptureSessionPresetMedium captureSession.startRunning() stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG] if captureSession.canAddOutput(stillImageOutput) { captureSession.addOutput(stillImageOutput) } avCaptureVideoPreview = AVCaptureVideoPreviewLayer(session: captureSession) if let previewLayer = avCaptureVideoPreview { previewLayer.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height) previewLayer.position = CGPointMake(view.bounds.midX, view.bounds.midY) previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill let cameraPreview = UIView(frame: CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height)) cameraPreview.layer.addSublayer(previewLayer) cameraPreview.addGestureRecognizer(UITapGestureRecognizer(target: self, action:"saveToCamera:")) view.addSubview(cameraPreview) } } // Add a selfie button if device is capable for device in devices { if device.position == AVCaptureDevicePosition.Front { // Add selfie button println("selfie capable") } } } override func viewWillLayoutSubviews() { if avCaptureVideoPreview != nil { // Orientation if (avCaptureVideoPreview!.connection.supportsVideoOrientation == true) { var newOrientation : AVCaptureVideoOrientation? switch UIDevice.currentDevice().orientation { case UIDeviceOrientation.Portrait: newOrientation = AVCaptureVideoOrientation.Portrait case UIDeviceOrientation.PortraitUpsideDown: newOrientation = AVCaptureVideoOrientation.PortraitUpsideDown case UIDeviceOrientation.LandscapeLeft: newOrientation = AVCaptureVideoOrientation.LandscapeRight; case UIDeviceOrientation.LandscapeRight: newOrientation = AVCaptureVideoOrientation.LandscapeLeft default: newOrientation = AVCaptureVideoOrientation.Portrait } avCaptureVideoPreview!.connection.videoOrientation = newOrientation! } // Frame avCaptureVideoPreview!.bounds = CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height) avCaptureVideoPreview!.position = CGPointMake(view.bounds.midX, view.bounds.midY) avCaptureVideoPreview!.videoGravity = AVLayerVideoGravityResizeAspectFill } } func saveToCamera(sender: UITapGestureRecognizer) { if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) { stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) { (imageDataSampleBuffer, error) -> Void in var image = UIImage(data: AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)) var imageOrientation : UIImageOrientation? switch UIDevice.currentDevice().orientation { case UIDeviceOrientation.PortraitUpsideDown: imageOrientation = UIImageOrientation.Left case UIDeviceOrientation.LandscapeRight: imageOrientation = UIImageOrientation.Down case UIDeviceOrientation.LandscapeLeft: imageOrientation = UIImageOrientation.Up case UIDeviceOrientation.Portrait: imageOrientation = UIImageOrientation.Right default: imageOrientation = UIImageOrientation.Right } var newImage = UIImage(CGImage: image!.CGImage, scale: 1.0, orientation: imageOrientation!) UIImageWriteToSavedPhotosAlbum(newImage!, nil, nil, nil) } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }