capacitor-camera-view 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CapacitorCameraView.podspec +1 -1
  2. package/Package.swift +1 -1
  3. package/README.md +341 -49
  4. package/android/build.gradle +0 -1
  5. package/android/src/main/AndroidManifest.xml +0 -1
  6. package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraError.kt +42 -0
  7. package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraView.kt +945 -207
  8. package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraViewPlugin.kt +87 -43
  9. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/BarcodeDetectionResult.kt +28 -2
  10. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/CameraDevice.kt +6 -1
  11. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/CameraSessionConfiguration.kt +15 -1
  12. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/TorchModeState.kt +15 -0
  13. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/WebBoundingRect.kt +1 -1
  14. package/android/src/main/java/com/michaelwolz/capacitorcameraview/utils.kt +73 -19
  15. package/dist/docs.json +475 -30
  16. package/dist/esm/definitions.d.ts +478 -26
  17. package/dist/esm/definitions.js.map +1 -1
  18. package/dist/esm/utils.d.ts +59 -15
  19. package/dist/esm/utils.js +79 -38
  20. package/dist/esm/utils.js.map +1 -1
  21. package/dist/esm/web.d.ts +191 -13
  22. package/dist/esm/web.js +624 -141
  23. package/dist/esm/web.js.map +1 -1
  24. package/dist/plugin.cjs.js +711 -179
  25. package/dist/plugin.cjs.js.map +1 -1
  26. package/dist/plugin.js +711 -179
  27. package/dist/plugin.js.map +1 -1
  28. package/ios/Sources/CameraViewPlugin/CameraError.swift +147 -2
  29. package/ios/Sources/CameraViewPlugin/CameraEvents.swift +41 -19
  30. package/ios/Sources/CameraViewPlugin/CameraSessionConfiguration.swift +29 -1
  31. package/ios/Sources/CameraViewPlugin/CameraViewManager+BarcodeScan.swift +78 -23
  32. package/ios/Sources/CameraViewPlugin/CameraViewManager+DeferredStart.swift +37 -0
  33. package/ios/Sources/CameraViewPlugin/CameraViewManager+Focus.swift +131 -0
  34. package/ios/Sources/CameraViewPlugin/CameraViewManager+Lifecycle.swift +156 -0
  35. package/ios/Sources/CameraViewPlugin/CameraViewManager+PhotoCapture.swift +73 -41
  36. package/ios/Sources/CameraViewPlugin/CameraViewManager+ResolutionSelection.swift +57 -0
  37. package/ios/Sources/CameraViewPlugin/CameraViewManager+Rotation.swift +195 -0
  38. package/ios/Sources/CameraViewPlugin/CameraViewManager+VideoDataOutput.swift +24 -12
  39. package/ios/Sources/CameraViewPlugin/CameraViewManager+VideoRecording.swift +22 -73
  40. package/ios/Sources/CameraViewPlugin/CameraViewManager+Zoom.swift +113 -0
  41. package/ios/Sources/CameraViewPlugin/CameraViewManager.swift +450 -403
  42. package/ios/Sources/CameraViewPlugin/CameraViewPlugin.swift +98 -65
  43. package/ios/Sources/CameraViewPlugin/Utils.swift +61 -7
  44. package/package.json +25 -9
package/dist/docs.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "api": {
3
3
  "name": "CameraViewPlugin",
4
4
  "slug": "cameraviewplugin",
5
- "docs": "Main plugin interface for Capacitor Camera View functionality.",
5
+ "docs": "Main plugin interface for Capacitor Camera View functionality.\n\nWhen a method below rejects, the resulting error carries a `code` property\nset to one of the stable `CameraErrorCode` strings so consumers can\n`switch` on `error.code` instead of matching on the human-readable message.\nSee the `CameraErrorCode` type for the full vocabulary, including the one\ndivergence on web for methods with no web implementation.",
6
6
  "tags": [
7
7
  {
8
8
  "text": "1.0.0",
@@ -35,7 +35,7 @@
35
35
  "text": "1.0.0"
36
36
  }
37
37
  ],
38
- "docs": "Start the camera view with optional configuration.",
38
+ "docs": "Start the camera view with optional configuration.\n\nRejects if a camera session is already running. Call `stop()` first if you need to\nstart a new session with different options.",
39
39
  "complexTypes": [
40
40
  "CameraSessionConfiguration"
41
41
  ],
@@ -83,12 +83,12 @@
83
83
  },
84
84
  {
85
85
  "name": "capture",
86
- "signature": "<T extends CaptureOptions>(options: T) => Promise<CaptureResponse<T>>",
86
+ "signature": "<T extends CaptureOptions = CaptureOptions & { saveToFile?: undefined; }>(options?: T | undefined) => Promise<CaptureResponse<T>>",
87
87
  "parameters": [
88
88
  {
89
89
  "name": "options",
90
90
  "docs": "- Capture configuration options",
91
- "type": "T"
91
+ "type": "T | undefined"
92
92
  }
93
93
  ],
94
94
  "returns": "Promise<CaptureResponse<T>>",
@@ -116,12 +116,12 @@
116
116
  },
