Удалите AVCaptureSession и PreviewLayer правильно в Swift

jKraut спросил: 13 июня 2018 в 11:03 в: ios

Использование iOS Swift для захвата видеопотока из приложения и поиска, чтобы остановить его правильно.

В настоящее время я создал кнопку, которая запускает AVCaptureSession и хочет, чтобы одна и та же кнопка останавливала сеанс AVCapture должным образом, когда пользователь предпочитает. Это позволит пользователю легко запускать и завершать захват камеры.

Я получаю сообщение об ошибке:

captureSession.stopRunning()  

Вот код:

import UIKit
import AVFoundation
import Visionclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {    // creates a new capture session
    let captureSession = AVCaptureSession()    override func viewDidLoad() {
        super.viewDidLoad()        setupLabel()
        createButton()    }    func setupCaptureSession() {        // search for available capture devices
        let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices        // get capture device, add device input to capture session
        do {
            if let captureDevice = availableDevices.first {
                captureSession.addInput(try AVCaptureDeviceInput(device: captureDevice))
            }
        } catch {
            print(error.localizedDescription)
        }        // setup output for Model 1, add output to capture session
        let captureOutput = AVCaptureVideoDataOutput()
        captureSession.addOutput(captureOutput)        captureOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = view.frame
        view.layer.addSublayer(previewLayer)        captureSession.startRunning()    }    // called everytime a frame is captured
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {        guard let model_one = try? VNCoreMLModel(for: imagenet_ut().model) else { return }        let request = VNCoreMLRequest(model: model_one) { (finishedRequest, error) in
            guard let results = finishedRequest.results as? [VNClassificationObservation] else { return }
            guard let Observation = results.first else { return }            DispatchQueue.main.async(execute: {                // use model here
            })
        }        guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }        // executes request
        try? VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]).perform([request])        self.label.text = "label text"    }    func setupLabel() {
        let label: UILabel = {
            let label = UILabel()
            label.textColor = .white
            label.translatesAutoresizingMaskIntoConstraints = false
            label.text = "Label"
            label.font = label.font.withSize(30)
            return label
        }90        view.addSubview(label)
        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        label.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50).isActive = true
    }    func createButton () {
        let button = UIButton();
        button.setTitle("Start Camera", for: .normal)
        button.setTitleColor(UIColor.white, for: .normal)
        button.frame = CGRect(x: 5, y: 710, width: 200, height: 100)        button.addTarget(self, action: #selector(ViewController.buttonPressed(_:)), for: .touchUpInside)
        self.view.addSubview(button)    }    @objc func buttonPressed(_ sender: UIButton!) {
        setupCaptureSession()        if let buttonTitle = sender.title(for: .normal) {
            print(buttonTitle)
            if buttonTitle == "Stop Camera" {
                print("was stopped")
            }
        }        sender.setTitle("Stop Camera", for: .normal)
    }    func stopCamera() {
        captureSession.stopRunning()  // error occurs here
    }
}

1 ответ

Есть решение
SAXENA ответил: 14 июня 2018 в 07:21

Чтобы остановить сеанс захвата: наслаждайтесь:)

func stopSession() {
    if captureSession.isRunning {
        DispatchQueue.global().async {
            self.captureSession.stopRunning()
        }
    }
}
SAXENA ответил: 14 июня 2018 в 04:20
Вызовите это имя функции (startession) в viewDidLoad, а также в viewWillAppear ............ func startSession () {if! captureSession.isRunning {DispatchQueue.global (). async {self.captureSession.startRunning ()}}}
jKraut ответил: 14 июня 2018 в 11:37
это работает, но когда я пытаюсь перезапустить, я получаю ошибку неперехваченного исключения. Должен ли я останавливать AVCaptureVideoDataOutput или VNCoreMLRequest?

Дополнительное видео по вопросу: Удалите AVCaptureSession и PreviewLayer правильно в Swift

BUILD SNAPCHAT CAMERA IN iOS WITH SWIFT - AVKIT AND AVFOUNDATION

iOS Swift Tutorial: Basic Custom Camera App - AVFoundation

CoreML: Real Time Camera Object Detection with Machine Learning - Swift 4