Using iOS Swift to capture video feed from App, and looking to stop it properly.
Right now, I have created a button which starts the AVCaptureSession, and would like to allow the same button to stop the AVCapture Session properly when the user prefers. This would allow the user to start and end camera capture easily.
I receive error when I use:
captureSession.stopRunning()
Here is the code:
import UIKit
import AVFoundation
import Vision
class 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
}
}
To Stop Capture Session:)
func stopSession() {
if captureSession.isRunning {
DispatchQueue.global().async {
self.captureSession.stopRunning()
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With