AVCapturePhotoOutput-可能无法重复使用设置

时间:2019-01-08 02:57:10

标签: ios swift camera avfoundation avcapturesession

我正在运行ios 12 swift 4.2。

我已经实现了一个基本的相机捕获会话,并且正在从中单击图像。一切都很好,直到我在自动/打开/关闭模式之间切换闪光灯为止。单击第一张照片然后更改闪光模式后,该应用程序崩溃并显示错误:

@media only screen and (min-width: 800px) and (max-width: 825px) and (max-height: 500px) {...}

以下是摄像机的实现:

[AVCapturePhotoOutput capturePhotoWithSettings:delegate:] Settings may not be re-used'

我真的不了解如何精确地重用var captureSession: AVCaptureSession! var videoPreviewLayer: AVCaptureVideoPreviewLayer! var capturePhotoOutput: AVCapturePhotoOutput! let capturePhotoSettings = AVCapturePhotoSettings() var previewView: UIView! override func viewDidLoad() { startCameraSession() setupCaptureOutput() } @objc // Tap on a button to capture func takePhotoOnTap() { guard let capturePhotoOutput = self.capturePhotoOutput else { return } capturePhotoSettings.isAutoStillImageStabilizationEnabled = true capturePhotoSettings.isHighResolutionPhotoEnabled = true capturePhotoSettings.flashMode = .auto let _ = getSettings(camera: captureDevice!, flashMode: spotmiCameraOptions.flashMode) capturePhotoOutput.capturePhoto(with: capturePhotoSettings, delegate: self) } //This is a delegate method from the button func toggleFlash(mode: FlashMode) { switch mode { case .auto: capturePhotoSettings.flashMode = .auto case .enabled: capturePhotoSettings.flashMode = .on case .disabled: capturePhotoSettings.flashMode = .off } } func setupCaptureOutput() { capturePhotoOutput = AVCapturePhotoOutput() capturePhotoOutput.isHighResolutionCaptureEnabled = true captureSession.addOutput(capturePhotoOutput) } func startCameraSession() { let captureDevice = AVCaptureDevice.default(.builtInDualCamera, for: AVMediaType.video, position: .back) do { let input = try AVCaptureDeviceInput(device: captureDevice!) captureSession = AVCaptureSession() captureSession.addInput(input) videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) videoPreviewLayer.videoGravity = .resizeAspectFill videoPreviewLayer.frame = self.view.layer.bounds camcontainer.layer.addSublayer(videoPreviewLayer) captureSession.startRunning() } catch { print(error.localizedDescription) } } func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { guard error == nil, let sampleBuffer = photoSampleBuffer else { print("error capturing photo due to \(String(describing: error?.localizedDescription))") return } guard let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else { return } let capturedImage = UIImage(data: imageData, scale: 1.0) if let image = capturedImage { UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) } } func getSettings(camera: AVCaptureDevice, flashMode: FlashMode) -> AVCapturePhotoSettings { let settings = capturePhotoSettings if camera.hasFlash { switch flashMode { // case .auto: settings.flashMode = .auto case .enabled: settings.flashMode = .on case .disabled: settings.flashMode = .off default: settings.flashMode = .auto } } return settings } 并每次使用不同的闪光模式进行更改。我遇到了几个问题,但主要是关于手电筒的问题。我正在寻找闪光灯。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

AVCapturePhotoSettings对象是唯一的,并且无法重复使用,因此,每次使用此方法都需要获取新设置:

func getSettings(camera: AVCaptureDevice, flashMode: CurrentFlashMode) -> AVCapturePhotoSettings {
    let settings = AVCapturePhotoSettings()

    if camera.hasFlash {
        switch flashMode {
           case .auto: settings.flashMode = .auto
           case .on: settings.flashMode = .on
           default: settings.flashMode = .off
        }
    }
    return settings
}

如您所见,不需要lockConfiguration

CurrentFlashModeenum,其创建目的是为了使内容保持清楚:

枚举CurrentFlashMode {    情况下    案子    案例自动 }

然后只需在拍摄照片时使用它即可

 @IBAction func captureButtonPressed(_ sender: UIButton) {
        let currentSettings = getSettings(camera: currentCamera, flashMode: currentFlashMode)
        photoOutput.capturePhoto(with: currentSettings, delegate: self)
    }

答案 1 :(得分:0)

{p> AVCapturePhotoSettings中的引号,请参阅最后一个重要部分:

  

摘要

     
    

用于单个照片捕获请求的功能和设置的规范。

  
     

声明

     
    

AVCapturePhotoSettings类:NSObject     讨论

         

要拍摄照片,请创建并配置一个AVCapturePhotoSettings对象,然后将其传递给AVCapturePhotoOutput capturePhoto(with:delegate :)方法。     AVCapturePhotoSettings实例可以包括设置的任何组合,无论该组合对于给定的捕获会话是否有效。通过将照片设置对象传递给AVCapturePhotoOutputcapturePhoto(with:delegate :)方法来启动捕获时,照片捕获输出会验证您的设置以确保确定性的行为。例如,flashMode设置必须指定一个在照片输出的受支持的FlashModes数组中存在的值。有关详细的验证规则,请参见下面的每个属性描述。

  
     

重要

     
    

将AVCapturePhotoSettings实例重用于多个捕获是非法的。如果设置对象的uniqueID值与任何以前使用的设置对象的uniqueID值匹配,则调用capturePhoto(with:delegate :)方法将引发异常(invalidArgumentException)。     To reuse a specific combination of settings, use the init(from:)初始化程序可从现有照片设置对象创建新的唯一AVCapturePhotoSettings实例。

  

与您同样的问题:this github issue