117
117
  {
118
118
  "name": "captureSample",
119
- "signature": "<T extends CaptureOptions>(options: T) => Promise<CaptureResponse<T>>",
119
+ "signature": "<T extends CaptureOptions = CaptureOptions & { saveToFile?: undefined; }>(options?: T | undefined) => Promise<CaptureResponse<T>>",
120
120
  "parameters": [
121
121
  {
122
122
  "name": "options",
123
123
  "docs": "- Capture configuration options",
124
- "type": "T"
124
+ "type": "T | undefined"
125
125
  }
126
126
  ],
127
127
  "returns": "Promise<CaptureResponse<T>>",
@@ -214,7 +214,7 @@
214
214
  "text": "1.0.0"
215
215
  }
216
216
  ],
217
- "docs": "Switch between front and back camera.",
217
+ "docs": "Switch between front and back camera.\n\nRejects with `RECORDING_ALREADY_IN_PROGRESS` while a video recording is active, on\niOS, Android, and web alike: swapping the camera input/device mid-recording would\neither drop the audio track or interrupt the recording outright, so the recording is\nleft intact and must be stopped before flipping.",
218
218
  "complexTypes": [],
219
219
  "slug": "flipcamera"
220
220
  },
@@ -258,7 +258,7 @@
258
258
  "text": "1.0.0"
259
259
  }
260
260
  ],
261
- "docs": "Get current zoom level information and available range.",
261
+ "docs": "Get current zoom level information and available range.\n\nOn iOS, when the camera is a virtual device (e.g. the triple camera enabled via\n`useTripleCameraIfAvailable`), the returned values are in the device's raw zoom domain and are\nnot UI multipliers like \"0.5x\"/\"1x\"/\"2x\". A `min` of `1.0` corresponds to the widest constituent\nlens (the ultra-wide \"0.5x\" lens), so a session started at the default zoom reports a `current`\nof the wide-lens switch-over factor (typically `2.0`) rather than `1.0`. Treat these numbers as\ndevice-relative and derive the usable range from `min`/`max` instead of assuming `1.0` is the\ndefault.",
262
262
  "complexTypes": [
263
263
  "GetZoomResponse"
264
264
  ],
@@ -301,10 +301,51 @@
301
301
  "text": "1.0.0"
302
302
  }
303
303
  ],
304
- "docs": "Set the camera zoom level.",
304
+ "docs": "Set the camera zoom level.\n\nOn iOS virtual devices (e.g. the triple camera) `level` is a raw device zoom factor, not a UI\nmultiplier. Derive valid values from the `min`/`max` returned by `getZoom()` rather than assuming\n`1.0` maps to the wide \"1x\" lens.",
305
305
  "complexTypes": [],
306
306
  "slug": "setzoom"
307
307
  },
