App crashing while taking both video and photo from same AVCaptureSession?
我正在尝试使用 AVFoundation 使用相同的 AVCaptureSession 制作一个包含音频、视频和照片的应用程序。
以下是我如何设置相机和捕获会话。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | func setUpCaptureSession(){ captureSession.sessionPreset = AVCaptureSession.Preset.photo } func setUpDevice(){ let deviceDiscoverSession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified) let devices = deviceDiscoverSession.devices for device in devices{ if device.position == AVCaptureDevice.Position.back{ backCamera = device }else{ frontCamera = device } } currentCamera = backCamera } func setUpInputOutput(){ do{ let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!) captureSession.addInput(captureDeviceInput) photoOutput = AVCapturePhotoOutput() photoOutput?.isHighResolutionCaptureEnabled = true self.captureSession.addOutput(photoOutput!) if #available(iOS 11.0, *) { photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])], completionHandler: nil) } else { // Fallback on earlier versions photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecJPEG])], completionHandler: nil) } }catch{ print(error) } } func setUpPreviewLayer(){ cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait cameraPreviewLayer?.frame = self.cameraView.frame self.cameraView.layer.insertSublayer(cameraPreviewLayer!, at: 0) } func startRunningCaptureSession(){ captureSession.startRunning() //Session starts with camera as default so set it to gesture let doubleTap = UITapGestureRecognizer(target: self, action: #selector(takePhoto(sender:))) doubleTap.numberOfTapsRequired = 2 self.view.addGestureRecognizer(doubleTap) } |
要从相机拍照(正在工作,照片存储在图库中),我做了以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | @objc func cameraAction(sender: UIButton){ if(imageSetAction()){ cameraImage.image = UIImage(named:"photo") cameraLabel.textColor = ConstantColors.selectedTextColor currentSelected = sender.tag let doubleTap = UITapGestureRecognizer(target: self, action: #selector(takePhoto(sender:))) doubleTap.numberOfTapsRequired = 2 self.view.addGestureRecognizer(doubleTap) } } @objc func takePhoto(sender: Any){ guard let capturePhotoOutput = self.photoOutput else { return } let photoSettings = AVCapturePhotoSettings() photoSettings.isAutoStillImageStabilizationEnabled = true photoSettings.isHighResolutionPhotoEnabled = true photoSettings.flashMode = .auto capturePhotoOutput.capturePhoto(with: photoSettings, delegate: self) } func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { guard error == nil, let photoSampleBuffer = photoSampleBuffer else { print("Error capturing photo: \\(String(describing: error))") return } guard let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else { return } let capturedImage = UIImage.init(data: imageData , scale: 1.0) if let image = capturedImage { //UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) let vc = UIStoryboard.init(name:"ImageEdit", bundle: Bundle.main).instantiateViewController(withIdentifier:"imageEdit") as? ImageEdit vc?.imagetoEdit = image self.navigationController?.pushViewController(vc!, animated: true) } } |
但是当我尝试从同一个捕获会话中拍照时,我收到错误 "NSInvalidArgumentException\\',原因:\\'*** -[AVCaptureMovieFileOutput startRecordingToOutputFileURL:recordingDelegate:] No active/enabled connections\\'"。下面是我尝试做的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { print("completed") } @objc func videoAction(sender: UIButton){ if(imageSetAction()){ videoImage.image = UIImage(named:"video") videoLabel.textColor = ConstantColors.selectedTextColor currentSelected = sender.tag captureSession.removeOutput(photoOutput!) self.movieFileOutput = AVCaptureMovieFileOutput() self.captureSession.addOutput(movieFileOutput!) let longPressGesture = UILongPressGestureRecognizer.init(target: self, action: #selector(handleLongPress)) self.view.addGestureRecognizer(longPressGesture); } } @objc func handleLongPress(gestureRecognizer: UILongPressGestureRecognizer) { if gestureRecognizer.state == UIGestureRecognizerState.began { debugPrint("long press started") let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL let filePath = documentsURL.appendingPathComponent("tempMovie.mp4") if FileManager.default.fileExists(atPath: filePath.absoluteString) { do { try FileManager.default.removeItem(at: filePath) } catch { // exception while deleting old cached file // ignore error if any } } movieFileOutput?.startRecording(to: filePath, recordingDelegate: self) } else if gestureRecognizer.state == UIGestureRecognizerState.ended { debugPrint("longpress ended") movieFileOutput?.stopRecording() } } |
对此的任何帮助表示赞赏。
您可以尝试像这样更改 videoAction 中的预设
1 | captureSession.sessionPreset = AVCaptureSessionPresetHigh |
你可以在这里看到类似的问题
AVCaptureMovieFileOutput - 没有活动/启用的连接