从同一AVCaptureSession拍摄视频和照片时应用程序崩溃?



我正在尝试制作一个带有音频,视频和照片的应用程序,以使用相同的AVCaptureSession使用AVFoundation通过手势拍摄。

以下是我设置相机和捕获会话的方法。

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)
}

要从相机拍摄照片(正在工作,照片被存储到画廊中(,我做了以下工作:

@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:] 没有活动/启用的连接"。以下是我尝试执行的操作的代码。

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()
}
}

任何有关这方面的帮助,不胜感激。

您可以尝试像这样更改视频中的预设操作

captureSession.sessionPreset = AVCaptureSessionPresetHigh

你可以在这里看到类似的问题 AVCaptureMovieFileOutput - 没有活动/启用的连接

最新更新