Ios AVCaptureSession将崩溃
我正在使用该代码拍照,我能够尽快拍照。 快速拍摄多张照片应用程序将崩溃 我用的是Swift 1.1 错误: 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'+[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] -空样本缓冲区。'Ios AVCaptureSession将崩溃,ios,swift,Ios,Swift,我正在使用该代码拍照,我能够尽快拍照。 快速拍摄多张照片应用程序将崩溃 我用的是Swift 1.1 错误: 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'+[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] -空样本缓冲区。' class ViewController: UIViewController { let captureSession = AVCapt
class ViewController: UIViewController {
let captureSession = AVCaptureSession()
var previewLayer : AVCaptureVideoPreviewLayer?
var captureDevice : AVCaptureDevice?
var captureConnection: AVCaptureConnection?
var stillImageOutput = AVCaptureStillImageOutput()
let targetRegion = CALayer()
var currentImage: UIImage?
@IBOutlet weak var cameraView: UIImageView!
@IBOutlet weak var imageDisplayed: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: true)
captureSession.sessionPreset = AVCaptureSessionPreset1920x1080
let devices = AVCaptureDevice.devices()
for device in devices {
if device.hasMediaType(AVMediaTypeVideo) {
if device.position == AVCaptureDevicePosition.Back {
captureDevice = device as? AVCaptureDevice
}
}
}
if captureDevice != nil {
println("Device trovato")
beginSession()
}
}
func beginSession() {
var err: NSError? = nil
captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err))
if err != nil {
println("err \(err?.localizedDescription)")
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
self.view.layer.addSublayer(previewLayer)
previewLayer?.frame = CGRect(x: cameraView.frame.origin.x, y: cameraView.frame.origin.y, width: cameraView.frame.size.width, height: cameraView.frame.size.height)
captureSetup()
captureSession.startRunning()
}
func captureSetup() {
let outputSetting = NSDictionary(dictionary: [AVVideoCodecKey: AVVideoCodecJPEG])
self.stillImageOutput.outputSettings = outputSetting
self.captureSession.addOutput(stillImageOutput)
for connection:AVCaptureConnection in self.stillImageOutput.connections as [AVCaptureConnection] {
for port:AVCaptureInputPort in connection.inputPorts! as [AVCaptureInputPort] {
if port.mediaType == AVMediaTypeVideo {
captureConnection = connection as AVCaptureConnection
break
}
}
if captureConnection != nil {
break
}
}
}
var i = 0;
func captureScene() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
if self.captureConnection != nil {
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in
let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
var pickedImage: UIImage = UIImage(data:imageDataJpeg)!
if let data = UIImagePNGRepresentation(pickedImage) {
let filename = self.getDocumentsDirectory().stringByAppendingPathComponent("\(self.i).png")
data.writeToFile(filename, atomically: true)
self.i++
}
})
}
})
}
func getDocumentsDirectory() -> NSString {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory: AnyObject = paths[0]
return documentsDirectory as NSString
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
captureScene()
}
}
@alper在中解释的是,有时
imageSampleBuffer
可能为零,这就是崩溃的根源
我相信在Swift 2
imageSampleBuffer
中,缓冲区是可选的,所以为了避免这种崩溃,您可以检查nil。例如:
if imageSampleBuffer != nil {
let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
// ...
} else {
// handle or ignore the error
}
但是您使用的是Swift 1,这是一个问题,因为在Swift 1imageSampleBuffer
中,它被声明为隐式展开的可选项,这意味着它不能为零,也不能像前面的示例中那样进行检查
@alper给出的解决方案是使用
CMSampleBufferIsValid(imageSampleBuffer)
作为检查缓冲区是否有效的一种方法
如果前面的解决方案不起作用,您可以试试这个 当我看到函数签名时:
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in
我看到缓冲区旁边有另一个参数,但您忽略了它:
(imageSampleBuffer:CMSampleBuffer!,389;)
我没有查找Swift 1文档,但如果\uuuu
实际上是一个错误参数,我也不会感到惊讶。尝试将其替换为错误
,如下所示:
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error) -> Void in
或许
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error:NSError) -> Void in
然后在继续执行imageSampleBuffer
之前,检查错误的内容
注意:正如我在最后一部分所说的,带有错误的解决方案是一个猜测,我没有测试:你必须尝试、调整,看看我的想法是否正确。如果您能找到有关Swift 1的文档并明确地告诉我们,这将是非常理想的
可能重复的问题您能解释关于同一个问题的答案吗?非常简单:检查imageSampleBuffer
是否为零,因为如果您快速拍摄几张照片,有时会为零我发现您的captureStillImageAsynchronouslyFromConnection
签名有一个非可选的imageSampleBuffer
。我相信这是Swift 1的问题,在Swift 2中它是可选的,您可以检查它是否为零。对于Swift 1,您应该查找此函数是否有可用的错误参数,并使用它。请重新编写作为答案,以便我可以提供完美的工作解决方案。回到过去,但为什么制作相机应用程序的方法如此缓慢?谢谢。不知道,我也有点惊讶,这个问题没有得到更明确的处理。检查这个解决方案,我不知道如何在swift中使用它@埃里克,我已经看过了,别担心不幸的是,我对另一个问题没有答案。