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

zd287kbt  于 2023-10-15  发布在  Swift
关注(0)|答案(3)|浏览(121)

我是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:]无法将输出添加到捕获会话<AVCaptureSession:<AVCapturePhotoOutput: 0x283584560>0x2837fc560 [AVCaptureSessionPresetPhoto]>\n\t <AVCaptureDeviceInput:0x2835aa460 [Back Camera]>[vide]->\n\t <AVCaptureDeviceInput:0x2835aa460 [Back Camera]>[vide]->因为不支持同一类型的多个输出"<AVCapturePhotoOutput: 0x283592a60><AVCaptureVideoPreviewLayer: 0x283594bc0>
我上网查了一下,发现了这篇文章: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:对于任何人谁是以下,问题是,我打电话给他们的看法确实出现了使输出显示几次感谢马特的帮助(在评论中)。我通过使用视图加载修复了它

9udxz4iz

9udxz4iz1#

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

lmyy7pcs

lmyy7pcs2#

在Swift 5.7,iOS 16.0中工作

if session.canAddOutput(videoDataOutput) {
        session.addOutput(videoDataOutput)
       
}
jogvjijk

jogvjijk3#

如果上述解决方案不起作用,请在每次会话之前或视图中从捕获会话中删除 * 输入 * 和 * 输出 * 将消失。

captureSession.removeInput(input)
captureSession.removeOutput(captureMetadataOutput)

当新会话启动时,输入和输出将再次添加。

相关问题