308
+ {
309
+ "name": "setFocusPoint",
310
+ "signature": "(options: { x: number; y: number; }) => Promise<void>",
311
+ "parameters": [
312
+ {
313
+ "name": "options",
314
+ "docs": "- The point to focus on",
315
+ "type": "{ x: number; y: number; }"
316
+ }
317
+ ],
318
+ "returns": "Promise<void>",
319
+ "tags": [
320
+ {
321
+ "name": "param",
322
+ "text": "options - The point to focus on"
323
+ },
324
+ {
325
+ "name": "param",
326
+ "text": "options.x - The horizontal coordinate in CSS/viewport pixels, measured\nfrom the left edge of the viewport. This is the same coordinate space the\nplugin emits for barcode `boundingRect`, just in the opposite direction."
327
+ },
328
+ {
329
+ "name": "param",
330
+ "text": "options.y - The vertical coordinate in CSS/viewport pixels, measured\nfrom the top edge of the viewport."
331
+ },
332
+ {
333
+ "name": "returns",
334
+ "text": "A promise that resolves when the focus/metering point has been applied"
335
+ },
336
+ {
337
+ "name": "remarks",
338
+ "text": "On fixed-focus cameras (e.g. some front cameras) the plugin degrades to\nexposure-only metering where possible. If neither focus nor exposure metering\nat a point is supported, the promise rejects with the `FOCUS_NOT_SUPPORTED`\nerror code. Rejects with `SESSION_NOT_RUNNING` when the camera is not running.\n\nNot supported on web: this method rejects with an `unimplemented` error there,\nbecause the `pointsOfInterest` media-track constraint has effectively no\nbrowser support."
339
+ },
340
+ {
341
+ "name": "since",
342
+ "text": "3.0.0"
343
+ }
344
+ ],
345
+ "docs": "Focus and meter the camera at a specific point (tap-to-focus).\n\nBecause the WebView sits above the native camera preview and consumes every\ntouch, the native preview can never receive tap gestures itself. Instead,\nthe app catches the tap in the DOM and forwards its coordinates here; since\nthe native preview is always rendered fullscreen behind the WebView, the\nmapping to the sensor is deterministic.\n\nThe camera runs a one-shot focus/exposure at the given point and then\nautomatically restores continuous auto-focus/auto-exposure (immediately on a\nsubsequent tap, or after a short timeout), so focus is never left\npermanently locked.",
346
+ "complexTypes": [],
347
+ "slug": "setfocuspoint"
348
+ },
308
349
  {
309
350
  "name": "getFlashMode",
310
351
  "signature": "() => Promise<GetFlashModeResponse>",
@@ -446,7 +487,7 @@
446
487
  "tags": [
447
488
  {
448
489
  "name": "remarks",
449
- "text": "**Important**: Call `isTorchAvailable()` first to ensure the device supports torch\nfunctionality. This method will throw an exception if torch is not supported.\n\nThe torch provides continuous illumination, unlike flash which only activates during photo capture.\nOn iOS, you can control the torch intensity level. On Android, the torch is either on or off."
490
+ "text": "**Important**: Call `isTorchAvailable()` first to ensure the device supports torch\nfunctionality. This method will throw an exception if torch is not supported.\n\nThe torch provides continuous illumination, unlike flash which only activates during photo capture.\nYou can control the torch intensity level on both iOS and, on API 33+ devices with\nmulti-level torch hardware, Android. On older Android versions or single-level torch\nhardware, `level` is best-effort and ignored - the torch is simply switched on or off."
450
491
  },
451
492
  {
452
493
  "name": "param",
@@ -458,7 +499,7 @@
458
499
  },
459
500
  {
460
501
  "name": "param",
461
- "text": "options.level - The torch intensity level (0.0 to 1.0, iOS only). Defaults to 1.0 when enabled"
502
+ "text": "options.level - The torch intensity level (0.0 to 1.0). Defaults to 1.0 when enabled"
462
503
  },
463
504
  {
464
505
  "name": "returns",
@@ -543,6 +584,10 @@
543
584
  ],
544
585
  "returns": "Promise<PluginListenerHandle>",
545
586
  "tags": [
587
+ {
588
+ "name": "remarks",
589
+ "text": "Events are rate-controlled to avoid flooding the bridge. Repeated detections\nof the same barcode (identical `value` and `type`) are suppressed while the\ncode stays in view: after an initial event, the same code re-emits at most\nonce per ~500 ms suppression window. Pointing the camera at a different\nbarcode (a different `value` or `type`) emits immediately rather than waiting\nfor the window to elapse. This behavior is consistent across iOS, Android,\nand web."
590
+ },
546
591
  {
547
592
  "name": "param",
548
593
  "text": "eventName - The name of the event to listen for ('barcodeDetected')"
@@ -568,20 +613,148 @@
568
613
  "slug": "addlistenerbarcodedetected-"
569
614
  },
570
615
  {
571
- "name": "removeAllListeners",
572
- "signature": "(eventName?: string | undefined) => Promise<void>",
616
+ "name": "addListener",
617
+ "signature": "(eventName: 'cameraInterrupted', listenerFunc: (data: CameraInterruptedData) => void) => Promise<PluginListenerHandle>",
573
618
  "parameters": [
574
619
  {
575
620
  "name": "eventName",
576
- "docs": "- Optional event name to remove listeners for",
577
- "type": "string | undefined"
621
+ "docs": "- The name of the event to listen for ('cameraInterrupted')",
622
+ "type": "'cameraInterrupted'"
623
+ },
624
+ {
625
+ "name": "listenerFunc",
626
+ "docs": "- The callback function to execute when the camera is interrupted",
627
+ "type": "(data: CameraInterruptedData) => void"
578
628
  }
579
629
  ],
580
- "returns": "Promise<void>",
630
+ "returns": "Promise<PluginListenerHandle>",
581
631
  "tags": [
632
+ {
633
+ "name": "remarks",
634
+ "text": "Currently emitted on iOS only. Android and web will follow."
635
+ },
582
636
  {
583
637
  "name": "param",
584
- "text": "eventName - Optional event name to remove listeners for"
638
+ "text": "eventName - The name of the event to listen for ('cameraInterrupted')"
639
+ },
640
+ {
641
+ "name": "param",
642
+ "text": "listenerFunc - The callback function to execute when the camera is interrupted"
643
+ },
644
+ {
645
+ "name": "returns",
646
+ "text": "A promise that resolves with an event subscription"
647
+ },
648
+ {
649
+ "name": "since",
650
+ "text": "3.0.0"
651
+ }
652
+ ],
653
+ "docs": "Listen for camera interruption events.\n\nEmitted when the capture session is interrupted by the system, for example\nan incoming phone call, another app claiming the camera or microphone,\nlosing the camera in iPad Split View, or system pressure. The preview\ntypically freezes for the duration of the interruption.",
654
+ "complexTypes": [
655
+ "PluginListenerHandle",
656
+ "CameraInterruptedData"
657
+ ],
658
+ "slug": "addlistenercamerainterrupted-"
659
+ },
660
+ {
661
+ "name": "addListener",
662
+ "signature": "(eventName: 'cameraResumed', listenerFunc: () => void) => Promise<PluginListenerHandle>",
663
+ "parameters": [
664
+ {
665
+ "name": "eventName",
666
+ "docs": "- The name of the event to listen for ('cameraResumed')",
667
+ "type": "'cameraResumed'"
668
+ },
669
+ {
670
+ "name": "listenerFunc",
671
+ "docs": "- The callback function to execute when the camera resumes",
672
+ "type": "() => void"
673
+ }
674
+ ],
675
+ "returns": "Promise<PluginListenerHandle>",
676
+ "tags": [
677
+ {
678
+ "name": "remarks",
679
+ "text": "Currently emitted on iOS only. Android and web will follow."
680
+ },
681
+ {
682
+ "name": "param",
683
+ "text": "eventName - The name of the event to listen for ('cameraResumed')"
684
+ },
685
+ {
686
+ "name": "param",
687
+ "text": "listenerFunc - The callback function to execute when the camera resumes"
688
+ },
689
+ {
690
+ "name": "returns",
691
+ "text": "A promise that resolves with an event subscription"
692
+ },
693
+ {
694
+ "name": "since",
695
+ "text": "3.0.0"
696
+ }
697
+ ],
698
+ "docs": "Listen for camera resume events.\n\nEmitted when a previous interruption ends and the capture session resumes,\nfor example after an incoming phone call finishes. Pair this with\n`cameraInterrupted` to update your UI when the preview recovers.",
699
+ "complexTypes": [
700
+ "PluginListenerHandle"
701
+ ],
702
+ "slug": "addlistenercameraresumed-"
703
+ },
704
+ {
705
+ "name": "addListener",
706
+ "signature": "(eventName: 'cameraRuntimeError', listenerFunc: (data: CameraRuntimeErrorData) => void) => Promise<PluginListenerHandle>",
707
+ "parameters": [
708
+ {
709
+ "name": "eventName",
710
+ "docs": "- The name of the event to listen for ('cameraRuntimeError')",
711
+ "type": "'cameraRuntimeError'"
712
+ },
713
+ {
714
+ "name": "listenerFunc",
715
+ "docs": "- The callback function to execute when a runtime error occurs",
716
+ "type": "(data: CameraRuntimeErrorData) => void"
717
+ }
718
+ ],
719
+ "returns": "Promise<PluginListenerHandle>",
720
+ "tags": [
721
+ {
722
+ "name": "remarks",
723
+ "text": "Currently emitted on iOS only. Android and web will follow."
724
+ },
725
+ {
726
+ "name": "param",
727
+ "text": "eventName - The name of the event to listen for ('cameraRuntimeError')"
728
+ },
729
+ {
730
+ "name": "param",
731
+ "text": "listenerFunc - The callback function to execute when a runtime error occurs"
732
+ },
733
+ {
734
+ "name": "returns",
735
+ "text": "A promise that resolves with an event subscription"
736
+ },
737
+ {
738
+ "name": "since",
739
+ "text": "3.0.0"
740
+ }
741
+ ],
742
+ "docs": "Listen for camera runtime error events.\n\nEmitted when the capture session hits a runtime error. When the underlying\nmedia services are reset, the plugin restarts the session automatically, so\nthis event is primarily informational for logging and diagnostics.",
743
+ "complexTypes": [
744
+ "PluginListenerHandle",
745
+ "CameraRuntimeErrorData"
746
+ ],
747
+ "slug": "addlistenercameraruntimeerror-"
748
+ },
749
+ {
750
+ "name": "removeAllListeners",
751
+ "signature": "() => Promise<void>",
752
+ "parameters": [],
753
+ "returns": "Promise<void>",
754
+ "tags": [
755
+ {
756
+ "name": "remarks",
757
+ "text": "This removes *every* listener registered on this plugin instance, regardless of event\nname, on iOS, Android, and web. There is no way to remove listeners for a single event\nname only; if you need that, keep track of the `PluginListenerHandle` returned by\n`addListener()` and call `remove()` on it instead."
585
758
  },
586
759
  {
587
760
  "name": "returns",
@@ -675,7 +848,7 @@
675
848
  "name": "default"
676
849
  }
677
850
  ],
678
- "docs": "Whether to use the triple camera if available (iPhone Pro models only)",
851
+ "docs": "Whether to use the triple camera if available (iPhone Pro models only).\n\nThe session starts directly on the virtual device, which lets iOS switch\nbetween the ultra-wide, wide and telephoto lenses automatically. Takes\nprecedence over `preferredCameraDeviceTypes` for the rear camera.",
679
852
  "complexTypes": [],
680
853
  "type": "boolean | undefined"
681
854
  },
@@ -697,6 +870,62 @@
697
870
  ],
698
871
  "type": "CameraDeviceType[] | undefined"
699
872
  },
873
+ {
874
+ "name": "aspectRatio",
875
+ "tags": [
876
+ {
877
+ "text": "undefined - platform default (see above)",
878
+ "name": "default"
879
+ },
880
+ {
881
+ "text": "3.0.0",
882
+ "name": "since"
883
+ }
884
+ ],
885
+ "docs": "The sensor aspect ratio to use for the camera session, applied to both\nthe live preview stream and photo capture so the captured image matches\nthe framing the user sees.\n\n**Preview-vs-capture framing contract** (identical on iOS, Android and\nweb when this option is set):\n\n- By default (`previewScaleMode: 'cover'`) the preview fills its container\n (the fullscreen view behind the WebView on iOS/Android, the container\n element on web) using cover semantics: when the chosen sensor ratio\n differs from the container ratio, the preview is center-cropped to fill\n it — never letterboxed. `capture()` returns the full sensor-ratio image\n (matching this option), NOT the on-screen crop. Parts of the image that\n were cropped out of the preview by cover-scaling are therefore included\n in the capture.\n- With `previewScaleMode: 'fit'` the whole sensor frame is letterboxed to\n fit inside the container, so the preview shows exactly the full captured\n frame: `capture()` returns what the preview shows, with nothing cropped\n out of view. See {@link previewScaleMode} for the letterbox-background\n note.\n\nWhen this option is omitted, each platform keeps its long-standing\ndefault behavior: iOS uses the sensor's native photo format (4:3),\nAndroid prefers 16:9 with an automatic fallback, and web requests a\n16:9 stream and returns the visible (cover-cropped) preview region from\n`capture()` instead of the full frame. Captured output stays JPEG on all\nplatforms either way.",
886
+ "complexTypes": [
887
+ "CameraAspectRatio"
888
+ ],
889
+ "type": "CameraAspectRatio"
890
+ },
891
+ {
892
+ "name": "captureMaxDimension",
893
+ "tags": [
894
+ {
895
+ "text": "1280 // capture photos at most 1280px wide (longer edge)",
896
+ "name": "example"
897
+ },
898
+ {
899
+ "text": "undefined - platform default resolution",
900
+ "name": "default"
901
+ },
902
+ {
903
+ "text": "3.0.0",
904
+ "name": "since"
905
+ }
906
+ ],
907
+ "docs": "Optional capture-resolution hint: an upper bound, in pixels, for the\nlonger edge of captured photos. The platform picks the largest supported\ncapture resolution whose longer edge does not exceed this value (falling\nback to the closest supported resolution when none fits) while keeping\nthe configured `aspectRatio`.\n\nThis is a best-effort hint: the exact output dimensions depend on the\nresolutions the sensor/browser actually supports.\n\n- iOS: constrains `AVCapturePhotoOutput.maxPhotoDimensions`. Only affects\n `capture()`; `captureSample()` keeps sampling the preview stream.\n- Android: bounds the CameraX ImageCapture resolution. Only affects\n `capture()`.\n- Web: used as the ideal `getUserMedia` width constraint, so it affects\n the stream (preview and capture alike).",
908
+ "complexTypes": [],
909
+ "type": "number | undefined"
910
+ },
911
+ {
912
+ "name": "previewScaleMode",
913
+ "tags": [
914
+ {
915
+ "text": "'cover'",
916
+ "name": "default"
917
+ },
918
+ {
919
+ "text": "3.0.0",
920
+ "name": "since"
921
+ }
922
+ ],
923
+ "docs": "How the live preview is scaled into its container when the sensor aspect\nratio differs from the container's aspect ratio.\n\n- `'cover'` (default): the preview fills the container, center-cropping the\n frame. This is the long-standing behavior and is unchanged when the\n option is omitted.\n- `'fit'`: the whole sensor frame is scaled to fit inside the container\n (letterboxed), so the user sees the entire frame they are about to\n capture. In `fit` mode the preview shows exactly the full captured frame,\n and `capture()` returns what the preview shows.\n\nApplied consistently on iOS (`AVCaptureVideoPreviewLayer.videoGravity`),\nAndroid (`PreviewView.ScaleType`) and web (`object-fit`). Barcode\n`boundingRect` and `setFocusPoint` coordinates stay correct in both modes.\n\n**Letterbox background**: the empty bars shown in `fit` mode are not painted\nby the plugin — they show whatever is visually behind/around the preview.\nOn iOS/Android that is the app's own background showing through the\ntransparent WebView; on web it is the container element's background. Style\nthat background (e.g. a black or themed color) to control how the\nletterbox bars look.",
924
+ "complexTypes": [
925
+ "PreviewScaleMode"
926
+ ],
927
+ "type": "PreviewScaleMode"
928
+ },
700
929
  {
701
930
  "name": "zoomFactor",
702
931
  "tags": [
@@ -705,10 +934,26 @@
705
934
  "name": "default"
706
935
  }
707
936
  ],
708
- "docs": "The initial zoom factor to use",
937
+ "docs": "The initial zoom factor to use.\n\nExpressed relative to the wide-angle lens, so `1.0` is the familiar \"1x\" field of view on every\ncamera. On iOS virtual devices whose raw `1.0` is the ultra-wide lens (e.g. the triple camera\nenabled via `useTripleCameraIfAvailable`) the factor is scaled into the device's own zoom domain,\nwhich is why `getZoom()` reports a larger `current` than the value passed here.",
709
938
  "complexTypes": [],
710
939
  "type": "number | undefined"
711
940
  },
