@capgo/camera-preview 8.5.0 → 8.6.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.
package/README.md CHANGED
@@ -382,6 +382,10 @@ Documentation for the [uploader](https://github.com/Cap-go/capacitor-uploader)
382
382
  * [`setVideoCodec(...)`](#setvideocodec)
383
383
  * [`getVideoCodec()`](#getvideocodec)
384
384
  * [`getSupportedVideoCodecs()`](#getsupportedvideocodecs)
385
+ * [`isVideoStabilizationSupported()`](#isvideostabilizationsupported)
386
+ * [`getSupportedVideoStabilizationModes()`](#getsupportedvideostabilizationmodes)
387
+ * [`getVideoStabilizationMode()`](#getvideostabilizationmode)
388
+ * [`setVideoStabilizationMode(...)`](#setvideostabilizationmode)
385
389
  * [`isRunning()`](#isrunning)
386
390
  * [`getAvailableDevices()`](#getavailabledevices)
387
391
  * [`getZoom()`](#getzoom)
@@ -755,9 +759,9 @@ startRecordVideo(options: CameraPreviewOptions) => Promise<void>
755
759
 
756
760
  Starts recording a video.
757
761
 
758
- | Param | Type | Description |
759
- | ------------- | --------------------------------------------------------------------- | ---------------------------------- |
760
- | **`options`** | <code><a href="#camerapreviewoptions">CameraPreviewOptions</a></code> | - The options for video recording. |
762
+ | Param | Type | Description |
763
+ | ------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
764
+ | **`options`** | <code><a href="#camerapreviewoptions">CameraPreviewOptions</a></code> | - The options for video recording. Supports `videoCodec`, `videoStabilizationMode`, `maxDuration`, `maxFileSize`, and `disableAudio`. |
761
765
 
762
766
  **Since:** 0.0.1
763
767
 
@@ -858,6 +862,70 @@ Returns the video codecs supported by the active camera.
858
862
  --------------------
859
863
 
860
864
 
865
+ ### isVideoStabilizationSupported()
866
+
867
+ ```typescript
868
+ isVideoStabilizationSupported() => Promise<{ supported: boolean; }>
869
+ ```
870
+
871
+ Checks whether video stabilization is supported by the active camera.
872
+
873
+ **Returns:** <code>Promise&lt;{ supported: boolean; }&gt;</code>
874
+
875
+ **Since:** 8.5.2
876
+
877
+ --------------------
878
+
879
+
880
+ ### getSupportedVideoStabilizationModes()
881
+
882
+ ```typescript
883
+ getSupportedVideoStabilizationModes() => Promise<{ modes: VideoStabilizationMode[]; }>
884
+ ```
885
+
886
+ Returns the video stabilization modes supported by the active camera.
887
+
888
+ **Returns:** <code>Promise&lt;{ modes: VideoStabilizationMode[]; }&gt;</code>
889
+
890
+ **Since:** 8.5.2
891
+
892
+ --------------------
893
+
894
+
895
+ ### getVideoStabilizationMode()
896
+
897
+ ```typescript
898
+ getVideoStabilizationMode() => Promise<{ mode: VideoStabilizationMode; }>
899
+ ```
900
+
901
+ Gets the current video stabilization mode.
902
+
903
+ **Returns:** <code>Promise&lt;{ mode: <a href="#videostabilizationmode">VideoStabilizationMode</a>; }&gt;</code>
904
+
905
+ **Since:** 8.5.2
906
+
907
+ --------------------
908
+
909
+
910
+ ### setVideoStabilizationMode(...)
911
+
912
+ ```typescript
913
+ setVideoStabilizationMode(options: { mode: VideoStabilizationMode; }) => Promise<void>
914
+ ```
915
+
916
+ Sets the video stabilization mode for recording.
917
+ Cannot be changed while a recording is in progress.
918
+ You can also pass `videoStabilizationMode` in `startRecordVideo()` options.
919
+
920
+ | Param | Type | Description |
921
+ | ------------- | ------------------------------------------------------------------------------------ | --------------------------------- |
922
+ | **`options`** | <code>{ mode: <a href="#videostabilizationmode">VideoStabilizationMode</a>; }</code> | - The desired stabilization mode. |
923
+
924
+ **Since:** 8.5.2
925
+
926
+ --------------------
927
+
928
+
861
929
  ### isRunning()
862
930
 
863
931
  ```typescript
@@ -1343,6 +1411,7 @@ Defines the configuration options for starting the camera preview.
1343
1411
  | **`maxDuration`** | <code>number</code> | Maximum recording duration in seconds. Recording stops automatically when reached. | | |
1344
1412
  | **`maxFileSize`** | <code>number</code> | Maximum recording file size in bytes. Recording stops automatically when reached. | | |
1345
1413
  | **`videoCodec`** | <code><a href="#videocodec">VideoCodec</a></code> | Preferred video codec for recording. | <code>"avc1"</code> | |
1414
+ | **`videoStabilizationMode`** | <code><a href="#videostabilizationmode">VideoStabilizationMode</a></code> | Preferred video stabilization mode for recording. | <code>"off"</code> | |
1346
1415
  | **`barcodeScanner`** | <code>boolean \| <a href="#barcodescanneroptions">BarcodeScannerOptions</a></code> | Starts barcode scanning together with the camera preview. Set to `true` or pass options to scan all supported formats. Omit this option to keep barcode scanning disabled at startup. | | 8.8.0 |
1347
1416
 
1348
1417
 
@@ -1563,6 +1632,16 @@ Video codec identifiers used when recording.
1563
1632
  <code>'avc1' | 'hvc1' | 'jpeg' | 'apcn' | 'ap4h'</code>
1564
1633
 
1565
1634
 
1635
+ #### VideoStabilizationMode
1636
+
1637
+ Video stabilization modes used when recording.
1638
+
1639
+ On Android only `off` and `standard` are supported.
1640
+ On iOS all listed modes may be available when the device supports video stabilization.
1641
+
1642
+ <code>'off' | 'standard' | 'cinematic' | 'cinematicExtended' | 'previewOptimized' | 'cinematicExtendedEnhanced' | 'auto' | 'lowLatency'</code>
1643
+
1644
+
1566
1645
  #### BarcodeScannerFormat
1567
1646
 
1568
1647
  <code>'aztec' | 'codabar' | 'code_39' | 'code_93' | 'code_128' | 'data_matrix' | 'ean_8' | 'ean_13' | 'itf' | 'pdf417' | 'qr_code' | 'upc_a' | 'upc_e'</code>
@@ -52,6 +52,7 @@ import com.google.android.gms.location.FusedLocationProviderClient;
52
52
  import com.google.android.gms.location.LocationServices;
53
53
  import java.util.ArrayList;
54
54
  import java.util.Arrays;
55
+ import java.util.Collections;
55
56
  import java.util.List;
56
57
  import java.util.Locale;
57
58
  import java.util.Objects;
@@ -2701,6 +2702,63 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2701
2702
  call.resolve(ret);
2702
2703
  }
2703
2704
 
2705
+ @PluginMethod
2706
+ public void isVideoStabilizationSupported(PluginCall call) {
2707
+ if (cameraXView == null || !cameraXView.isRunning()) {
2708
+ call.reject("Camera is not running");
2709
+ return;
2710
+ }
2711
+ JSObject ret = new JSObject();
2712
+ ret.put("supported", cameraXView.isVideoStabilizationSupported());
2713
+ call.resolve(ret);
2714
+ }
2715
+
2716
+ @PluginMethod
2717
+ public void getSupportedVideoStabilizationModes(PluginCall call) {
2718
+ List<String> modes = cameraXView != null ? cameraXView.getSupportedVideoStabilizationModes() : Collections.singletonList("off");
2719
+ JSONArray arr = new JSONArray();
2720
+ for (String mode : modes) {
2721
+ arr.put(mode);
2722
+ }
2723
+ JSObject ret = new JSObject();
2724
+ ret.put("modes", arr);
2725
+ call.resolve(ret);
2726
+ }
2727
+
2728
+ @PluginMethod
2729
+ public void getVideoStabilizationMode(PluginCall call) {
2730
+ if (cameraXView == null || !cameraXView.isRunning()) {
2731
+ call.reject("Camera is not running");
2732
+ return;
2733
+ }
2734
+ JSObject ret = new JSObject();
2735
+ ret.put("mode", cameraXView.getVideoStabilizationModeSetting());
2736
+ call.resolve(ret);
2737
+ }
2738
+
2739
+ @PluginMethod
2740
+ public void setVideoStabilizationMode(PluginCall call) {
2741
+ if (cameraXView == null || !cameraXView.isRunning()) {
2742
+ call.reject("Camera is not running");
2743
+ return;
2744
+ }
2745
+ String mode = call.getString("mode");
2746
+ if (mode == null) {
2747
+ call.reject("mode is required");
2748
+ return;
2749
+ }
2750
+ try {
2751
+ cameraXView.setVideoStabilizationModeSetting(mode);
2752
+ call.resolve();
2753
+ } catch (IllegalArgumentException e) {
2754
+ call.reject(e.getMessage());
2755
+ } catch (IllegalStateException e) {
2756
+ call.reject(e.getMessage());
2757
+ } catch (Exception e) {
2758
+ call.reject("Failed to set video stabilization mode: " + e.getMessage());
2759
+ }
2760
+ }
2761
+
2704
2762
  @PluginMethod
2705
2763
  public void startRecordVideo(PluginCall call) {
2706
2764
  if (cameraXView == null || !cameraXView.isRunning()) {
@@ -2717,6 +2775,7 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2717
2775
  if (PermissionState.GRANTED.equals(getPermissionState(permissionAlias))) {
2718
2776
  try {
2719
2777
  applyVideoCodecFromCall(call);
2778
+ applyVideoStabilizationFromCall(call);
2720
2779
  cameraXView.startRecordVideo(getMaxDurationMillis(call), getMaxFileSize(call));
2721
2780
  call.resolve();
2722
2781
  } catch (Exception e) {
@@ -2773,6 +2832,13 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2773
2832
  }
2774
2833
  }
2775
2834
 
2835
+ private void applyVideoStabilizationFromCall(PluginCall call) {
2836
+ String mode = call.getString("videoStabilizationMode");
2837
+ if (mode != null && cameraXView != null) {
2838
+ cameraXView.setVideoStabilizationModeSetting(mode);
2839
+ }
2840
+ }
2841
+
2776
2842
  private Long getMaxDurationMillis(PluginCall call) {
2777
2843
  if (!call.getData().has("maxDuration") || call.getData().isNull("maxDuration")) {
2778
2844
  return null;
@@ -2804,6 +2870,7 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2804
2870
  ) {
2805
2871
  try {
2806
2872
  applyVideoCodecFromCall(call);
2873
+ applyVideoStabilizationFromCall(call);
2807
2874
  cameraXView.startRecordVideo(getMaxDurationMillis(call), getMaxFileSize(call));
2808
2875
  call.resolve();
2809
2876
  } catch (Exception e) {
@@ -1139,7 +1139,9 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
1139
1139
  recorderBuilder.setVideoCapabilitiesSource(Recorder.VIDEO_CAPABILITIES_SOURCE_CODEC_CAPABILITIES);
1140
1140
  }
1141
1141
  Recorder recorder = recorderBuilder.build();
1142
- videoCapture = VideoCapture.withOutput(recorder);
1142
+ VideoCapture.Builder<Recorder> videoCaptureBuilder = new VideoCapture.Builder<>(recorder);
1143
+ videoCaptureBuilder.setVideoStabilizationEnabled(isVideoStabilizationEnabledForSession());
1144
+ videoCapture = videoCaptureBuilder.build();
1143
1145
  }
1144
1146
 
1145
1147
  // Unbind any existing use cases and bind new ones
@@ -4785,6 +4787,15 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
4785
4787
  private static final List<String> ALL_VIDEO_QUALITIES = Arrays.asList("low", "medium", "high", "2160p", "1080p", "720p", "480p", "4:3");
4786
4788
 
4787
4789
  private static final List<String> ALL_VIDEO_CODECS = Arrays.asList("avc1", "hvc1");
4790
+ private static final List<String> ALL_VIDEO_STABILIZATION_MODES = Arrays.asList("off", "standard");
4791
+ private static final List<String> IOS_ONLY_VIDEO_STABILIZATION_MODES = Arrays.asList(
4792
+ "cinematic",
4793
+ "cinematicExtended",
4794
+ "previewOptimized",
4795
+ "cinematicExtendedEnhanced",
4796
+ "auto",
4797
+ "lowLatency"
4798
+ );
4788
4799
 
4789
4800
  public String getVideoQualitySetting() {
4790
4801
  if (sessionConfig == null) {
@@ -4864,4 +4875,86 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
4864
4875
  }
4865
4876
  return false;
4866
4877
  }
4878
+
4879
+ public boolean isVideoStabilizationSupported() {
4880
+ return isStandardVideoStabilizationSupported();
4881
+ }
4882
+
4883
+ public List<String> getSupportedVideoStabilizationModes() {
4884
+ List<String> modes = new ArrayList<>();
4885
+ modes.add("off");
4886
+ if (isStandardVideoStabilizationSupported()) {
4887
+ modes.add("standard");
4888
+ }
4889
+ return modes;
4890
+ }
4891
+
4892
+ public String getVideoStabilizationModeSetting() {
4893
+ if (sessionConfig == null) {
4894
+ return "off";
4895
+ }
4896
+ return sessionConfig.getVideoStabilizationMode();
4897
+ }
4898
+
4899
+ public void setVideoStabilizationModeSetting(String mode) {
4900
+ if (sessionConfig == null) {
4901
+ throw new IllegalStateException("Camera session is not running");
4902
+ }
4903
+ if (currentRecording != null) {
4904
+ throw new IllegalStateException("Cannot change video stabilization while recording is in progress");
4905
+ }
4906
+ String normalized = mode != null ? mode : "off";
4907
+ if (IOS_ONLY_VIDEO_STABILIZATION_MODES.contains(normalized)) {
4908
+ throw new IllegalArgumentException(
4909
+ "Video stabilization mode '" + normalized + "' is only supported on iOS. Use 'off' or 'standard' on Android."
4910
+ );
4911
+ }
4912
+ if (!ALL_VIDEO_STABILIZATION_MODES.contains(normalized)) {
4913
+ throw new IllegalArgumentException("Unsupported video stabilization mode: " + mode);
4914
+ }
4915
+ if ("standard".equals(normalized) && !isStandardVideoStabilizationSupported()) {
4916
+ throw new IllegalArgumentException("Video stabilization mode 'standard' is not supported on this device");
4917
+ }
4918
+ if (normalized.equals(sessionConfig.getVideoStabilizationMode())) {
4919
+ return;
4920
+ }
4921
+ sessionConfig.setVideoStabilizationMode(normalized);
4922
+ if (sessionConfig.isVideoModeEnabled() && isRunning) {
4923
+ mainExecutor.execute(this::bindCameraUseCases);
4924
+ }
4925
+ }
4926
+
4927
+ private boolean isVideoStabilizationEnabledForSession() {
4928
+ if (sessionConfig == null) {
4929
+ return false;
4930
+ }
4931
+ return "standard".equalsIgnoreCase(sessionConfig.getVideoStabilizationMode());
4932
+ }
4933
+
4934
+ private boolean isStandardVideoStabilizationSupported() {
4935
+ if (camera == null) {
4936
+ return false;
4937
+ }
4938
+ try {
4939
+ String cameraId = Camera2CameraInfo.from(camera.getCameraInfo()).getCameraId();
4940
+ CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
4941
+ if (cameraManager == null) {
4942
+ return false;
4943
+ }
4944
+ int[] modes = cameraManager
4945
+ .getCameraCharacteristics(cameraId)
4946
+ .get(CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
4947
+ if (modes == null) {
4948
+ return false;
4949
+ }
4950
+ for (int availableMode : modes) {
4951
+ if (availableMode == CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE_ON) {
4952
+ return true;
4953
+ }
4954
+ }
4955
+ } catch (CameraAccessException e) {
4956
+ Log.w(TAG, "Failed to read video stabilization modes", e);
4957
+ }
4958
+ return false;
4959
+ }
4867
4960
  }
@@ -27,6 +27,7 @@ public class CameraSessionConfiguration {
27
27
  private boolean isCentered = false;
28
28
  private String videoQuality;
29
29
  private String videoCodec = "avc1";
30
+ private String videoStabilizationMode = "off";
30
31
  private boolean enablePhysicalDeviceSelection = false;
31
32
  private boolean barcodeScannerEnabled = false;
32
33
 
@@ -160,6 +161,14 @@ public class CameraSessionConfiguration {
160
161
  this.videoCodec = codec != null ? codec : "avc1";
161
162
  }
162
163
 
164
+ public String getVideoStabilizationMode() {
165
+ return videoStabilizationMode;
166
+ }
167
+
168
+ public void setVideoStabilizationMode(String mode) {
169
+ this.videoStabilizationMode = mode != null ? mode : "off";
170
+ }
171
+
163
172
  public boolean isPhysicalDeviceSelectionEnabled() {
164
173
  return enablePhysicalDeviceSelection;
165
174
  }
package/dist/docs.json CHANGED
@@ -520,7 +520,7 @@
520
520
  "parameters": [
521
521
  {
522
522
  "name": "options",
523
- "docs": "- The options for video recording.",
523
+ "docs": "- The options for video recording. Supports `videoCodec`, `videoStabilizationMode`, `maxDuration`, `maxFileSize`, and `disableAudio`.",
524
524
  "type": "CameraPreviewOptions"
525
525
  }
526
526
  ],
@@ -528,7 +528,7 @@
528
528
  "tags": [
529
529
  {
530
530
  "name": "param",
531
- "text": "options - The options for video recording."
531
+ "text": "options - The options for video recording. Supports `videoCodec`, `videoStabilizationMode`, `maxDuration`, `maxFileSize`, and `disableAudio`."
532
532
  },
533
533
  {
534
534
  "name": "returns",
@@ -715,6 +715,114 @@
715
715
  ],
716
716
  "slug": "getsupportedvideocodecs"
717
717
  },
718
+ {
719
+ "name": "isVideoStabilizationSupported",
720
+ "signature": "() => Promise<{ supported: boolean; }>",
721
+ "parameters": [],
722
+ "returns": "Promise<{ supported: boolean; }>",
723
+ "tags": [
724
+ {
725
+ "name": "returns",
726
+ "text": "A promise that resolves with the support state."
727
+ },
728
+ {
729
+ "name": "since",
730
+ "text": "8.5.2"
731
+ },
732
+ {
733
+ "name": "platform",
734
+ "text": "android, ios"
735
+ }
736
+ ],
737
+ "docs": "Checks whether video stabilization is supported by the active camera.",
738
+ "complexTypes": [],
739
+ "slug": "isvideostabilizationsupported"
740
+ },
741
+ {
742
+ "name": "getSupportedVideoStabilizationModes",
743
+ "signature": "() => Promise<{ modes: VideoStabilizationMode[]; }>",
744
+ "parameters": [],
745
+ "returns": "Promise<{ modes: VideoStabilizationMode[]; }>",
746
+ "tags": [
747
+ {
748
+ "name": "returns",
749
+ "text": "A promise that resolves with supported modes."
750
+ },
751
+ {
752
+ "name": "since",
753
+ "text": "8.5.2"
754
+ },
755
+ {
756
+ "name": "platform",
757
+ "text": "android, ios"
758
+ }
759
+ ],
760
+ "docs": "Returns the video stabilization modes supported by the active camera.",
761
+ "complexTypes": [
762
+ "VideoStabilizationMode"
763
+ ],
764
+ "slug": "getsupportedvideostabilizationmodes"
765
+ },
766
+ {
767
+ "name": "getVideoStabilizationMode",
768
+ "signature": "() => Promise<{ mode: VideoStabilizationMode; }>",
769
+ "parameters": [],
770
+ "returns": "Promise<{ mode: VideoStabilizationMode; }>",
771
+ "tags": [
772
+ {
773
+ "name": "returns",
774
+ "text": "A promise that resolves with the current mode."
775
+ },
776
+ {
777
+ "name": "since",
778
+ "text": "8.5.2"
779
+ },
780
+ {
781
+ "name": "platform",
782
+ "text": "android, ios"
783
+ }
784
+ ],
785
+ "docs": "Gets the current video stabilization mode.",
786
+ "complexTypes": [
787
+ "VideoStabilizationMode"
788
+ ],
789
+ "slug": "getvideostabilizationmode"
790
+ },
791
+ {
792
+ "name": "setVideoStabilizationMode",
793
+ "signature": "(options: { mode: VideoStabilizationMode; }) => Promise<void>",
794
+ "parameters": [
795
+ {
796
+ "name": "options",
797
+ "docs": "- The desired stabilization mode.",
798
+ "type": "{ mode: VideoStabilizationMode; }"
799
+ }
800
+ ],
801
+ "returns": "Promise<void>",
802
+ "tags": [
803
+ {
804
+ "name": "param",
805
+ "text": "options - The desired stabilization mode."
806
+ },
807
+ {
808
+ "name": "returns",
809
+ "text": "A promise that resolves when the mode is set."
810
+ },
811
+ {
812
+ "name": "since",
813
+ "text": "8.5.2"
814
+ },
815
+ {
816
+ "name": "platform",
817
+ "text": "android, ios"
818
+ }
819
+ ],
820
+ "docs": "Sets the video stabilization mode for recording.\nCannot be changed while a recording is in progress.\nYou can also pass `videoStabilizationMode` in `startRecordVideo()` options.",
821
+ "complexTypes": [
822
+ "VideoStabilizationMode"
823
+ ],
824
+ "slug": "setvideostabilizationmode"
825
+ },
718
826
  {
719
827
  "name": "isRunning",
720
828
  "signature": "() => Promise<{ isRunning: boolean; }>",
@@ -1777,7 +1885,7 @@
1777
1885
  "name": "default"
1778
1886
  },
1779
1887
  {
1780
- "text": "android",
1888
+ "text": "android, ios",
1781
1889
  "name": "platform"
1782
1890
  },
1783
1891
  {
@@ -1873,6 +1981,24 @@
1873
1981
  ],
1874
1982
  "type": "VideoCodec"
1875
1983
  },
1984
+ {
1985
+ "name": "videoStabilizationMode",
1986
+ "tags": [
1987
+ {
1988
+ "text": "ios, android",
1989
+ "name": "platform"
1990
+ },
1991
+ {
1992
+ "text": "\"off\"",
1993
+ "name": "default"
1994
+ }
1995
+ ],
1996
+ "docs": "Preferred video stabilization mode for recording.",
1997
+ "complexTypes": [
1998
+ "VideoStabilizationMode"
1999
+ ],
2000
+ "type": "VideoStabilizationMode"
2001
+ },
1876
2002
  {
1877
2003
  "name": "barcodeScanner",
1878
2004
  "tags": [
@@ -2713,6 +2839,45 @@
2713
2839
  }
2714
2840
  ]
2715
2841
  },
2842
+ {
2843
+ "name": "VideoStabilizationMode",
2844
+ "slug": "videostabilizationmode",
2845
+ "docs": "Video stabilization modes used when recording.\n\nOn Android only `off` and `standard` are supported.\nOn iOS all listed modes may be available when the device supports video stabilization.",
2846
+ "types": [
2847
+ {
2848
+ "text": "'off'",
2849
+ "complexTypes": []
2850
+ },
2851
+ {
2852
+ "text": "'standard'",
2853
+ "complexTypes": []
2854
+ },
2855
+ {
2856
+ "text": "'cinematic'",
2857
+ "complexTypes": []
2858
+ },
2859
+ {
2860
+ "text": "'cinematicExtended'",
2861
+ "complexTypes": []
2862
+ },
2863
+ {
2864
+ "text": "'previewOptimized'",
2865
+ "complexTypes": []
2866
+ },
2867
+ {
2868
+ "text": "'cinematicExtendedEnhanced'",
2869
+ "complexTypes": []
2870
+ },
2871
+ {
2872
+ "text": "'auto'",
2873
+ "complexTypes": []
2874
+ },
2875
+ {
2876
+ "text": "'lowLatency'",
2877
+ "complexTypes": []
2878
+ }
2879
+ ]
2880
+ },
2716
2881
  {
2717
2882
  "name": "BarcodeScannerFormat",
2718
2883
  "slug": "barcodescannerformat",
@@ -114,6 +114,13 @@ export type VideoQuality = 'low' | 'medium' | 'high' | '2160p' | '1080p' | '720p
114
114
  * - `hvc1`: HEVC / H.265
115
115
  */
116
116
  export type VideoCodec = 'avc1' | 'hvc1' | 'jpeg' | 'apcn' | 'ap4h';
117
+ /**
118
+ * Video stabilization modes used when recording.
119
+ *
120
+ * On Android only `off` and `standard` are supported.
121
+ * On iOS all listed modes may be available when the device supports video stabilization.
122
+ */
123
+ export type VideoStabilizationMode = 'off' | 'standard' | 'cinematic' | 'cinematicExtended' | 'previewOptimized' | 'cinematicExtendedEnhanced' | 'auto' | 'lowLatency';
117
124
  export type RecordingFinishedReason = 'manual' | 'maxDuration' | 'maxFileSize';
118
125
  export interface RecordingFinishedEvent {
119
126
  /**
@@ -274,7 +281,7 @@ export interface CameraPreviewOptions {
274
281
  /**
275
282
  * If true, enables video capture capabilities when the camera starts.
276
283
  * @default false
277
- * @platform android
284
+ * @platform android, ios
278
285
  * @since 7.11.0
279
286
  */
280
287
  enableVideoMode?: boolean;
@@ -310,6 +317,12 @@ export interface CameraPreviewOptions {
310
317
  * @default "avc1"
311
318
  */
312
319
  videoCodec?: VideoCodec;
320
+ /**
321
+ * Preferred video stabilization mode for recording.
322
+ * @platform ios, android
323
+ * @default "off"
324
+ */
325
+ videoStabilizationMode?: VideoStabilizationMode;
313
326
  /**
314
327
  * Starts barcode scanning together with the camera preview.
315
328
  * Set to `true` or pass options to scan all supported formats.
@@ -658,7 +671,7 @@ export interface CameraPreviewPlugin {
658
671
  /**
659
672
  * Starts recording a video.
660
673
  *
661
- * @param {CameraPreviewOptions} options - The options for video recording.
674
+ * @param {CameraPreviewOptions} options - The options for video recording. Supports `videoCodec`, `videoStabilizationMode`, `maxDuration`, `maxFileSize`, and `disableAudio`.
662
675
  * @returns {Promise<void>} A promise that resolves when video recording starts.
663
676
  * @since 0.0.1
664
677
  */
@@ -725,6 +738,49 @@ export interface CameraPreviewPlugin {
725
738
  getSupportedVideoCodecs(): Promise<{
726
739
  codecs: VideoCodec[];
727
740
  }>;
741
+ /**
742
+ * Checks whether video stabilization is supported by the active camera.
743
+ *
744
+ * @returns {Promise<{ supported: boolean }>} A promise that resolves with the support state.
745
+ * @since 8.5.2
746
+ * @platform android, ios
747
+ */
748
+ isVideoStabilizationSupported(): Promise<{
749
+ supported: boolean;
750
+ }>;
751
+ /**
752
+ * Returns the video stabilization modes supported by the active camera.
753
+ *
754
+ * @returns {Promise<{ modes: VideoStabilizationMode[] }>} A promise that resolves with supported modes.
755
+ * @since 8.5.2
756
+ * @platform android, ios
757
+ */
758
+ getSupportedVideoStabilizationModes(): Promise<{
759
+ modes: VideoStabilizationMode[];
760
+ }>;
761
+ /**
762
+ * Gets the current video stabilization mode.
763
+ *
764
+ * @returns {Promise<{ mode: VideoStabilizationMode }>} A promise that resolves with the current mode.
765
+ * @since 8.5.2
766
+ * @platform android, ios
767
+ */
768
+ getVideoStabilizationMode(): Promise<{
769
+ mode: VideoStabilizationMode;
770
+ }>;
771
+ /**
772
+ * Sets the video stabilization mode for recording.
773
+ * Cannot be changed while a recording is in progress.
774
+ * You can also pass `videoStabilizationMode` in `startRecordVideo()` options.
775
+ *
776
+ * @param {{ mode: VideoStabilizationMode }} options - The desired stabilization mode.
777
+ * @returns {Promise<void>} A promise that resolves when the mode is set.
778
+ * @since 8.5.2
779
+ * @platform android, ios
780
+ */
781
+ setVideoStabilizationMode(options: {
782
+ mode: VideoStabilizationMode;
783
+ }): Promise<void>;
728
784
  /**
729
785
  * Checks if the camera preview is currently running.
730
786
  *