我的相机应用Swift代码中的几个错误

时间:2018-12-11 19:37:04

标签: swift avfoundation avcapturesession initializer avcapturedevice

我正在尝试使用Swift为学校项目在Xcode 10.1上创建相机应用程序。我已经为此工作了一段时间,但仍然有几个错误。

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
    let captureSession = AVCaptureSession()
    var previewLayer:CALayer!

    var captureDevice:AVCaptureDevice?

    var takePhoto = false

    override func viewDidLoad() {
        super.viewDidLoad()
        prepareCamera()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        prepareCamera()
    }

    func prepareCamera() {
        captureSession.sessionPreset = AVCaptureSession.Preset.photo

       if let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.back) {


        //if availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType:AVMediaType.video, position: .back).devices {
            //let captureDevice = availableDevices
            beginSession()
        }
    }

    func beginSession () {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput( device: captureDevice)



            captureSession.addInput(captureDeviceInput)
        } catch {

            print(error.localizedDescription)

        }
        if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {
            self.previewLayer = previewLayer
            self.view.layer.addSublayer(self.previewLayer)
            self.previewLayer.frame = self.view.layer.frame
            captureSession.startRunning()

        let dataOutput = AVCaptureVideoDataOutput()
            dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString): NSNumber(value: kCVPixelFormatType_32BGRA)] as [String : Any]

            dataOutput.alwaysDiscardsLateVideoFrames = true

            if captureSession.canAddOutput(dataOutput) {
                captureSession.addOutput(dataOutput)

            }

            captureSession.commitConfiguration()

            let queue = DispatchQueue(label: "com.sophiaradis.captureQueue")
            dataOutput.setSampleBufferDelegate(self, queue: queue)

        }

    }

    @IBAction func takePhoto(_ sender: Any) {
        takePhoto = true
    }

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

        if takePhoto {
            takePhoto = false

            if let image = self.getImageFromSamplyBuffer(buffer: sampleBuffer){

                let photoVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoVC") as! PhotoViewController

                photoVC.takenPhoto = image

                DispatchQueue.main.async {
                    self.present(photoVC, animated: true, completion: {
                        self.stopCaptureSession()

                    })

                }
            }

        }

    }

    func getImageFromSamplyBuffer (buffer:CMSampleBuffer) -> UIImage? {
        if let pixelBuffer = CMSampleBufferGetImageBuffer(buffer) {
            let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
            let context = CIContext()

            let imageRect = CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer))


            if let image = context.createCGImage(ciImage, from: imageRect) {
                return UIImage(cgImage: image, scale: UIScreen.main.scale, orientation: .right)
            }
        }

        return nil
    }

    func stopCaptureSession () {
        self.captureSession.stopRunning()

        if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
            for input in inputs {
                self.captureSession.removeInput(input)

            }
        }
    }
}

这些代码行中有错误:

if let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes:[AVCaptureDevice.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.back)

此错误表明AVCaptureDevice类型没有成员发现会话。但是当我上网查看时,确实如此。

这些行中还有第二个错误,我无法转换“ AVCaptureDevice”类型的值?到预期的参数类型'AVCaptureDevice'。

func beginSession () {
    do {
        let captureDeviceInput = try AVCaptureDeviceInput( device: captureDevice)

我根本不知道如何解决这个问题。我的下一个错误发生在该行的正下方,在以下几行中

 if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {
    self.previewLayer = previewLayer
    self.view.layer.addSublayer(self.previewLayer)
    self.previewLayer.frame = self.view.layer.frame
    captureSession.startRunning()

这被标记为条件绑定的初始化程序必须具有可选类型,而不是“ AVCaptureVideoPreviewLayer”。

如果您能解决甚至提出建议来解决其中的任何问题,那对我来说意义重大,并能使我真正地度过一年。

1 个答案:

答案 0 :(得分:0)

1-

let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.back)

2-如果让captureDevice或强制解开captureDevice!

let captureDeviceInput = try AVCaptureDeviceInput( device: captureDevice!)

3- AVCaptureVideoPreviewLayer不返回optional,所以替换

 if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {

使用

 let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)