无法添加输出,因为不支持多个相同类型的输出

问题描述

我是Swift的初学者,使用Swift 5和XCode 11.5。这是我创建相机的代码。我希望足够了!

override func viewDidAppear(_ animated: Bool) {
    setupCaptureSession()
    setupDevice()
    setupInputOutput()
    setupPreviewLayer()
    captureSession.startRunning()
}
   
func setupCaptureSession() {
    captureSession.sessionPreset = AVCaptureSession.Preset.photo
}

func setupDevice() {
    let devicediscoverySession = AVCaptureDevice.discoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],mediaType: AVMediaType.video,position: AVCaptureDevice.Position.unspecified)
    let devices = devicediscoverySession.devices
    
    for device in devices {
        if device.position == AVCaptureDevice.Position.back {
            backCamera = device
        } else if device.position == AVCaptureDevice.Position.front {
            frontCamera = device
        }
    }
    currentDevice = backCamera
}

func setupInputOutput() {
    do {
        
        let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)
        if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
            for input in inputs {
                captureSession.removeInput(input)
            }
        }
        captureSession.addInput(captureDeviceInput)
        photoOutput = AVCapturePhotoOutput()
        photoOutput!.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])],completionHandler: nil)
        captureSession.addOutput(photoOutput!)
        
    } catch {
        print(error)
    }
}

func setupPreviewLayer() {
    self.cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    self.cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    self.cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
    self.cameraPreviewLayer?.frame = view.frame
    
    self.view.layer.insertSublayer(self.cameraPreviewLayer!,at: 0)
}


@IBAction func rotateCamera(_ sender: Any) {
    captureSession.beginConfiguration()
    
    // Change the device based on the current camera
    let newDevice = (currentDevice?.position == AVCaptureDevice.Position.back) ? frontCamera : backCamera
    
    // Remove all inputs from the session
    for input in captureSession.inputs {
        captureSession.removeInput(input as! AVCaptureDeviceInput)
    }
    
    // Change to the new input
    let cameraInput:AVCaptureDeviceInput
    do {
        cameraInput = try AVCaptureDeviceInput(device: newDevice!)
    } catch {
        print(error)
        return
    }
    
    if captureSession.canAddInput(cameraInput) {
        captureSession.addInput(cameraInput)
    }
    
    currentDevice = newDevice
    captureSession.commitConfiguration()
}

我正在尝试使用AVFoundation创建摄像机,但出现一条错误消息: 线程1:异常:“ ***-[AVCaptureSession addOutput:]无法添加输出以捕获会话 \ n \ t [视频] -> \ n \ t [vide]-> ,因为不支持多个相同类型的输出“

所以我看了网上,发现这篇文章:AVCapture Session To Capture Image SWIFT提到了类似的错误,但是因为它使用的是旧版本,所以我尝试重新创建它。但是,我能得到的最远的是:

        dispatchQueue.global(qos: .userInteractive).async { // 1
            self.captureSession.addOutput(self.photoOutput!)
            try self.captureSession.addInput( AVCaptureDeviceInput(device: self.currentDevice!))

//supposed to add error here but Couldn't do it
                self.captureSession.sessionPreset = AVCaptureSession.Preset.photo
            var previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
                previewLayer.frame = self.cameraview.layer.bounds
//In my project it said there was no member cameraview of UIViewController. 
                previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
            dispatchQueue.main.async { // 2
                        // 3
                self.cameraview.layer.addSublayer(previewLayer)
                self.captureSession.startRunning()
                }
            }

由于从那时起不赞成使用许多方法,因此我很难找到新的方法,而且我什至无法将错误添加为参数,因为它是调用中的额外参数。如果有人可以帮助我解决如何解决多个输入问题,我将非常感激。我尽了最大的努力,但老实说我找不到任何解决方案。

谢谢!

编辑:我添加了更多代码

编辑2:对于所有关注的人,问题在于我在视野中给他们打电话的确是在Matt的帮助下(在评论中)确实使输出多次显示。我通过使用视图加载来修复了它

解决方法

在调用 addOutput: 之前,您应该检查 canAddOutput:。因为调用 addOutput: 次数过多会导致崩溃。