微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决更改视频方向时,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 举报,一经查实,本站将立刻删除。