iPhone Xs Max: AVCaptureVideoPreviewLayer when add

2019-08-27 20:03发布

问题:

I am trying to build a custom camera using a single view application with the new iPhone Xs Max. With reference to the screenshot below, it can be seen that the video output displayed in AVCaptureVideoPreviewLayer occupies less than the safe area of the screen on the iPhone x. How do I calculate the space that has not been occupied?

How do I know that the AVCaptureVideoPreviewLayer occupies less than the safe area? Well, the top border of the top 'Button' is anchored to the top border of the safe area. The bottom button is similarly anchored to the bottom of the bottom safe area. Yet there is huge overlap!

Problem:

The layout of single view application: Button top constraint

Bottom white button bottom constraint:

All other layout constraints:

SWIFT:

class ViewController: UIViewController, UIImagePickerControllerDelegate, AVCaptureVideoDataOutputSampleBufferDelegate  {

var previewLayer = AVCaptureVideoPreviewLayer.init()
var captureSession: AVCaptureSession!
var previewFrame = CGRect.init()
var safeAreaFrame: CGRect = CGRect.init()



override func viewDidLoad() {
    super.viewDidLoad()

      let screenSize = UIScreen.main.bounds
      // This is (0.0, 0.0, 414.0, 896.0)

      startAVCaptureSession()

}



override func viewDidLayoutSubviews() {
    print("viewDidLayoutSubviews ...")

    let sAreaFrame = UIApplication.shared.windows[0].safeAreaLayoutGuide.layoutFrame
    self.safeAreaFrame = sAreaFrame

    // self.safeAreaFrame - This is (0.0, 44.0, 414.0, 818.0)


    self.previewLayer.frame = view.bounds // // I have tried  self.previewLayer.frame = self.safeAreaFrame 
    self.previewFrame = previewLayer.frame
}




func startAVCaptureSession() {
    print("START CAPTURE SESSION!!")

    // Setting Up a Capture Session
    self.captureSession = AVCaptureSession()
    captureSession.beginConfiguration()

    // Configure input
    let videoDevice = AVCaptureDevice.default(for: .video)

    guard
        let videoDeviceInput = try? AVCaptureDeviceInput.init(device: videoDevice!) as AVCaptureInput,
        self.captureSession.canAddInput(videoDeviceInput)else {return}

    self.captureSession.addInput(videoDeviceInput)

    // Capture video output
    let videoOutput = AVCaptureVideoDataOutput.init()
    guard self.captureSession.canAddOutput(videoOutput) else {return}
    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.init(label: "videoQueue"))
    self.captureSession.addOutput(videoOutput)


    // start
    self.captureSession.commitConfiguration()
    self.captureSession.startRunning()


    // Display camera preview
    self.previewLayer = AVCaptureVideoPreviewLayer.init(session: self.captureSession)

    // Use 'insertSublayer' to enable button to be viewable
    view.layer.insertSublayer(self.previewLayer, at: 0)



}





}

PROJCT LINK: https://github.com/babylon123/RectangleCapture