我正在使用该代码拍照 我能够尽可能快地拍照。 快速拍摄多张照片应用程序会崩溃。
我使用的是 Swift 1.1。
错误:
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“+[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] - 空样本缓冲区。'
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 在 linked answer 中解释的内容是有时 imageSampleBuffer
可以为 nil,这就是崩溃的根源。
我相信在 Swift 2 中 imageSampleBuffer
是可选的,因此为了避免这种崩溃,您可以检查 nil。示例:
if imageSampleBuffer != nil {
let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
// ...
} else {
// handle or ignore the error
}
但是您使用的是 Swift 1,这是一个问题,因为在 Swift 1 中,imageSampleBuffer
被声明为隐式展开的可选值,这意味着它不能为 nil,您不能像在前面的例子。
@alper给出的解决方案是使用
CMSampleBufferIsValid(imageSampleBuffer)
作为检查缓冲区是否有效的一种方式。
如果前面的解决方案不起作用,您可以试试这个。
当我查看函数签名时:
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in
我看到缓冲区旁边还有另一个参数,但您忽略了它:
(imageSampleBuffer:CMSampleBuffer!, _)
我没有查找 Swift 1 文档,但如果 _
实际上是一个错误参数,我不会感到惊讶。尝试用这样的 error
替换它:
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error) -> Void in
或者也许
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error:NSError) -> Void in
然后在继续 imageSampleBuffer
之前检查 error
的内容。
注意:正如我在最后一部分所说,错误
的解决方案是一个猜测,我没有测试:您必须尝试、适应并看看我的想法对不对。如果您能找到关于此的 Swift 1 文档并明确地告诉我们它,那将是理想的。
关于ios - AVCaptureSession 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34024942/