Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import VisionCamera

final class HybridBarcodeScannerOutput: HybridCameraOutputSpec, NativeCameraOutput {
private let scanner: BarcodeScanner
private let onBarcodeScanned: (_ barcodes: [any HybridBarcodeSpec]) -> Void
private let onError: (_ error: Error) -> Void
private var isScanning = false
private var delegate: BarcodeScannerDelegate? = nil
private let queue: DispatchQueue
let output: AVCaptureVideoDataOutput
Expand All @@ -32,37 +35,15 @@ final class HybridBarcodeScannerOutput: HybridCameraOutputSpec, NativeCameraOutp

init(options: BarcodeScannerOutputOptions) {
self.scanner = BarcodeScanner.barcodeScanner(options: options.toMLKitOptions())
self.onBarcodeScanned = options.onBarcodeScanned
self.onError = options.onError
self.queue = DispatchQueue(label: "com.margelo.camera.barcodescanner")
self.output = AVCaptureVideoDataOutput()
super.init()

// set delegate
var isScanning = false
self.delegate = BarcodeScannerDelegate(onSampleBuffer: { [weak self] buffer in
guard let self else { return }
if isScanning { return }

// prepare MLImage
isScanning = true
guard let image = MLImage(sampleBuffer: buffer) else {
options.onError(
RuntimeError.error(withMessage: "Failed to convert CMSampleBuffer to MLImage!"))
return
}
image.orientation = self.outputOrientation.toUIImageOrientation()
// start scanning
self.scanner.process(image) { barcodes, error in
isScanning = false
if let barcodes {
// scanned x barcodes!
let hybridBarcodes = barcodes.map { HybridBarcode(barcode: $0) }
options.onBarcodeScanned(hybridBarcodes)
}
if let error {
// error
options.onError(error)
}
}
self?.scan(buffer)
})
self.output.setSampleBufferDelegate(delegate, queue: queue)
self.output.alwaysDiscardsLateVideoFrames = true
Expand All @@ -72,6 +53,33 @@ final class HybridBarcodeScannerOutput: HybridCameraOutputSpec, NativeCameraOutp
}
}

private func scan(_ buffer: CMSampleBuffer) {
if isScanning { return }

// prepare MLImage
isScanning = true
guard let image = MLImage(sampleBuffer: buffer) else {
isScanning = false
onError(RuntimeError.error(withMessage: "Failed to convert CMSampleBuffer to MLImage!"))
return
}
image.orientation = outputOrientation.toUIImageOrientation()
// start scanning
scanner.process(image) { [weak self] barcodes, error in
guard let self else { return }
self.isScanning = false
if let barcodes {
// scanned x barcodes!
let hybridBarcodes: [any HybridBarcodeSpec] = barcodes.map { HybridBarcode(barcode: $0) }
self.onBarcodeScanned(hybridBarcodes)
}
if let error {
// error
self.onError(error)
}
}
}

func configure(config: CameraOutputConfiguration) {
guard let connection = self.output.connection(with: .video) else {
return
Expand Down
Loading