941
+ {
942
+ "name": "prioritizeQuality",
943
+ "tags": [
944
+ {
945
+ "text": "false",
946
+ "name": "default"
947
+ },
948
+ {
949
+ "text": "3.0.0",
950
+ "name": "since"
951
+ }
952
+ ],
953
+ "docs": "Prioritize photo quality over capture responsiveness (iOS 17+ only).\n\nBy default the plugin opts into the iOS 17+ responsive-capture pipeline\n(zero-shutter-lag, responsive capture and fast capture prioritization) so\nconsecutive `capture()` calls have a lower shot-to-shot latency. Rapid\nconsecutive captures may then be delivered at a slightly reduced quality\ninstead of queueing.\n\nSet this to `true` to opt out of that behavior and always prioritize photo\nquality. Has no effect on iOS versions or hardware without support for the\nresponsive-capture APIs, and no effect on Android or Web.",
954
+ "complexTypes": [],
955
+ "type": "boolean | undefined"
956
+ },
712
957
  {
713
958
  "name": "containerElementId",
714
959
  "tags": [
@@ -744,6 +989,60 @@
744
989
  }
745
990
  ]
746
991
  },
992
+ {
993
+ "name": "CaptureFileResult",
994
+ "slug": "capturefileresult",
995
+ "docs": "The file-path shaped result returned when `saveToFile` is `true`.",
996
+ "tags": [
997
+ {
998
+ "text": "1.0.0",
999
+ "name": "since"
1000
+ }
1001
+ ],
1002
+ "methods": [],
1003
+ "properties": [
1004
+ {
1005
+ "name": "webPath",
1006
+ "tags": [],
1007
+ "docs": "The web path to the captured photo that can be used to set the src attribute of an image\nfor efficient loading and rendering (when saveToFile is true).\n\nOn web, this is a blob URL created with `URL.createObjectURL()`. The plugin does not revoke\nit automatically; once you are done with it (e.g. after the image has been displayed or\nuploaded), call `URL.revokeObjectURL(webPath)` to release the underlying memory. On\niOS/Android this is a Capacitor bridge path served by the local web server and does not\nneed to be revoked.",
1008
+ "complexTypes": [],
1009
+ "type": "string"
1010
+ },
1011
+ {
1012
+ "name": "path",
1013
+ "tags": [
1014
+ {
1015
+ "text": "2.4.0",
1016
+ "name": "since"
1017
+ }
1018
+ ],
1019
+ "docs": "The full, platform-specific file URL (`file://...`) to the captured photo,\nusable with the Filesystem API or `Capacitor.convertFileSrc()`.\nNative only (iOS/Android); `undefined` on web.",
1020
+ "complexTypes": [],
1021
+ "type": "string | undefined"
1022
+ }
1023
+ ]
1024
+ },
1025
+ {
1026
+ "name": "CaptureBase64Result",
1027
+ "slug": "capturebase64result",
1028
+ "docs": "The base64 shaped result returned when `saveToFile` is `false` or `undefined`.",
1029
+ "tags": [
1030
+ {
1031
+ "text": "1.0.0",
1032
+ "name": "since"
1033
+ }
1034
+ ],
1035
+ "methods": [],
1036
+ "properties": [
1037
+ {
1038
+ "name": "photo",
1039
+ "tags": [],
1040
+ "docs": "The base64 encoded string of the captured photo (when saveToFile is false or undefined)",
1041
+ "complexTypes": [],
1042
+ "type": "string"
1043
+ }
1044
+ ]
1045
+ },
747
1046
  {
748
1047
  "name": "CaptureOptions",
749
1048
  "slug": "captureoptions",
@@ -759,14 +1058,18 @@
759
1058
  {
760
1059
  "name": "quality",
761
1060
  "tags": [
1061
+ {
1062
+ "text": "90",
1063
+ "name": "default"
1064
+ },
762
1065
  {
763
1066
  "text": "1.1.0",
764
1067
  "name": "since"
765
1068
  }
766
1069
  ],
767
- "docs": "The JPEG quality of the captured photo/sample on a scale of 0-100",
1070
+ "docs": "The JPEG quality of the captured photo/sample on a scale of 0-100. Cross-platform note:\nfor `quality >= 90`, iOS returns the original, unmodified JPEG produced by the camera\nhardware instead of re-encoding it, to avoid unnecessary quality loss and CPU overhead.\nAndroid and Web always encode at the exact requested quality. As a result, the same\n`quality` value (90-100) can produce different file sizes on iOS versus Android/Web.",
768
1071
  "complexTypes": [],
769
- "type": "number"
1072
+ "type": "number | undefined"
770
1073
  },
771
1074
  {
772
1075
  "name": "saveToFile",
@@ -854,7 +1157,7 @@
854
1157
  "name": "since"
855
1158
  }
856
1159
  ],
