How to Add Live Camera Preview to UIView

前端 未结 5 484
温柔的废话
温柔的废话 2020-12-04 16:45

I run into a problem, I\'m trying to solve within UIView boundary, is there any way to Add Camera Preview to UIView? And Add other content on top of The UIView (Buttons, Lab

5条回答
  •  孤城傲影
    2020-12-04 17:38

    Swift 4

    Condensed version of mauricioconde's solution

    You can use this as a drop in component:

    //
    //  CameraView.swift
    
    import Foundation
    import AVFoundation
    import UIKit
    
    final class CameraView: UIView {
    
        private lazy var videoDataOutput: AVCaptureVideoDataOutput = {
            let v = AVCaptureVideoDataOutput()
            v.alwaysDiscardsLateVideoFrames = true
            v.setSampleBufferDelegate(self, queue: videoDataOutputQueue)
            v.connection(with: .video)?.isEnabled = true
            return v
        }()
    
        private let videoDataOutputQueue: DispatchQueue = DispatchQueue(label: "JKVideoDataOutputQueue")
        private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
            let l = AVCaptureVideoPreviewLayer(session: session)
            l.videoGravity = .resizeAspect
            return l
        }()
    
        private let captureDevice: AVCaptureDevice? = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
        private lazy var session: AVCaptureSession = {
            let s = AVCaptureSession()
            s.sessionPreset = .vga640x480
            return s
        }()
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            commonInit()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            commonInit()
        }
    
        private func commonInit() {
            contentMode = .scaleAspectFit
            beginSession()
        }
    
        private func beginSession() {
            do {
                guard let captureDevice = captureDevice else {
                    fatalError("Camera doesn't work on the simulator! You have to test this on an actual device!")
                }
                let deviceInput = try AVCaptureDeviceInput(device: captureDevice)
                if session.canAddInput(deviceInput) {
                    session.addInput(deviceInput)
                }
    
                if session.canAddOutput(videoDataOutput) {
                    session.addOutput(videoDataOutput)
                }
                layer.masksToBounds = true
                layer.addSublayer(previewLayer)
                previewLayer.frame = bounds
                session.startRunning()
            } catch let error {
                debugPrint("\(self.self): \(#function) line: \(#line).  \(error.localizedDescription)")
            }
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
            previewLayer.frame = bounds
        }
    }
    
    extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate {}
    

提交回复
热议问题