我们有一个自定义相机,可以在我们的IOS应用上拍照。当我们在IOS 11.0及更高版本上尝试该应用程序时,该应用程序将崩溃。该错误发生在AVCapturePhotoOutput的capturePhoto中。
这是viewWillAppear的代码。我们已经建立了一个自定义相机。
override func viewWillAppear(_ animated: Bool) {
let devices = AVCaptureDevice.devices().filter{ ($0 as AnyObject).hasMediaType(AVMediaType.video) && ($0 as AnyObject).position == AVCaptureDevice.Position.back }
if let captureDevice = devices.first {
do {
if self.captureSession.inputs.isEmpty {
try self.captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
}
}
catch _ as NSError {
// print("Error: \(error.localizedDescription)")
}
self.captureSession.sessionPreset = AVCaptureSession.Preset.photo
stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
if #available(iOS 11.0, *) {
stillPhotoDataOutput.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey:AVVideoCodecType.jpeg])], completionHandler: nil)
if self.captureSession.canAddOutput(stillPhotoDataOutput){
self.captureSession.addOutput(stillPhotoDataOutput)
}
}
else {
stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG];
if self.captureSession.canAddOutput(stillImageOutput) {
self.captureSession.addOutput(stillImageOutput)
}
}
self.avCaptureVideoPreview = AVCaptureVideoPreviewLayer(session: captureSession)
self.previewLayer = self.avCaptureVideoPreview
self.previewLayer.position = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
self.previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.previewLayer.bounds = CameraView.frame
self.previewLayer.frame = self.view.bounds
self.previewLayer.connection?.videoOrientation = self.returnedOrientation()
CameraView.layer.addSublayer(previewLayer)
self.captureSession.commitConfiguration()
self.captureSession.startRunning()
}
这里是单击按钮拍照时执行的代码。
@IBAction func takePicture(_ sender: Any) {
// self.performSegue(withIdentifier: "CameraSelectMembersSegue", sender: self)
if #available(iOS 11.0, *){
self.saveToCamera110();
}
else {
self.saveToCamera()
}
}
func saveToCamera110(){
// if let videoConnection = self.stillImageOutput.connection(with: AVMediaType.video) {
if let videoConnection = self.stillPhotoDataOutput.connection(with: AVMediaType.video){
// print (self.Tag, " into saveto camera 110")
// videoConnection.videoOrientation = self.videoOrientationFromCurrentDeviceOrientation()
// videoConnection.videoOrientation = AVCaptureVideoOrientation(ui: UIApplication.shared.statusBarOrientation)
videoConnection.videoOrientation = returnedOrientation()
// videoConnection.videoOrientation = AVCaptureVideoOrientation(ui:self.interfaceOrientation)
let stimageout = AVCapturePhotoOutput()
var settings = AVCapturePhotoSettings()
if #available(iOS 11.0, *) {
// settings.livePhotoVideoCodecType = .jpeg
settings = AVCapturePhotoSettings.init(format: [AVVideoCodecKey : AVVideoCodecJPEG])
// The delegate takes the picture and then calls photoOutput
**// THE ERROR OCCURES IN THIS STATEMENT BELOW**
stimageout.capturePhoto(with: settings, delegate: self);
} else {
settings = AVCapturePhotoSettings.init(format: [AVVideoCodecKey: AVVideoCodecJPEG])
// Fallback on earlier versions
// The delegate takes the picture and then calls photoOutput
stimageout.capturePhoto(with: settings, delegate: self);
};
self.stillImageOutput.captureStillImageAsynchronously(from: videoConnection , completionHandler: {(imageDataSampleBuffer: CMSampleBuffer!, error: Error!) -> Void in
if ((imageDataSampleBuffer) != nil){
var imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer!)
//write the image to stagging directory
} as! (CMSampleBuffer?, Error?) -> Void)
}
}
照片输出代码如下
// callBack from take picture
@available(iOS 11.0, *)
func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
}