857
- "docs": "Web-accessible path to the recorded video file that can be used to set the\n`src` attribute of a video element for efficient loading and rendering.\nOn web, this is a blob URL.\nOn iOS/Android, this is a Capacitor bridge path served by the local web server.",
1160
+ "docs": "Web-accessible path to the recorded video file that can be used to set the\n`src` attribute of a video element for efficient loading and rendering.\nOn web, this is a blob URL created with `URL.createObjectURL()`; the plugin does not\nrevoke it automatically, so call `URL.revokeObjectURL(webPath)` once you are done with\nit (e.g. after playback or upload) to release the underlying memory.\nOn iOS/Android, this is a Capacitor bridge path served by the local web server and does\nnot need to be revoked.",
858
1161
  "complexTypes": [],
859
1162
  "type": "string"
860
1163
  },
@@ -946,6 +1249,10 @@
946
1249
  "slug": "getzoomresponse",
947
1250
  "docs": "Response for getting zoom level information.",
948
1251
  "tags": [
1252
+ {
1253
+ "text": "On iOS virtual devices (e.g. the triple camera) these values are in the device's raw zoom domain,\nnot UI multipliers: `min` of `1.0` is the ultra-wide (\"0.5x\") lens and `current` reports the\nwide-lens switch-over factor rather than `1.0` at the default zoom. See {@link CameraViewPlugin.getZoom}.",
1254
+ "name": "remarks"
1255
+ },
949
1256
  {
950
1257
  "text": "1.0.0",
951
1258
  "name": "since"
@@ -956,21 +1263,21 @@
956
1263
  {
957
1264
  "name": "min",
958
1265
  "tags": [],
959
- "docs": "The minimum zoom level supported",
1266
+ "docs": "The minimum zoom level supported. On iOS virtual devices `1.0` maps to the ultra-wide lens.",
960
1267
  "complexTypes": [],
961
1268
  "type": "number"
962
1269
  },
963
1270
  {
964
1271
  "name": "max",
965
1272
  "tags": [],
966
- "docs": "The maximum zoom level supported",
1273
+ "docs": "The maximum zoom level supported. On iOS virtual devices this is a raw device factor (capped at a 10x wide-equivalent zoom).",
967
1274
  "complexTypes": [],
968
1275
  "type": "number"
969
1276
  },
970
1277
  {
971
1278
  "name": "current",
972
1279
  "tags": [],
973
- "docs": "The current zoom level",
1280
+ "docs": "The current zoom level. On iOS virtual devices this is a raw device factor, not a UI multiplier.",
974
1281
  "complexTypes": [],
975
1282
  "type": "number"
976
1283
  }
@@ -1065,7 +1372,7 @@
1065
1372
  {
1066
1373
  "name": "level",
1067
1374
  "tags": [],
1068
- "docs": "The current torch intensity level (0.0 to 1.0, iOS only). Always 1.0 on Android when enabled",
1375
+ "docs": "The current torch intensity level (0.0 to 1.0).\n\nOn Android this reflects the real hardware strength only on API 33+ devices with\nmulti-level torch hardware; below API 33, or on single-level hardware, the torch is\nbinary, so this is always 1.0 when enabled and 0.0 when off.",
1069
1376
  "complexTypes": [],
1070
1377
  "type": "number"
1071
1378
  }
@@ -1160,8 +1467,10 @@
1160
1467
  {
1161
1468
  "name": "type",
1162
1469
  "tags": [],
1163
- "docs": "The type/format of the barcode (e.g., 'qr', 'code128', etc.)",
1164
- "complexTypes": [],
1470
+ "docs": "The type/format of the detected barcode.\n\nFor formats that are part of the `BarcodeType` union, all platforms emit\nidentical values, so scanning the same barcode yields the same `type` on\nweb, iOS, and Android (e.g. `'qr'`, `'code128'`, `'dataMatrix'`).\n\nThe type is `BarcodeType | string` rather than `BarcodeType` because a\nplatform detector can occasionally report a format that has no\ncross-platform union member; in that case the raw platform string is\nforwarded unchanged instead of being dropped. In practice this is Android's\n`'unknown'` (ML Kit's `FORMAT_UNKNOWN`) and the equivalent `'unknown'` from\nthe web BarcodeDetector. Narrow against the `BarcodeType` members you care\nabout and treat anything else as an opaque string.\n\nPlatform-specific notes:\n- iOS distinguishes `interleaved2of5` from `itf14`, whereas Android and web\n cannot tell them apart and always report `itf14` for their shared\n interleaved-2-of-5/ITF detector format.\n- UPC-A is reported as `'upcA'` on Android and web, but as `'ean13'` on iOS:\n AVFoundation has no UPC-A metadata type and surfaces UPC-A codes as EAN-13\n (a UPC-A value is an EAN-13 with a leading `0`). This is a hardware/OS\n limitation, not a normalization choice.\n- Codabar is reported as `'codabar'` on all three platforms.",
1471
+ "complexTypes": [
1472
+ "BarcodeType"
1473
+ ],
1165
1474
  "type": "string"
1166
1475
  },
1167
1476
  {
@@ -1178,7 +1487,7 @@
1178
1487
  {
1179
1488
  "name": "BoundingRect",
1180
1489
  "slug": "boundingrect",
1181
- "docs": "Rectangle defining the boundary of the barcode in the camera frame.\nCoordinates are normalized between 0 and 1 relative to the camera frame.",
1490
+ "docs": "Rectangle defining the boundary of the barcode in the camera frame.\nCoordinates are given in display/CSS pixels within the webview (display)\ncoordinate space, not normalized values. This lets you position an overlay\ndirectly on top of the detected barcode without further scaling.",
1182
1491
  "tags": [
1183
1492
  {
1184
1493
  "text": "1.0.0",
@@ -1216,6 +1525,57 @@
1216
1525
  "type": "number"
1217
1526
  }
1218
1527
  ]
1528
+ },
1529
+ {
1530
+ "name": "CameraInterruptedData",
1531
+ "slug": "camerainterrupteddata",
1532
+ "docs": "Data for a camera interruption event.",
1533
+ "tags": [
1534
+ {
1535
+ "text": "3.0.0",
1536
+ "name": "since"
1537
+ }
1538
+ ],
1539
+ "methods": [],
1540
+ "properties": [
1541
+ {
1542
+ "name": "reason",
1543
+ "tags": [],
1544
+ "docs": "The reason the camera session was interrupted.",
1545
+ "complexTypes": [
1546
+ "CameraInterruptionReason"
1547
+ ],
1548
+ "type": "CameraInterruptionReason"
1549
+ }
1550
+ ]
1551
+ },
1552
+ {
1553
+ "name": "CameraRuntimeErrorData",
1554
+ "slug": "cameraruntimeerrordata",
1555
+ "docs": "Data for a camera runtime error event.",
1556
+ "tags": [
1557
+ {
1558
+ "text": "3.0.0",
1559
+ "name": "since"
1560
+ }
1561
+ ],
1562
+ "methods": [],
1563
+ "properties": [
1564
+ {
1565
+ "name": "message",
1566
+ "tags": [],
1567
+ "docs": "A human-readable description of the runtime error.",
1568
+ "complexTypes": [],
1569
+ "type": "string"
1570
+ },
1571
+ {
1572
+ "name": "code",
1573
+ "tags": [],
1574
+ "docs": "The underlying platform error code, when available.\nOn iOS this is the `AVError` code.",
1575
+ "complexTypes": [],
1576
+ "type": "number | undefined"
1577
+ }
1578
+ ]
1219
1579
  }
1220
1580
  ],
1221
1581
  "enums": [],
@@ -1245,6 +1605,10 @@
1245
1605
  "text": "'code93'",
1246
1606
  "complexTypes": []
1247
1607
  },
1608
+ {
1609
+ "text": "'codabar'",
1610
+ "complexTypes": []
1611
+ },
1248
1612
  {
1249
1613
  "text": "'ean8'",
1250
1614
  "complexTypes": []
@@ -1273,6 +1637,10 @@
1273
1637
  "text": "'dataMatrix'",
1274
1638
  "complexTypes": []
1275
1639
  },
1640
+ {
1641
+ "text": "'upcA'",
1642
+ "complexTypes": []
1643
+ },
1276
1644
  {
1277
1645
  "text": "'upce'",
1278
1646
  "complexTypes": []
@@ -1329,13 +1697,59 @@
1329
1697
  }
1330
1698
  ]
