RealityKit(Swift5)应用捕获RAW图像报错“Cannot Record”求助
解决RealityKit AR应用中RAW图像捕获的"Cannot Record"错误
Hey there, let's break down why you're hitting that "Cannot Record" error when trying to capture RAW photos in your RealityKit AR app, and fix it step by step.
核心问题分析
Your code has a few critical issues, plus a key conflict with how ARKit uses the camera:
- Missing RAW format configuration: Your
getBestSettings()method doesn't specify a valid RAW pixel format, which is mandatory for capturing RAW photos. - Incorrect AVCaptureSession setup order: You're adding the output before the input, which can cause configuration conflicts.
- Camera session conflict with ARKit: When using RealityKit/ARKit, the framework already owns the camera session. Creating a separate
AVCaptureSessionwill clash with ARKit's session, leading directly to the "Cannot Record" error. - Potential missing camera permissions: You need to explicitly request camera access in your app's
Info.plist.
解决方案
1. 利用ARKit的原生RAW捕获(推荐)
Since you're building an AR app, the right approach is to leverage ARKit's built-in support for RAW camera capture instead of creating a separate AVCaptureSession. Here's how to implement it:
Step 1: Enable RAW capture in your AR configuration
import RealityKit import ARKit class ARViewContainer: UIView { let arView = ARView(frame: .zero) override init(frame: CGRect) { super.init(frame: frame) setupARSession() } required init?(coder: NSCoder) { super.init(coder: coder) setupARSession() } private func setupARSession() { addSubview(arView) arView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ arView.topAnchor.constraint(equalTo: topAnchor), arView.leadingAnchor.constraint(equalTo: leadingAnchor), arView.trailingAnchor.constraint(equalTo: trailingAnchor), arView.bottomAnchor.constraint(equalTo: bottomAnchor) ]) // Configure AR session with RAW capture support let configuration = ARWorldTrackingConfiguration() if ARWorldTrackingConfiguration.supportsRawCameraCapture { configuration.isRawCameraCaptureEnabled = true print("RAW camera capture enabled successfully") } else { print("This device doesn't support RAW camera capture") } arView.session.delegate = self arView.session.run(configuration) } } extension ARViewContainer: ARSessionDelegate { // Trigger capture on user action (e.g., button tap) instead of every frame func captureRAWOnDemand() { guard let currentFrame = arView.session.currentFrame, let rawImageBuffer = currentFrame.rawCameraImage else { print("Failed to access RAW image buffer") return } processRAWImage(rawImageBuffer) } private func processRAWImage(_ rawBuffer: CVImageBuffer) { print("Successfully captured RAW image") // Example: Convert RAW buffer to DNG file (simplified) guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back), let rawFormat = device.availableRawPhotoPixelFormatTypes.first else { return } let photoSettings = AVCapturePhotoSettings(rawPixelFormatType: rawFormat, processedFormat: nil) let photoOutput = AVCapturePhotoOutput() photoOutput.prepare(forPhotoCaptureWith: photoSettings) { preparedSettings, error in if let error = error { print("Preparation error: \(error.localizedDescription)") return } // Use preparedSettings and rawBuffer to generate a DNG file // For full implementation, you can use CoreImage or dedicated RAW processing libraries } } }
2. 修复独立AVCaptureSession代码(不推荐用于AR应用)
If you absolutely need to use a separate AVCaptureSession (not advised for AR apps), fix these issues in your original code:
Fix RAW format configuration
func getBestSettings() -> AVCapturePhotoSettings? { guard let device = getDevice() else { return nil } // Get the first supported RAW pixel format from the device if let rawPixelFormat = device.availableRawPhotoPixelFormatTypes.first { return AVCapturePhotoSettings(rawPixelFormatType: rawPixelFormat, processedFormat: nil) } // Fallback to standard photo settings if RAW isn't supported return AVCapturePhotoSettings() }
Fix session setup order
func configSession(){ session.stopRunning() session.beginConfiguration() session.sessionPreset = .photo // Add input FIRST, then output (critical for correct configuration) guard let device = getDevice(), let input = try? AVCaptureDeviceInput(device: device) else { fatalError("Failed to create camera input") } if session.canAddInput(input) { session.addInput(input) } if session.canAddOutput(capture) { session.addOutput(capture) } session.commitConfiguration() }
Add camera permission
Add this entry to your Info.plist to request camera access from the user:
<key>NSCameraUsageDescription</key> <string>需要访问相机来捕获RAW图像</string>
Key Notes
- Avoid session conflicts: ARKit reserves the camera for its own use, so using a separate
AVCaptureSessionwill almost always cause issues like "Cannot Record". Stick to ARKit'srawCameraImagewhenever possible. - RAW support varies: Not all iOS devices support RAW capture, so always check
ARWorldTrackingConfiguration.supportsRawCameraCaptureordevice.availableRawPhotoPixelFormatTypesbefore enabling it.
内容的提问来源于stack exchange,提问作者Paul-Boer Putter
相关产品推荐
相关产品推荐

