AVCaptureVideoPreviewLayer, wrong orientation

Viewed 351

I'm attempting to rotate AVCaptureVideoPreviewLayer according to the device's orientation.

  1. In portrait mode, it works fine.

  2. However, in landscape it looks like this: 1

  3. I have tried rotating the UIView around AVCaptureVideoPreviewLayer but I don't want to take this approach since it crops the edges.

  4. I have also tried setting it manually. However, connection seems to be nill when unwrapped and there is no change to AVCaptureVideoOrientation's orientation.

    camera.preview.connection?.videoOrientation = AVCaptureVideoOrientation.landscapeRight

How do I make sure that AVCaptureVideoPreviewLayer corresponds with the orientation of the device?

Here is the code:

class CameraModel: NSObject, ObservableObject, AVCapturePhotoCaptureDelegate {
    
    @Published var session = AVCaptureSession()
    
    // since were going to read pic data...
    @Published var output = AVCapturePhotoOutput()
    
    // preview
    @Published var preview : AVCaptureVideoPreviewLayer!
    
    func setUp() {
        
        // setting up camera...
        
        do {
            
            // setting configs...
            self.session.beginConfiguration()
            
            // change for your own
            
            let device = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
            
            let input = try AVCaptureDeviceInput(device: device!)
            
            // checking and adding to session...
            
            if self.session.canAddInput(input) {
                self.session.addInput(input)
            }
            
            // same for output...
            
            if self.session.canAddOutput(self.output) {
                self.session.addOutput(self.output)
            }
            
            self.session.commitConfiguration()
        }
        catch {
            print(error.localizedDescription)
        }
    }
    
}

struct CameraPreview: UIViewRepresentable {
    
    @ObservedObject var camera: CameraModel
    
    func makeUIView(context: Context) -> UIView {
        
        let view = UIView(frame: UIScreen.main.bounds)
        
        camera.preview = AVCaptureVideoPreviewLayer(session: camera.session)
        camera.preview.frame = view.frame

        // Your Own Properties
        camera.preview.videoGravity = .resizeAspectFill
        view.layer.addSublayer(camera.preview)
        
        // starting session
        camera.session.startRunning()
        
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        
    }
    
}
1 Answers

Update to landscape mode in UpdateUIView -

    func updateUIView(_ uiView: UIViewType, context: Context) {
        camera.preview.connection?.videoOrientation = .landscapeRight
    }
Related