1331
1699
  },
1700
+ {
1701
+ "name": "CameraAspectRatio",
1702
+ "slug": "cameraaspectratio",
1703
+ "docs": "Sensor aspect ratio for a camera session, applied consistently to both the\nlive preview stream and photo capture.\n- '4:3': The native photo aspect ratio of most mobile camera sensors\n- '16:9': The typical video aspect ratio",
1704
+ "types": [
1705
+ {
1706
+ "text": "'4:3'",
1707
+ "complexTypes": []
1708
+ },
1709
+ {
1710
+ "text": "'16:9'",
1711
+ "complexTypes": []
1712
+ }
1713
+ ]
1714
+ },
1715
+ {
1716
+ "name": "PreviewScaleMode",
1717
+ "slug": "previewscalemode",
1718
+ "docs": "How the camera preview is scaled to fill its container when the sensor\naspect ratio differs from the container's aspect ratio.\n- 'cover': The preview fills the whole container, center-cropping the frame\n so no empty bars are shown. Parts of the frame outside the container are\n hidden from the preview (long-standing default behavior).\n- 'fit': The whole sensor frame is scaled to fit inside the container\n (letterboxed), so the user sees the entire frame they are about to\n capture. Empty bars appear on the short axis.",
1719
+ "types": [
1720
+ {
1721
+ "text": "'cover'",
1722
+ "complexTypes": []
1723
+ },
1724
+ {
1725
+ "text": "'fit'",
1726
+ "complexTypes": []
1727
+ }
1728
+ ]
1729
+ },
1332
1730
  {
1333
1731
  "name": "CaptureResponse",
1334
1732
  "slug": "captureresponse",
1335
1733
  "docs": "Response for capturing a photo\nThis will contain either a base64 encoded string or a web path to the captured photo,\ndepending on the `saveToFile` option in the CaptureOptions.",
1336
1734
  "types": [
1337
1735
  {
1338
- "text": "T['saveToFile'] extends true\n ? {\n /** The web path to the captured photo that can be used to set the src attribute of an image for efficient loading and rendering (when saveToFile is true) */\n webPath: string;\n\n /**\n * The full, platform-specific file URL (`file://...`) to the captured photo,\n * usable with the Filesystem API or `Capacitor.convertFileSrc()`.\n * Native only (iOS/Android); `undefined` on web.\n * @since 2.4.0\n */\n path?: string;\n }\n : {\n /** The base64 encoded string of the captured photo (when saveToFile is false or undefined) */\n photo: string;\n }",
1736
+ "text": "SaveToFileOf<T> extends true\n ? CaptureFileResult\n : SaveToFileOf<T> extends false | undefined\n ? CaptureBase64Result\n : CaptureFileResult | CaptureBase64Result",
1737
+ "complexTypes": [
1738
+ "SaveToFileOf",
1739
+ "T",
1740
+ "CaptureFileResult",
1741
+ "CaptureBase64Result"
1742
+ ]
1743
+ }
1744
+ ]
1745
+ },
1746
+ {
1747
+ "name": "SaveToFileOf",
1748
+ "slug": "savetofileof",
1749
+ "docs": "`T['saveToFile']` resolves through the `CaptureOptions` constraint to `boolean | undefined`\nwhen `T` omits the key, which would widen the result to the union. Treat an absent key as\n`undefined` instead.",
1750
+ "types": [
1751
+ {
1752
+ "text": "'saveToFile' extends keyof T ? T['saveToFile'] : undefined",
1339
1753
  "complexTypes": [
1340
1754
  "T"
1341
1755
  ]
@@ -1429,6 +1843,37 @@
1429
1843
  "complexTypes": []
1430
1844
  }
1431
1845
  ]
1846
+ },
1847
+ {
1848
+ "name": "CameraInterruptionReason",
1849
+ "slug": "camerainterruptionreason",
1850
+ "docs": "Reason why the camera session was interrupted.\n\nMirrors `AVCaptureSession.InterruptionReason` on iOS. Unknown or future\nreasons fall back to `'unknown'`.",
1851
+ "types": [
1852
+ {
1853
+ "text": "'videoDeviceNotAvailableInBackground'",
1854
+ "complexTypes": []
1855
+ },
1856
+ {
1857
+ "text": "'audioDeviceInUseByAnotherClient'",
1858
+ "complexTypes": []
1859
+ },
1860
+ {
1861
+ "text": "'videoDeviceInUseByAnotherClient'",
1862
+ "complexTypes": []
1863
+ },
1864
+ {
1865
+ "text": "'videoDeviceNotAvailableWithMultipleForegroundApps'",
1866
+ "complexTypes": []
1867
+ },
1868
+ {
1869
+ "text": "'videoDeviceNotAvailableDueToSystemPressure'",
1870
+ "complexTypes": []
1871
+ },
1872
+ {
1873
+ "text": "'unknown'",
1874
+ "complexTypes": []
1875
+ }
1876
+ ]
1432
1877
  }
1433
1878
  ],
1434
1879
  "pluginConfigs": []