What I want: I want to scan for barcodes with all available back cameras of an iPhone at the same time. So the user don't have to care about the distance of the barcode so much.
What I tried:
I created an
AVCaptureSessionfor each camera, and used one camera for thevideoPreviewLayerso that the user can see a live video of one camera. The problem here is that if I start more than oneAVCaptureSession, the live video will freeze.func setupCaptureSessions() { let devices = [ AVCaptureDevice.DiscoverySession(deviceTypes: codeScanningDevicesTypes, mediaType: .video, position: .back).devices.first!, AVCaptureDevice.DiscoverySession(deviceTypes: codeScanningDevicesTypes, mediaType: .video, position: .back).devices.last! ] for device in devices { let captureSession = AVCaptureSession() captureSession.beginConfiguration() guard let deviceInput = try? AVCaptureDeviceInput(device: device) else { print("Failed to create device input for camera") return } guard captureSession.canAddInput(deviceInput) else { print("Failed to add device input to capture session") return } captureSession.addInput(deviceInput) let metadataOutput = AVCaptureMetadataOutput() if captureSession.canAddOutput(metadataOutput) { captureSession.addOutput(metadataOutput) metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) metadataOutput.metadataObjectTypes = metadataOutput.availableMetadataObjectTypes } captureSession.commitConfiguration() captureSessions.append(captureSession) } } func startScanning() { // Video Konfiguration let videoOutput = AVCaptureVideoDataOutput() videoOutput.alwaysDiscardsLateVideoFrames = true guard let captureSession = captureSessions.first else { return } if captureSession.canAddOutput(videoOutput) { videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "video_ouput_queue")) captureSession.addOutput(videoOutput) } videoPreviewLayer.session = captureSession videoPreviewLayer.videoGravity = .resizeAspectFill videoPreviewLayer.connection?.videoOrientation = videoOrientationFromCurrentDeviceOrientation() for captureSession in captureSessions { captureSession.startRunning() } }Another try was to use an
AVCaptureMultiCamSessionand just to create a bunch ofAVCaptureDeviceInputand at them to thecaptureSession. The problem here is that just one camera was really scanning for barcodes:let codeScanningDevicesTypes: [AVCaptureDevice.DeviceType] = [ .builtInUltraWideCamera, .builtInDualWideCamera, .builtInWideAngleCamera, .builtInTripleCamera, .builtInDualCamera, .builtInTelephotoCamera, ] private let allDetactableCodeTypes = [ AVMetadataObject.ObjectType.code39, .code39Mod43, .code93, .code128, .ean8, .ean13, .interleaved2of5, .itf14, .upce, .aztec, .dataMatrix, .pdf417, .qr ] private func setupCaptureSession() { defer { captureDevice?.unlockForConfiguration() captureSession.commitConfiguration() } guard let device = captureDevice else { return } let backCameras:[AVCaptureDevice] = AVCaptureDevice.DiscoverySession(deviceTypes: codeScanningDevicesTypes, mediaType: .video, position: .back).devices captureSession.beginConfiguration() // Inputs: backCameras.forEach { device in guard let deviceInput = try? AVCaptureDeviceInput(device: device) else { return } if captureSession.canAddInput(deviceInput) { captureSession.addInput(deviceInput) } do { try configureDevice(device: device) } catch { let error = ImageScannerControllerError.inputDevice delegate?.captureSessionManager(self, didFailWithError: error) return } } // Outputs: let metadataOutput = AVCaptureMetadataOutput() if captureSession.canAddOutput(metadataOutput) { captureSession.addOutput(metadataOutput) metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) metadataOutput.metadataObjectTypes = allDetactableCodeTypes } let videoOutput = AVCaptureVideoDataOutput() videoOutput.alwaysDiscardsLateVideoFrames = true if captureSession.canAddOutput(videoOutput) { videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "video_ouput_queue")) captureSession.addOutput(videoOutput) } videoPreviewLayer.session = captureSession videoPreviewLayer.videoGravity = .resizeAspectFill videoPreviewLayer.connection?.videoOrientation = videoOrientationFromCurrentDeviceOrientation() }
So the question now, how is it possible to scan for barcodes with all available cameras at the same time?
I could find a solution for myself, maybe it can help someone with the same Problem: