Skip to content

Commit 82f8b25

Browse files
Merge pull request juliansteenbakker#1600 from nngb102/fix/issue_1578
fix: improve pixel format selection for video output on iPhone 17
2 parents 4bd2a94 + 51055a5 commit 82f8b25

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 7.1.4
2+
3+
* [Apple] Fixed crash on iPhone 17 when starting MobileScanner by checking available pixel formats before setting video output settings. ([#1578](https://github.com/juliansteenbakker/mobile_scanner/issues/1578))
4+
15
### 7.1.3
26

37
* Overlay: Updated `BarcodePainter` to receive `deviceOrientation` and dynamically adjust `cameraPreviewSize`, fixing barcode overlay misalignment during device rotation changes [](https://github.com/juliansteenbakker/mobile_scanner/issues/1462).

darwin/mobile_scanner/Sources/mobile_scanner/MobileScannerPlugin.swift

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -455,17 +455,15 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
455455
}
456456
captureSession!.sessionPreset = AVCaptureSession.Preset.high
457457

458-
// Add video output
459458
let videoOutput = AVCaptureVideoDataOutput()
460-
videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA]
461-
videoOutput.alwaysDiscardsLateVideoFrames = true
462459

460+
let format = getPreferredVideoFormat(videoOutput: videoOutput)
461+
videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: format]
462+
videoOutput.alwaysDiscardsLateVideoFrames = true
463463
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main)
464464
captureSession!.addOutput(videoOutput)
465465
let deviceVideoOrientation = self.getVideoOrientation()
466-
467466

468-
// Adjust orientation for the video connection
469467
if let connection = videoOutput.connections.first {
470468
if connection.isVideoOrientationSupported {
471469
connection.videoOrientation = deviceVideoOrientation
@@ -478,7 +476,6 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
478476

479477
captureSession!.commitConfiguration()
480478

481-
// Move startRunning to a background thread to avoid blocking the main UI thread.
482479
DispatchQueue.global(qos: .background).async {
483480
self.captureSession!.startRunning()
484481

@@ -491,12 +488,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
491488
dimensions = CMVideoDimensions()
492489
}
493490

494-
// Turn on the torch if requested.
495491
if (torch) {
496492
self.turnTorchOn()
497493
}
498494

499-
// Set the initial zoom factor
500495
if (initialZoom != nil) {
501496
do {
502497
try self.setScaleInternal(initialZoom!)
@@ -543,6 +538,34 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
543538
}
544539
}
545540

541+
/// Get the preferred video format for the given video output.
542+
private func getPreferredVideoFormat(videoOutput: AVCaptureVideoDataOutput) -> OSType {
543+
// Define preferred pixel formats in order of preference
544+
let preferredFormats: [OSType] = [
545+
kCVPixelFormatType_32BGRA,
546+
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
547+
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
548+
]
549+
550+
// Get available formats and convert from NSNumber to OSType
551+
let availableFormats = videoOutput.availableVideoPixelFormatTypes
552+
let availablePixelFormats = availableFormats.compactMap { ($0 as NSNumber).uint32Value }
553+
554+
// Find the first preferred format that is available
555+
for format in preferredFormats {
556+
if availablePixelFormats.contains(format) {
557+
return format
558+
}
559+
}
560+
561+
if let firstAvailable = availablePixelFormats.first {
562+
return firstAvailable
563+
}
564+
565+
// Ultimate fallback: use the original default format
566+
return kCVPixelFormatType_32BGRA
567+
}
568+
546569
/// Turn the torch on.
547570
private func turnTorchOn() {
548571
guard let device = self.device else {

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: mobile_scanner
22
description: A universal Flutter barcode and QR code scanner using CameraX/ML Kit for Android, AVFoundation/Apple Vision for iOS & macOS, and ZXing for web.
3-
version: 7.1.3
3+
version: 7.1.4
44
repository: https://github.com/juliansteenbakker/mobile_scanner
55

66
screenshots:

0 commit comments

Comments
 (0)