2015-02-05 51 views
3

我尝试使用自定义视图拍摄照片(不使用UIImagePickerController),但每当我尝试拍摄照片时,应用程序都会崩溃并引发此错误:尝试拍摄照片时通过的无效/无效连接

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection:completionHandler:] - inactive/invalid connection passed.'

这是我的takePhoto()功能,这将导致错误:

func takePhoto(sender: UIButton!){ 
    var still: AVCaptureStillImageOutput = AVCaptureStillImageOutput() 
    var connection: AVCaptureConnection = AVCaptureConnection(inputPorts: self.input.ports, output: still) 

    if(connection.enabled){ 
     still.captureStillImageAsynchronouslyFromConnection(connection, completionHandler: {(buffer: CMSampleBuffer!, error: NSError!) -> Void in 
      println("picture taken")//this never gets executed 
     }) 
    } 
} 

我也试过在takePhoto()功能设置connection变量:

self.output.connections[0] as AVCaptureConnection 

以及

(self.session.outputs[0] as AVCaptureOutput).connections[0] as AVCaptureConnection 

,我也得到了相同的结果。

在同一视图作为取照片按钮,也有摄像头的实时预览(工作):

func setupCamera(){ 
    self.session = AVCaptureSession() 
    self.session.sessionPreset = AVCaptureSessionPreset640x480 
    self.session.beginConfiguration() 
    self.session.commitConfiguration() 

    var error: NSError? 

    var devices: [AVCaptureDevice] = AVCaptureDevice.devices() as [AVCaptureDevice] 
    for device in devices{ 
     if(device.hasMediaType(AVMediaTypeVideo) && device.supportsAVCaptureSessionPreset(AVCaptureSessionPreset640x480)){ 

      //the input variable is initialized here 

      self.input = AVCaptureDeviceInput.deviceInputWithDevice(device as AVCaptureDevice, error: &error) as AVCaptureDeviceInput 

      if(self.session.canAddInput(self.input)){ 
       self.session.addInput(self.input) 
       break 
      } 
     } 
    } 

    var settings = [kCVPixelBufferPixelFormatTypeKey:kCVPixelFormatType_32BGRA] 

    //the output variable is initialized here 

    self.output = AVCaptureVideoDataOutput() 
    self.output.videoSettings = settings 
    self.output.alwaysDiscardsLateVideoFrames = true 

    if(self.session.canAddOutput(self.output)){ 
     self.session.addOutput(self.output) 
    } 

    var captureLayer = AVCaptureVideoPreviewLayer(session: self.session) 
    captureLayer.frame = CGRectMake(0, 64, self.view.frame.width, (self.view.frame.width * 4)/3) 
    self.view.layer.addSublayer(captureLayer) 

    self.session.startRunning() 
} 

我在我的iPhone 5S测试这一点,一切正常,包括预览功能在内的takePhoto()功能除外。

有没有办法做到这一点,或者我必须使用UIImagePickerController

回答

4

设置相机时,请将stillImageOutput添加到AVCaptureSession

self.stillImageOutput = AVCaptureStillImageOutput() 
let stillSettings = [AVVideoCodecJPEG:AVVideoCodecKey] 
self.stillImageOutput.outputSettings = stillSettings 

if(self.session.canAddOutput(self.stillImageOutput)){ 
    self.session.addOutput(self.stillImageOutput) 
} 

然后拍照时,从stillImageOutput中获取AVCaptureSession

func takePhoto(sender: UIButton!){ 
    let connection = self.stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) 

    if(connection.enabled){ 
     self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(connection, completionHandler: {(buffer: CMSampleBuffer!, error: NSError!) -> Void in 
      println("picture taken") // Now, this is executed 
     }) 
    } 
} 
0

谁伸手从crashlytics什么这个问题无法重现:

用户拒绝访问摄像机。检查相机许可是否被授予。我得到了生产崩溃,结果是这种情况。