Simon Guest
Simon Guest

Reputation: 2162

Unable to mirror AVCaptureVideoPreviewLayer on macOS

I'm using AVCaptureVideoPreviewLayer (macOS, not iOS) to capture video input from an attached camera. I've setup a capture session and created a UIView to display the image:

self.captureLayer = AVCaptureVideoPreviewLayer(session: self.captureSession); self.playerView.layer = self.captureLayer;

Everything is working fine, and I see the image from the camera, but now I want to mirror the image (vertically). I'm using a CATransform3DMakeScale:

self.captureLayer.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0);

Instead of mirroring the image however, the layer just goes blank (background of the parent view).

I've tried other transforms (e.g. resizes) and they work fine. I've also tried mirroring the superlayer:

self.captureLayer.superLayer?.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0);

And this works (although it mirrors the entire window including the title bar!).

Any help appreciated. I believe the transform is correct, but for some reason it's not applying to a AVCaptureVideoPreviewLayer.

Upvotes: 5

Views: 1429

Answers (2)

macfsr
macfsr

Reputation: 11

Do this for mirroring after adding layer to sublayer (no other sublayer) :

yourview.layer!.sublayers?[0].transform = CATransform3DMakeScale(-1.0, 1.0, 1.0);

Upvotes: 0

manishg
manishg

Reputation: 9818

You can make use of avcaptureconnection properties to do this.

self.cameraLayer = AVCaptureVideoPreviewLayer(session: frontVideoSession)
self.cameraLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill

    if (self.cameraLayer!.connection.isVideoMirroringSupported)
    {
        self.cameraLayer!.connection.automaticallyAdjustsVideoMirroring = false
        self.cameraLayer!.connection.isVideoMirrored = true
    }

You can read more about this at https://developer.apple.com/reference/avfoundation/avcaptureconnection/1389172-isvideomirrored


The isVideoMirrored flag allows you to choose whether you want to mirror the video or not. If it is set to true, it will mirror the video, if it set to false, it will not mirror. In order for you to use this flag, you must set automaticallyAdjustsVideoMirroring flag to false.


Wrote an example code for you https://github.com/manishganvir/mac-camera-mirror-example. Please check the same. Snippet below

do {
         let input = try AVCaptureDeviceInput(device: camDevice)


          VideoSession.addInput(input)

          self.cameraLayer = AVCaptureVideoPreviewLayer(session: VideoSession)
          print(" connection " , self.cameraLayer!.connection.isVideoMirroringSupported , self.cameraLayer!.connection.automaticallyAdjustsVideoMirroring);

          if (self.cameraLayer!.connection.isVideoMirroringSupported)
          {
                 self.cameraLayer!.connection.automaticallyAdjustsVideoMirroring = false
                 self.cameraLayer!.connection.isVideoMirrored = true
          }
          self.cameraLayer!.frame = self.view.bounds

          self.view.layer = self.cameraLayer!
          self.view.wantsLayer = true

          VideoSession.startRunning()
   }

Upvotes: 7

Related Questions