iPhone Xs Max:AVCaptureVideoPreviewLayer 添加到 View 的子层时占用的空间小于 iphone x 的安全区域 - 为啥?

Posted

技术标签:

【中文标题】iPhone Xs Max:AVCaptureVideoPreviewLayer 添加到 View 的子层时占用的空间小于 iphone x 的安全区域 - 为啥?【英文标题】:iPhone Xs Max: AVCaptureVideoPreviewLayer when added to sublayer of View occupies less than the safe area of the iphone x - why?iPhone Xs Max:AVCaptureVideoPreviewLayer 添加到 View 的子层时占用的空间小于 iphone x 的安全区域 - 为什么? 【发布时间】:2018-12-01 10:26:41 【问题描述】:

我正在尝试使用带有新 iPhone Xs Max 的单视图应用程序构建自定义相机。参考下面的截图可以看出,在 AVCaptureVideoPreviewLayer 中显示的视频输出占用的空间小于 iPhone x 上屏幕的安全区域。如何计算未被占用的空间?

我怎么知道 AVCaptureVideoPreviewLayer 占用的空间小于安全区域?好吧,顶部“按钮”的顶部边框锚定到安全区域的顶部边框。底部按钮同样固定在底部安全区域的底部。然而有巨大的重叠!

问题:

单视图应用布局:按钮顶部约束

底部白色按钮底部约束:

所有其他布局约束:

斯威夫特:

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)










项目链接: https://github.com/babylon123/RectangleCapture

【问题讨论】:

那么问题出在按钮上,还是只是相机预览部分? 相机预览没有占据整个安全区。我想知道输出预览所占用空间的大小(在安全区域内)或确定安全区域内预览未占用的空间。 所以您只想知道预览中的空间,还是只想将预览调整为您想要的大小? 预览相对于安全区域或超级视图的位置。任何一个。我希望这是有道理的 我认为现在的问题不是UI代码而是视频的分辨率。请注意,相机以某种分辨率捕获视频,并且该分辨率的宽度/高度比(纵横比)与屏幕的纵横比不同。看AVCaptureVideoPreviewLayer.videoGravity。 【参考方案1】:

它与纵横比有关。如果您添加此行,它应该可以工作:

self.previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

【讨论】:

更正它会使视频全屏显示,但在应用后看起来视频看起来有点放大了。如果你可以检查 snapchat 应用程序,它没有放大。你能建议任何其他选择?谢谢

以上是关于iPhone Xs Max:AVCaptureVideoPreviewLayer 添加到 View 的子层时占用的空间小于 iphone x 的安全区域 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章

iOS App Icon启动图尺寸配置适配iPhone XS XR XS Max等

物理尺寸Iphone XS Max和Iphone XR屏幕[重复]

为啥 iPhone XR、XS 和 XS Max 没有将环境图像应用到 ARKit 中的场景?

为啥桌面视图与 iPhone X~iPhone XS Max 的大小不同?

为啥 iPhone XR/Xs Max 不遵守比率约束?

为什么iPhone XR,XS和XS Max不会将环境图像应用到ARKit中的场景?