Несколько ошибок в моем коде Swift для приложения камеры - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь создать приложение для камеры на Xcode 10.1, используя Swift для школьного проекта.Я работал над этим некоторое время, и все еще имею несколько ошибок.

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()

И это помечено, поскольку у Initializer для условного связывания должен быть необязательный тип, а не AVCaptureVideoPreviewLayer.

Если вы можете исправить или даже предложить совет, как исправить любой из них, это будет много значить для меня и действительно сделает мой год.

1 Ответ

0 голосов
/ 11 декабря 2018

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 не возвращается по желанию, поэтому замените

 if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {

с

 let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
...