@capgo/camera-preview 8.5.1 → 8.7.1

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)
@@ -408,6 +412,9 @@ Documentation for the [uploader](https://github.com/Cap-go/capacitor-uploader)
408
412
  * [`getExposureCompensationRange()`](#getexposurecompensationrange)
409
413
  * [`getExposureCompensation()`](#getexposurecompensation)
410
414
  * [`setExposureCompensation(...)`](#setexposurecompensation)
415
+ * [`getSupportedVideoFrameRates()`](#getsupportedvideoframerates)
416
+ * [`getVideoFrameRate()`](#getvideoframerate)
417
+ * [`setVideoFrameRate(...)`](#setvideoframerate)
411
418
  * [`getPluginVersion()`](#getpluginversion)
412
419
  * [Interfaces](#interfaces)
413
420
  * [Type Aliases](#type-aliases)
@@ -755,6 +762,8 @@ startRecordVideo(options: CameraPreviewOptions) => Promise<void>
755
762
 
756
763
  Starts recording a video.
757
764
 
765
+ Supports `frameRate`, `videoCodec`, `videoStabilizationMode`, `maxDuration`, `maxFileSize`, and `disableAudio` on each call.
766
+
758
767
  | Param | Type | Description |
759
768
  | ------------- | --------------------------------------------------------------------- | ---------------------------------- |
760
769
  | **`options`** | <code><a href="#camerapreviewoptions">CameraPreviewOptions</a></code> | - The options for video recording. |
@@ -858,6 +867,70 @@ Returns the video codecs supported by the active camera.
858
867
  --------------------
859
868
 
860
869
 
870
+ ### isVideoStabilizationSupported()
871
+
872
+ ```typescript
873
+ isVideoStabilizationSupported() => Promise<{ supported: boolean; }>
874
+ ```
875
+
876
+ Checks whether video stabilization is supported by the active camera.
877
+
878
+ **Returns:** <code>Promise&lt;{ supported: boolean; }&gt;</code>
879
+
880
+ **Since:** 8.5.2
881
+
882
+ --------------------
883
+
884
+
885
+ ### getSupportedVideoStabilizationModes()
886
+
887
+ ```typescript
888
+ getSupportedVideoStabilizationModes() => Promise<{ modes: VideoStabilizationMode[]; }>
889
+ ```
890
+
891
+ Returns the video stabilization modes supported by the active camera.
892
+
893
+ **Returns:** <code>Promise&lt;{ modes: VideoStabilizationMode[]; }&gt;</code>
894
+
895
+ **Since:** 8.5.2
896
+
897
+ --------------------
898
+
899
+
900
+ ### getVideoStabilizationMode()
901
+
902
+ ```typescript
903
+ getVideoStabilizationMode() => Promise<{ mode: VideoStabilizationMode; }>
904
+ ```
905
+
906
+ Gets the current video stabilization mode.
907
+
908
+ **Returns:** <code>Promise&lt;{ mode: <a href="#videostabilizationmode">VideoStabilizationMode</a>; }&gt;</code>
909
+
910
+ **Since:** 8.5.2
911
+
912
+ --------------------
913
+
914
+
915
+ ### setVideoStabilizationMode(...)
916
+
917
+ ```typescript
918
+ setVideoStabilizationMode(options: { mode: VideoStabilizationMode; }) => Promise<void>
919
+ ```
920
+
921
+ Sets the video stabilization mode for recording.
922
+ Cannot be changed while a recording is in progress.
923
+ You can also pass `videoStabilizationMode` in `startRecordVideo()` options.
924
+
925
+ | Param | Type | Description |
926
+ | ------------- | ------------------------------------------------------------------------------------ | --------------------------------- |
927
+ | **`options`** | <code>{ mode: <a href="#videostabilizationmode">VideoStabilizationMode</a>; }</code> | - The desired stabilization mode. |
928
+
929
+ **Since:** 8.5.2
930
+
931
+ --------------------
932
+
933
+
861
934
  ### isRunning()
862
935
 
863
936
  ```typescript
@@ -1291,6 +1364,57 @@ Sets the exposure compensation (EV bias). Value will be clamped to range.
1291
1364
  --------------------
1292
1365
 
1293
1366
 
1367
+ ### getSupportedVideoFrameRates()
1368
+
1369
+ ```typescript
1370
+ getSupportedVideoFrameRates() => Promise<{ frameRates: number[]; }>
1371
+ ```
1372
+
1373
+ Lists the video frame rates supported by the active camera for the current format.
1374
+ Supported values depend on the selected camera, lens, and video quality.
1375
+
1376
+ **Returns:** <code>Promise&lt;{ frameRates: number[]; }&gt;</code>
1377
+
1378
+ **Since:** 8.6.0
1379
+
1380
+ --------------------
1381
+
1382
+
1383
+ ### getVideoFrameRate()
1384
+
1385
+ ```typescript
1386
+ getVideoFrameRate() => Promise<{ frameRate: number; }>
1387
+ ```
1388
+
1389
+ Returns the configured video frame rate for the active camera.
1390
+ On Android the actual recording frame rate can still vary in low light or under thermal pressure.
1391
+
1392
+ **Returns:** <code>Promise&lt;{ frameRate: number; }&gt;</code>
1393
+
1394
+ **Since:** 8.6.0
1395
+
1396
+ --------------------
1397
+
1398
+
1399
+ ### setVideoFrameRate(...)
1400
+
1401
+ ```typescript
1402
+ setVideoFrameRate(options: { frameRate: number; }) => Promise<void>
1403
+ ```
1404
+
1405
+ Sets the target video frame rate for the active camera session.
1406
+ Prefer passing `frameRate` to `startRecordVideo()` when starting a recording.
1407
+ Rejects unsupported values with a clear error.
1408
+
1409
+ | Param | Type |
1410
+ | ------------- | ----------------------------------- |
1411
+ | **`options`** | <code>{ frameRate: number; }</code> |
1412
+
1413
+ **Since:** 8.6.0
1414
+
1415
+ --------------------
1416
+
1417
+
1294
1418
  ### getPluginVersion()
1295
1419
 
1296
1420
  ```typescript
@@ -1343,6 +1467,8 @@ Defines the configuration options for starting the camera preview.
1343
1467
  | **`maxDuration`** | <code>number</code> | Maximum recording duration in seconds. Recording stops automatically when reached. | | |
1344
1468
  | **`maxFileSize`** | <code>number</code> | Maximum recording file size in bytes. Recording stops automatically when reached. | | |
1345
1469
  | **`videoCodec`** | <code><a href="#videocodec">VideoCodec</a></code> | Preferred video codec for recording. | <code>"avc1"</code> | |
1470
+ | **`frameRate`** | <code>number</code> | Target video frame rate in frames per second. Applied when recording starts. Use `getSupportedVideoFrameRates()` to list supported values. | | 8.6.0 |
1471
+ | **`videoStabilizationMode`** | <code><a href="#videostabilizationmode">VideoStabilizationMode</a></code> | Preferred video stabilization mode for recording. | <code>"off"</code> | |
1346
1472
  | **`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
1473
 
1348
1474
 
@@ -1563,6 +1689,16 @@ Video codec identifiers used when recording.
1563
1689
  <code>'avc1' | 'hvc1' | 'jpeg' | 'apcn' | 'ap4h'</code>
1564
1690
 
1565
1691
 
1692
+ #### VideoStabilizationMode
1693
+
1694
+ Video stabilization modes used when recording.
1695
+
1696
+ On Android only `off` and `standard` are supported.
1697
+ On iOS all listed modes may be available when the device supports video stabilization.
1698
+
1699
+ <code>'off' | 'standard' | 'cinematic' | 'cinematicExtended' | 'previewOptimized' | 'cinematicExtendedEnhanced' | 'auto' | 'lowLatency'</code>
1700
+
1701
+
1566
1702
  #### BarcodeScannerFormat
1567
1703
 
1568
1704
  <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;
@@ -290,6 +291,56 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
290
291
  }
291
292
  }
292
293
 
294
+ @PluginMethod
295
+ public void getSupportedVideoFrameRates(PluginCall call) {
296
+ if (cameraXView == null || !cameraXView.isRunning()) {
297
+ call.reject("Camera is not running");
298
+ return;
299
+ }
300
+ try {
301
+ List<Integer> frameRates = cameraXView.getSupportedVideoFrameRates();
302
+ JSObject ret = new JSObject();
303
+ JSONArray frameRatesArray = new JSONArray();
304
+ for (Integer frameRate : frameRates) {
305
+ frameRatesArray.put(frameRate);
306
+ }
307
+ ret.put("frameRates", frameRatesArray);
308
+ call.resolve(ret);
309
+ } catch (Exception e) {
310
+ call.reject("Failed to get supported video frame rates: " + e.getMessage());
311
+ }
312
+ }
313
+
314
+ @PluginMethod
315
+ public void getVideoFrameRate(PluginCall call) {
316
+ if (cameraXView == null || !cameraXView.isRunning()) {
317
+ call.reject("Camera is not running");
318
+ return;
319
+ }
320
+ try {
321
+ int frameRate = cameraXView.getVideoFrameRate();
322
+ JSObject ret = new JSObject();
323
+ ret.put("frameRate", frameRate);
324
+ call.resolve(ret);
325
+ } catch (Exception e) {
326
+ call.reject("Failed to get video frame rate: " + e.getMessage());
327
+ }
328
+ }
329
+
330
+ @PluginMethod
331
+ public void setVideoFrameRate(PluginCall call) {
332
+ if (cameraXView == null || !cameraXView.isRunning()) {
333
+ call.reject("Camera is not running");
334
+ return;
335
+ }
336
+ Integer frameRate = call.getInt("frameRate");
337
+ if (frameRate == null) {
338
+ call.reject("frameRate parameter is required");
339
+ return;
340
+ }
341
+ cameraXView.setVideoFrameRate(frameRate, call::resolve, call::reject);
342
+ }
343
+
293
344
  @PluginMethod
294
345
  public void getOrientation(PluginCall call) {
295
346
  String o = getDeviceOrientationString();
@@ -2701,6 +2752,63 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2701
2752
  call.resolve(ret);
2702
2753
  }
2703
2754
 
2755
+ @PluginMethod
2756
+ public void isVideoStabilizationSupported(PluginCall call) {
2757
+ if (cameraXView == null || !cameraXView.isRunning()) {
2758
+ call.reject("Camera is not running");
2759
+ return;
2760
+ }
2761
+ JSObject ret = new JSObject();
2762
+ ret.put("supported", cameraXView.isVideoStabilizationSupported());
2763
+ call.resolve(ret);
2764
+ }
2765
+
2766
+ @PluginMethod
2767
+ public void getSupportedVideoStabilizationModes(PluginCall call) {
2768
+ List<String> modes = cameraXView != null ? cameraXView.getSupportedVideoStabilizationModes() : Collections.singletonList("off");
2769
+ JSONArray arr = new JSONArray();
2770
+ for (String mode : modes) {
2771
+ arr.put(mode);
2772
+ }
2773
+ JSObject ret = new JSObject();
2774
+ ret.put("modes", arr);
2775
+ call.resolve(ret);
2776
+ }
2777
+
2778
+ @PluginMethod
2779
+ public void getVideoStabilizationMode(PluginCall call) {
2780
+ if (cameraXView == null || !cameraXView.isRunning()) {
2781
+ call.reject("Camera is not running");
2782
+ return;
2783
+ }
2784
+ JSObject ret = new JSObject();
2785
+ ret.put("mode", cameraXView.getVideoStabilizationModeSetting());
2786
+ call.resolve(ret);
2787
+ }
2788
+
2789
+ @PluginMethod
2790
+ public void setVideoStabilizationMode(PluginCall call) {
2791
+ if (cameraXView == null || !cameraXView.isRunning()) {
2792
+ call.reject("Camera is not running");
2793
+ return;
2794
+ }
2795
+ String mode = call.getString("mode");
2796
+ if (mode == null) {
2797
+ call.reject("mode is required");
2798
+ return;
2799
+ }
2800
+ try {
2801
+ cameraXView.setVideoStabilizationModeSetting(mode);
2802
+ call.resolve();
2803
+ } catch (IllegalArgumentException e) {
2804
+ call.reject(e.getMessage());
2805
+ } catch (IllegalStateException e) {
2806
+ call.reject(e.getMessage());
2807
+ } catch (Exception e) {
2808
+ call.reject("Failed to set video stabilization mode: " + e.getMessage());
2809
+ }
2810
+ }
2811
+
2704
2812
  @PluginMethod
2705
2813
  public void startRecordVideo(PluginCall call) {
2706
2814
  if (cameraXView == null || !cameraXView.isRunning()) {
@@ -2715,13 +2823,7 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2715
2823
  String permissionAlias = disableAudio ? CAMERA_ONLY_PERMISSION_ALIAS : CAMERA_WITH_AUDIO_PERMISSION_ALIAS;
2716
2824
 
2717
2825
  if (PermissionState.GRANTED.equals(getPermissionState(permissionAlias))) {
2718
- try {
2719
- applyVideoCodecFromCall(call);
2720
- cameraXView.startRecordVideo(getMaxDurationMillis(call), getMaxFileSize(call));
2721
- call.resolve();
2722
- } catch (Exception e) {
2723
- call.reject("Failed to start video recording: " + e.getMessage());
2724
- }
2826
+ beginVideoRecording(call);
2725
2827
  } else {
2726
2828
  requestPermissionForAlias(permissionAlias, call, "handleVideoRecordingPermissionResult");
2727
2829
  }
@@ -2773,6 +2875,13 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2773
2875
  }
2774
2876
  }
2775
2877
 
2878
+ private void applyVideoStabilizationFromCall(PluginCall call) {
2879
+ String mode = call.getString("videoStabilizationMode");
2880
+ if (mode != null && cameraXView != null) {
2881
+ cameraXView.setVideoStabilizationModeSetting(mode);
2882
+ }
2883
+ }
2884
+
2776
2885
  private Long getMaxDurationMillis(PluginCall call) {
2777
2886
  if (!call.getData().has("maxDuration") || call.getData().isNull("maxDuration")) {
2778
2887
  return null;
@@ -2792,6 +2901,23 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2792
2901
  return bytes > 0L ? bytes : null;
2793
2902
  }
2794
2903
 
2904
+ private void beginVideoRecording(PluginCall call) {
2905
+ if (cameraXView == null || !cameraXView.isRunning()) {
2906
+ call.reject("Camera is not running");
2907
+ return;
2908
+ }
2909
+ try {
2910
+ applyVideoCodecFromCall(call);
2911
+ applyVideoStabilizationFromCall(call);
2912
+ Integer frameRate = call.getInt("frameRate");
2913
+ cameraXView.startRecordVideo(getMaxDurationMillis(call), getMaxFileSize(call), frameRate, call::resolve, (message) ->
2914
+ call.reject("Failed to start video recording: " + message)
2915
+ );
2916
+ } catch (Exception e) {
2917
+ call.reject("Failed to start video recording: " + e.getMessage());
2918
+ }
2919
+ }
2920
+
2795
2921
  @PermissionCallback
2796
2922
  private void handleVideoRecordingPermissionResult(PluginCall call) {
2797
2923
  // Use the persisted session value to determine which permission we requested
@@ -2802,13 +2928,7 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
2802
2928
  PermissionState.GRANTED.equals(getPermissionState(CAMERA_ONLY_PERMISSION_ALIAS)) ||
2803
2929
  PermissionState.GRANTED.equals(getPermissionState(CAMERA_WITH_AUDIO_PERMISSION_ALIAS))
2804
2930
  ) {
2805
- try {
2806
- applyVideoCodecFromCall(call);
2807
- cameraXView.startRecordVideo(getMaxDurationMillis(call), getMaxFileSize(call));
2808
- call.resolve();
2809
- } catch (Exception e) {
2810
- call.reject("Failed to start video recording: " + e.getMessage());
2811
- }
2931
+ beginVideoRecording(call);
2812
2932
  } else {
2813
2933
  call.reject("camera permission denied. enable camera access in Settings.", "cameraPermissionDenied");
2814
2934
  }