更改视频方向时,AVFoundation视频预览层口吃

问题描述

为捕获会话(AVCaptureVideoOrientation)更改视频输出AVCaptureVideoDataOutput)的视频方向(AVCaptureSession)时,预览层(AVCaptureVideoPreviewLayer)将闪烁/抖动/停顿/掉帧片刻。

我在做错什么吗?这是一个重现问题的最小示例。

class CameraviewController: UIViewController {
    
    private let session = AVCaptureSession()
    private var output: AVCaptureVideoDataOutput!
    private var preview: AVCaptureVideoPreviewLayer!

    override func viewDidLoad() {
        AVCaptureDevice.requestAccess(for: .video) { _ in }

        session.beginConfiguration()

        let discovery = AVCaptureDevice.discoverySession(deviceTypes: [.builtInWideAngleCamera],mediaType: .video,position: .back)
        let device = discovery.devices.first!
        let input = try! AVCaptureDeviceInput(device: device)
        session.addInput(input)

        output = AVCaptureVideoDataOutput()
        session.addOutput(output)

        session.commitConfiguration()
        session.startRunning()

        preview = AVCaptureVideoPreviewLayer(session: session)
        view.layer.addSublayer(preview)

        NotificationCenter.default.addobserver(self,selector: #selector(handleOrientationChange),name: UIDevice.orientationDidChangeNotification,object: nil)
    }

    @objc private func handleOrientationChange() {
        let deviceOrientation = UIDevice.current.orientation
        
        let videoOrientation: AVCaptureVideoOrientation?
        switch deviceOrientation {
        case .portrait:
            videoOrientation = .portrait
        case .landscapeRight:
            videoOrientation = .landscapeLeft
        case .landscapeLeft:
            videoOrientation = .landscapeRight
        case .portraitUpsideDown:
            videoOrientation = .portraitUpsideDown
        default:
            videoOrientation = nil
        }

        if let videoOrientation = videoOrientation {
            output.connection(with: .video)!.videoOrientation = videoOrientation
        }
    }
    
    override var shouldAutorotate: Bool {
        false
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        preview.frame = view.bounds
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)