【问题标题】:Using AVCapturePhotoOutput in iOS10 - NSGenericException在 iOS10 中使用 AVCapturePhotoOutput - NSGenericException
【发布时间】:2017-03-28 01:47:48
【问题描述】:

我目前正在尝试弄清楚如何使用 iOS 10 的 AVCapturePhotoOutput 方法,但在这样做时遇到了麻烦。我觉得我即将做对,但继续收到错误:

由于未捕获的异常“NSGenericException”而终止应用程序,原因:“-[AVCapturePhotoOutput capturePhotoWithSettings:delegate:] 没有活动和启用的视频连接”

我尝试将这行代码放在 AVCapturePhotoCaptureDelegate 或我的 didPressTakePhoto 函数中:

if let videoConnection = stillImageOutput.connection(withMediaType: AVMediaTypeVideo) {
     videoConnection.videoOrientation = AVCaptureVideoOrientation.portrait;
     ...
}

这是我目前的代码:

import AVFoundation
import UIKit

class Camera: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, AVCapturePhotoCaptureDelegate {

    @IBOutlet weak var cameraView: UIView!
    @IBOutlet weak var imageView: UIImageView!

    var captureSession : AVCaptureSession?
    var stillImageOutput : AVCapturePhotoOutput?
    var stillImageOutputSettings : AVCapturePhotoSettings?
    var previewLayer : AVCaptureVideoPreviewLayer?

    var didTakePhoto = Bool();

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated);

        previewLayer?.frame = cameraView.bounds;
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated);

        captureSession = AVCaptureSession();
        captureSession?.sessionPreset = AVCaptureSessionPreset1920x1080;

        stillImageOutput = AVCapturePhotoOutput();

        let backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo);

        do {
            let input = try AVCaptureDeviceInput(device: backCamera)

            if (captureSession?.canAddInput(input))! {
                captureSession?.addInput(input);

                if (captureSession?.canAddOutput(stillImageOutput))! {
                    captureSession?.canAddOutput(stillImageOutput);

                    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
                    previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect;
                    previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait;
                    cameraView.layer.addSublayer(previewLayer!);
                    captureSession?.startRunning();
                }
            }
        } catch {
            print(error);
        }
    }

    func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
        if let error = error {
            print(error.localizedDescription);
        }

        if let sampleBuffer = photoSampleBuffer, let previewBuffer = previewPhotoSampleBuffer, let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) {
            print(UIImage(data: dataImage)?.size as Any);

            let dataProvider = CGDataProvider(data: dataImage as CFData);
            let cgImageRef: CGImage! = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent);
            let image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.right);

            self.imageView.image = image;
            self.imageView.isHidden = false;
        }
    }

    func didPressTakePhoto() {
            stillImageOutputSettings = AVCapturePhotoSettings();

            let previewPixelType = stillImageOutputSettings?.availablePreviewPhotoPixelFormatTypes.first!;
            let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewPixelType,
                                 kCVPixelBufferWidthKey as String: 160,
                                 kCVPixelBufferHeightKey as String: 160];
            stillImageOutputSettings?.previewPhotoFormat = previewFormat;

            stillImageOutput.capturePhoto(with: stillImageOutputSettings!, delegate: self);
    }

    func didPressTakeAnother() {
        if (didTakePhoto == true) {
            imageView.isHidden = true;
            didTakePhoto = false;
        } else {
            captureSession?.startRunning();
            didTakePhoto = true;
            didPressTakePhoto();
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        didPressTakeAnother();
    }
}

有什么建议吗?

提前致谢!

【问题讨论】:

  • 你是在模拟器上运行这个吗?
  • 不,在我的 iPhone 6S+ 上运行它

标签: ios nsexception avcapture


【解决方案1】:

代码错误。

应该是这样的

if (captureSession?.canAddOutput(stillImageOutput))!{
      captureSession?.addOutput(stillImageOutput)
}

【讨论】:

    【解决方案2】:

    对于其他可能试图弄清楚这一点的人,以下资源帮助了我:

    供参考和代码布局

    SnapChat: Camera 1

    SnapChat: Camera 2

    iOS10相机新功能的实际实现和使用

    AV Foundation: iOS 10

    iOS Custom Camera

    【讨论】:

      【解决方案3】:

      AVCaptureSessionPreset1920x1080 更改为AVCaptureSessionPresetHigh

      试试看

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-18
        • 2018-10-17
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        • 2017-03-07
        • 2023-04-07
        • 2017-01-03
        相关资源
        最近更新 更多