@capacitor-community/camera-preview 1.2.0 → 2.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 (107) hide show
  1. package/CapacitorCommunityCameraPreview.podspec +3 -2
  2. package/LICENSE +21 -0
  3. package/README.md +61 -57
  4. package/android/.gradle/4.10.1/fileChanges/last-build.bin +0 -0
  5. package/android/.gradle/4.10.1/fileHashes/fileHashes.bin +0 -0
  6. package/android/.gradle/4.10.1/fileHashes/fileHashes.lock +0 -0
  7. package/android/.gradle/4.10.1/gc.properties +0 -0
  8. package/android/.gradle/vcs-1/gc.properties +0 -0
  9. package/android/.idea/compiler.xml +6 -0
  10. package/android/.idea/gradle.xml +20 -0
  11. package/android/.idea/jarRepositories.xml +45 -0
  12. package/android/.idea/libraries/Gradle__androidx_activity_activity_1_2_0_aar.xml +14 -0
  13. package/android/.idea/libraries/Gradle__androidx_activity_activity_1_2_3_aar.xml +14 -0
  14. package/android/.idea/libraries/Gradle__androidx_annotation_annotation_1_1_0.xml +9 -0
  15. package/android/.idea/libraries/Gradle__androidx_annotation_annotation_1_2_0.xml +9 -0
  16. package/android/.idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_0_0_aar.xml +11 -0
  17. package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_2_0_aar.xml +14 -0
  18. package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_3_0_aar.xml +14 -0
  19. package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_2_0_aar.xml +11 -0
  20. package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_3_0_aar.xml +11 -0
  21. package/android/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0.xml +9 -0
  22. package/android/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_1_0_aar.xml +11 -0
  23. package/android/.idea/libraries/Gradle__androidx_collection_collection_1_1_0.xml +9 -0
  24. package/android/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml +14 -0
  25. package/android/.idea/libraries/Gradle__androidx_core_core_1_3_2_aar.xml +14 -0
  26. package/android/.idea/libraries/Gradle__androidx_core_core_1_5_0_aar.xml +14 -0
  27. package/android/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml +11 -0
  28. package/android/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml +11 -0
  29. package/android/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml +14 -0
  30. package/android/.idea/libraries/Gradle__androidx_exifinterface_exifinterface_1_3_2_aar.xml +14 -0
  31. package/android/.idea/libraries/Gradle__androidx_fragment_fragment_1_3_0_aar.xml +14 -0
  32. package/android/.idea/libraries/Gradle__androidx_fragment_fragment_1_3_4_aar.xml +14 -0
  33. package/android/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml +11 -0
  34. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_3_0.xml +9 -0
  35. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_3_1.xml +9 -0
  36. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml +11 -0
  37. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_3_0_aar.xml +11 -0
  38. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_3_1_aar.xml +11 -0
  39. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_3_0_aar.xml +11 -0
  40. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_3_1_aar.xml +11 -0
  41. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_3_0_aar.xml +11 -0
  42. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_3_1_aar.xml +11 -0
  43. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_3_0_aar.xml +11 -0
  44. package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_3_1_aar.xml +11 -0
  45. package/android/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml +11 -0
  46. package/android/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_1_0_aar.xml +11 -0
  47. package/android/.idea/libraries/Gradle__androidx_test_core_1_3_0_aar.xml +11 -0
  48. package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_1_0_alpha3_aar.xml +11 -0
  49. package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_3_0_aar.xml +11 -0
  50. package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_1_0_alpha3_aar.xml +11 -0
  51. package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_3_0_aar.xml +11 -0
  52. package/android/.idea/libraries/Gradle__androidx_test_ext_junit_1_1_2_aar.xml +11 -0
  53. package/android/.idea/libraries/Gradle__androidx_test_monitor_1_1_0_alpha3_aar.xml +11 -0
  54. package/android/.idea/libraries/Gradle__androidx_test_monitor_1_3_0_aar.xml +11 -0
  55. package/android/.idea/libraries/Gradle__androidx_test_runner_1_1_0_alpha3_aar.xml +11 -0
  56. package/android/.idea/libraries/Gradle__androidx_test_runner_1_3_0_aar.xml +11 -0
  57. package/android/.idea/libraries/Gradle__androidx_tracing_tracing_1_0_0_aar.xml +11 -0
  58. package/android/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml +11 -0
  59. package/android/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml +11 -0
  60. package/android/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_0_aar.xml +11 -0
  61. package/android/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_1_aar.xml +11 -0
  62. package/android/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml +11 -0
  63. package/android/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1.xml +9 -0
  64. package/android/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1.xml +9 -0
  65. package/android/.idea/libraries/Gradle__javax_inject_javax_inject_1.xml +9 -0
  66. package/android/.idea/libraries/Gradle__junit_junit_4_12.xml +9 -0
  67. package/android/.idea/libraries/Gradle__junit_junit_4_13_1.xml +9 -0
  68. package/android/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_10_18.xml +9 -0
  69. package/android/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_10_18.xml +9 -0
  70. package/android/.idea/libraries/Gradle__net_sf_kxml_kxml2_2_3_0.xml +9 -0
  71. package/android/.idea/libraries/Gradle__org_apache_cordova_framework_7_0_0_aar.xml +11 -0
  72. package/android/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml +9 -0
  73. package/android/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3.xml +9 -0
  74. package/android/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3.xml +9 -0
  75. package/android/.idea/libraries/Gradle__org_json_json_20140107.xml +9 -0
  76. package/android/.idea/libraries/Gradle__org_mockito_mockito_core_3_6_28.xml +9 -0
  77. package/android/.idea/libraries/Gradle__org_mockito_mockito_inline_3_6_28.xml +9 -0
  78. package/android/.idea/libraries/Gradle__org_objenesis_objenesis_3_1.xml +9 -0
  79. package/android/.idea/misc.xml +9 -0
  80. package/android/.idea/modules/1419750366/android.capacitor-android.iml +92 -0
  81. package/android/.idea/modules/android.iml +87 -0
  82. package/android/.idea/modules.xml +9 -0
  83. package/android/.idea/vcs.xml +6 -0
  84. package/android/build.gradle +4 -4
  85. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java +128 -70
  86. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +163 -118
  87. package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomTextureView.java +31 -0
  88. package/android/src/main/java/com/ahm/capacitor/camera/preview/Preview.java +96 -19
  89. package/dist/esm/definitions.d.ts +18 -5
  90. package/dist/esm/definitions.js +1 -0
  91. package/dist/esm/index.d.ts +3 -1
  92. package/dist/esm/index.js +5 -1
  93. package/dist/esm/index.js.map +1 -1
  94. package/dist/esm/web.d.ts +8 -1
  95. package/dist/esm/web.js +95 -77
  96. package/dist/esm/web.js.map +1 -1
  97. package/ios/Plugin/CameraController.swift +155 -48
  98. package/ios/Plugin/Plugin.m +3 -0
  99. package/ios/Plugin/Plugin.swift +126 -47
  100. package/ios/Plugin.xcodeproj/project.pbxproj +4 -8
  101. package/ios/Podfile +2 -2
  102. package/ios/Podfile.lock +5 -5
  103. package/package.json +4 -3
  104. package/android/local.properties +0 -8
  105. package/ios/Plugin.xcodeproj/xcuserdata/nielsvanharen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  106. package/ios/Plugin.xcworkspace/xcuserdata/arielhernandezmusa.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  107. package/ios/Plugin.xcworkspace/xcuserdata/nielsvanharen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
@@ -2,22 +2,27 @@ package com.ahm.capacitor.camera.preview;
2
2
 
3
3
  import android.app.Activity;
4
4
  import android.content.Context;
5
+ import android.graphics.SurfaceTexture;
5
6
  import android.hardware.Camera;
6
7
  import android.util.DisplayMetrics;
7
8
  import android.util.Log;
8
9
  import android.view.Surface;
9
10
  import android.view.SurfaceHolder;
11
+ import android.view.TextureView;
10
12
  import android.view.View;
11
13
  import android.widget.RelativeLayout;
12
14
 
13
15
  import java.io.IOException;
14
16
  import java.util.List;
15
17
 
16
- class Preview extends RelativeLayout implements SurfaceHolder.Callback {
18
+ class Preview extends RelativeLayout implements SurfaceHolder.Callback,
19
+ TextureView.SurfaceTextureListener {
17
20
  private final String TAG = "Preview";
18
21
 
19
22
  CustomSurfaceView mSurfaceView;
23
+ CustomTextureView mTextureView;
20
24
  SurfaceHolder mHolder;
25
+ SurfaceTexture mSurface;
21
26
  Camera.Size mPreviewSize;
22
27
  List<Camera.Size> mSupportedPreviewSizes;
23
28
  Camera mCamera;
@@ -26,20 +31,36 @@ class Preview extends RelativeLayout implements SurfaceHolder.Callback {
26
31
  int facing = Camera.CameraInfo.CAMERA_FACING_BACK;
27
32
  int viewWidth;
28
33
  int viewHeight;
34
+ private boolean enableOpacity = false;
35
+ private float opacity = 1F;
29
36
 
30
37
  Preview(Context context) {
31
- super(context);
32
-
33
- mSurfaceView = new CustomSurfaceView(context);
34
- addView(mSurfaceView);
38
+ this(context, false);
39
+ }
35
40
 
36
- requestLayout();
41
+ Preview(Context context, boolean enableOpacity) {
42
+ super(context);
37
43
 
38
- // Install a SurfaceHolder.Callback so we get notified when the
39
- // underlying surface is created and destroyed.
40
- mHolder = mSurfaceView.getHolder();
41
- mHolder.addCallback(this);
42
- mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
44
+ this.enableOpacity = enableOpacity;
45
+ if (!enableOpacity) {
46
+ mSurfaceView = new CustomSurfaceView(context);
47
+ addView(mSurfaceView);
48
+ requestLayout();
49
+
50
+ // Install a SurfaceHolder.Callback so we get notified when the
51
+ // underlying surface is created and destroyed.
52
+ mHolder = mSurfaceView.getHolder();
53
+ mHolder.addCallback(this);
54
+ mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
55
+ } else {
56
+ // Use a TextureView so we can manage opacity
57
+ mTextureView = new CustomTextureView(context);
58
+ // Install a SurfaceTextureListener so we get notified
59
+ mTextureView.setSurfaceTextureListener(this);
60
+ mTextureView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
61
+ addView(mTextureView);
62
+ requestLayout();
63
+ }
43
64
  }
44
65
 
45
66
  public void setCamera(Camera camera, int cameraId) {
@@ -123,7 +144,14 @@ class Preview extends RelativeLayout implements SurfaceHolder.Callback {
123
144
 
124
145
  Log.d("CameraPreview", "before set camera");
125
146
 
126
- camera.setPreviewDisplay(mHolder);
147
+ View v;
148
+ if (enableOpacity) {
149
+ camera.setPreviewTexture(mSurface);
150
+ v = mTextureView;
151
+ } else {
152
+ camera.setPreviewDisplay(mHolder);
153
+ v = mSurfaceView;
154
+ }
127
155
 
128
156
  Log.d("CameraPreview", "before getParameters");
129
157
 
@@ -132,7 +160,7 @@ class Preview extends RelativeLayout implements SurfaceHolder.Callback {
132
160
  Log.d("CameraPreview", "before setPreviewSize");
133
161
 
134
162
  mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
135
- mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, mSurfaceView.getWidth(), mSurfaceView.getHeight());
163
+ mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, v.getWidth(), v.getHeight());
136
164
  parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
137
165
  Log.d(TAG, mPreviewSize.width + " " + mPreviewSize.height);
138
166
 
@@ -285,21 +313,70 @@ class Preview extends RelativeLayout implements SurfaceHolder.Callback {
285
313
  if (mSupportedPreviewSizes != null) {
286
314
  mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, w, h);
287
315
  }
288
- Camera.Parameters parameters = mCamera.getParameters();
289
- parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
290
- requestLayout();
291
- //mCamera.setDisplayOrientation(90);
292
- mCamera.setParameters(parameters);
293
- mCamera.startPreview();
316
+ startCamera();
294
317
  } catch (Exception exception) {
295
318
  Log.e(TAG, "Exception caused by surfaceChanged()", exception);
296
319
  }
297
320
  }
298
321
  }
299
322
 
323
+ private void startCamera() {
324
+ Camera.Parameters parameters = mCamera.getParameters();
325
+ parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
326
+ requestLayout();
327
+ //mCamera.setDisplayOrientation(90);
328
+ mCamera.setParameters(parameters);
329
+ mCamera.startPreview();
330
+ }
331
+
332
+ // Texture Callbacks
333
+
334
+ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
335
+ // The Surface has been created, acquire the camera and tell it where
336
+ // to draw.
337
+ try {
338
+ mSurface = surface;
339
+ if (mSupportedPreviewSizes != null) {
340
+ mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
341
+ }
342
+ if (mCamera != null) {
343
+ mTextureView.setAlpha(opacity);
344
+ mCamera.setPreviewTexture(surface);
345
+ startCamera();
346
+ }
347
+ } catch (Exception exception) {
348
+ Log.e(TAG, "Exception caused by onSurfaceTextureAvailable()", exception);
349
+ }
350
+ }
351
+
352
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
353
+ }
354
+
355
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
356
+ try {
357
+ if (mCamera != null) {
358
+ mCamera.stopPreview();
359
+ }
360
+ } catch (Exception exception) {
361
+ Log.e(TAG, "Exception caused by onSurfaceTextureDestroyed()", exception);
362
+ return false;
363
+ }
364
+ return true;
365
+
366
+ }
367
+
368
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {
369
+ }
300
370
  public void setOneShotPreviewCallback(Camera.PreviewCallback callback) {
301
371
  if(mCamera != null) {
302
372
  mCamera.setOneShotPreviewCallback(callback);
303
373
  }
304
374
  }
375
+
376
+ public void setOpacity(final float opacity) {
377
+ this.opacity = opacity;
378
+ if (mCamera != null && enableOpacity) {
379
+ mTextureView.setAlpha(opacity);
380
+ }
381
+ }
305
382
  }
@@ -1,8 +1,3 @@
1
- declare module "@capacitor/core" {
2
- interface PluginRegistry {
3
- CameraPreview: CameraPreviewPlugin;
4
- }
5
- }
6
1
  export declare type CameraPosition = 'rear' | 'front';
7
2
  export interface CameraPreviewOptions {
8
3
  /** Parent element to attach the video preview element to (applicable to the web platform only) */
@@ -33,6 +28,12 @@ export interface CameraPreviewOptions {
33
28
  enableHighResolution?: boolean;
34
29
  /** Defaults to false - Web only - Disables audio stream to prevent permission requests and output switching */
35
30
  disableAudio?: boolean;
31
+ /** Android Only - Locks device orientation when camera is showing. */
32
+ lockAndroidOrientation?: boolean;
33
+ /** Defaults to false - Android and Web only. Set if camea preview can change opacity. */
34
+ enableOpacity?: boolean;
35
+ /** Defaults to false - Android only. Set if camea preview will support pinch to zoom. */
36
+ enableZoom?: boolean;
36
37
  }
37
38
  export interface CameraPreviewPictureOptions {
38
39
  /** The picture height, optional, default 0 (Device default) */
@@ -42,13 +43,24 @@ export interface CameraPreviewPictureOptions {
42
43
  /** The picture quality, 0 - 100, default 85 */
43
44
  quality?: number;
44
45
  }
46
+ export interface CameraSampleOptions {
47
+ /** The picture quality, 0 - 100, default 85 */
48
+ quality?: number;
49
+ }
45
50
  export declare type CameraPreviewFlashMode = 'off' | 'on' | 'auto' | 'red-eye' | 'torch';
51
+ export interface CameraOpacityOptions {
52
+ /** The percent opacity to set for camera view, default 1 */
53
+ opacity?: number;
54
+ }
46
55
  export interface CameraPreviewPlugin {
47
56
  start(options: CameraPreviewOptions): Promise<{}>;
48
57
  stop(): Promise<{}>;
49
58
  capture(options: CameraPreviewPictureOptions): Promise<{
50
59
  value: string;
51
60
  }>;
61
+ captureSample(options: CameraSampleOptions): Promise<{
62
+ value: string;
63
+ }>;
52
64
  getSupportedFlashModes(): Promise<{
53
65
  result: CameraPreviewFlashMode[];
54
66
  }>;
@@ -56,4 +68,5 @@ export interface CameraPreviewPlugin {
56
68
  flashMode: CameraPreviewFlashMode | string;
57
69
  }): void;
58
70
  flip(): void;
71
+ setOpacity(options: CameraOpacityOptions): Promise<{}>;
59
72
  }
@@ -1 +1,2 @@
1
+ export {};
1
2
  //# sourceMappingURL=definitions.js.map
@@ -1,2 +1,4 @@
1
+ import { CameraPreviewPlugin } from './definitions';
2
+ declare const CameraPreview: CameraPreviewPlugin;
1
3
  export * from './definitions';
2
- export * from './web';
4
+ export { CameraPreview };
package/dist/esm/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const CameraPreview = registerPlugin('CameraPreview', {
3
+ web: () => import('./web').then(m => new m.CameraPreviewWeb()),
4
+ });
1
5
  export * from './definitions';
2
- export * from './web';
6
+ export { CameraPreview };
3
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAG/C,MAAM,aAAa,GAAG,cAAc,CAAsB,eAAe,EAAE;IACzE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;CAC/D,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAC,aAAa,EAAC,CAAC"}
package/dist/esm/web.d.ts CHANGED
@@ -1,10 +1,16 @@
1
1
  import { WebPlugin } from "@capacitor/core";
2
- import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode } from "./definitions";
2
+ import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode, CameraSampleOptions, CameraOpacityOptions } from "./definitions";
3
3
  export declare class CameraPreviewWeb extends WebPlugin implements CameraPreviewPlugin {
4
+ /**
5
+ * track which camera is used based on start options
6
+ * used in capture
7
+ */
8
+ private isBackCamera;
4
9
  constructor();
5
10
  start(options: CameraPreviewOptions): Promise<{}>;
6
11
  stop(): Promise<any>;
7
12
  capture(_options: CameraPreviewPictureOptions): Promise<any>;
13
+ captureSample(_options: CameraSampleOptions): Promise<any>;
8
14
  getSupportedFlashModes(): Promise<{
9
15
  result: CameraPreviewFlashMode[];
10
16
  }>;
@@ -12,6 +18,7 @@ export declare class CameraPreviewWeb extends WebPlugin implements CameraPreview
12
18
  flashMode: CameraPreviewFlashMode | string;
13
19
  }): Promise<void>;
14
20
  flip(): Promise<void>;
21
+ setOpacity(_options: CameraOpacityOptions): Promise<any>;
15
22
  }
16
23
  declare const CameraPreview: CameraPreviewWeb;
17
24
  export { CameraPreview };
package/dist/esm/web.js CHANGED
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { WebPlugin } from "@capacitor/core";
11
2
  export class CameraPreviewWeb extends WebPlugin {
12
3
  constructor() {
@@ -15,88 +6,115 @@ export class CameraPreviewWeb extends WebPlugin {
15
6
  platforms: ["web"],
16
7
  });
17
8
  }
18
- start(options) {
19
- return __awaiter(this, void 0, void 0, function* () {
20
- return new Promise((resolve, reject) => {
21
- navigator.mediaDevices.getUserMedia({
22
- audio: !options.disableAudio,
23
- video: true
24
- });
25
- const video = document.getElementById("video");
26
- const parent = document.getElementById(options.parent);
27
- if (!video) {
28
- const videoElement = document.createElement("video");
29
- videoElement.id = "video";
30
- videoElement.setAttribute("class", options.className || "");
9
+ async start(options) {
10
+ return new Promise(async (resolve, reject) => {
11
+ await navigator.mediaDevices.getUserMedia({
12
+ audio: !options.disableAudio,
13
+ video: true
14
+ }).then((stream) => {
15
+ // Stop any existing stream so we can request media with different constraints based on user input
16
+ stream.getTracks().forEach((track) => track.stop());
17
+ }).catch(error => {
18
+ reject(error);
19
+ });
20
+ const video = document.getElementById("video");
21
+ const parent = document.getElementById(options.parent);
22
+ if (!video) {
23
+ const videoElement = document.createElement("video");
24
+ videoElement.id = "video";
25
+ videoElement.setAttribute("class", options.className || "");
26
+ // Don't flip video feed if camera is rear facing
27
+ if (options.position !== 'rear') {
31
28
  videoElement.setAttribute("style", "-webkit-transform: scaleX(-1); transform: scaleX(-1);");
32
- parent.appendChild(videoElement);
33
- if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
34
- // Not adding `{ audio: true }` since we only want video now
35
- navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
36
- //video.src = window.URL.createObjectURL(stream);
37
- videoElement.srcObject = stream;
38
- videoElement.play();
39
- resolve({});
40
- }, (err) => {
41
- reject(err);
42
- });
43
- }
44
29
  }
45
- else {
46
- reject({ message: "camera already started" });
30
+ const userAgent = navigator.userAgent.toLowerCase();
31
+ const isSafari = userAgent.includes('safari') && !userAgent.includes('chrome');
32
+ // Safari on iOS needs to have the autoplay, muted and playsinline attributes set for video.play() to be successful
33
+ // Without these attributes videoElement.play() will throw a NotAllowedError
34
+ // https://developer.apple.com/documentation/webkit/delivering_video_content_for_safari
35
+ if (isSafari) {
36
+ videoElement.setAttribute('autoplay', 'true');
37
+ videoElement.setAttribute('muted', 'true');
38
+ videoElement.setAttribute('playsinline', 'true');
47
39
  }
48
- });
49
- });
50
- }
51
- stop() {
52
- return __awaiter(this, void 0, void 0, function* () {
53
- const video = document.getElementById("video");
54
- if (video) {
55
- video.pause();
56
- const st = video.srcObject;
57
- const tracks = st.getTracks();
58
- for (var i = 0; i < tracks.length; i++) {
59
- var track = tracks[i];
60
- track.stop();
40
+ parent.appendChild(videoElement);
41
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
42
+ const constraints = {
43
+ video: true,
44
+ };
45
+ if (options.position === 'rear') {
46
+ constraints.video = { facingMode: 'environment' };
47
+ this.isBackCamera = true;
48
+ }
49
+ else {
50
+ this.isBackCamera = false;
51
+ }
52
+ navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
53
+ //video.src = window.URL.createObjectURL(stream);
54
+ videoElement.srcObject = stream;
55
+ videoElement.play();
56
+ resolve({});
57
+ }, (err) => {
58
+ reject(err);
59
+ });
61
60
  }
62
- video.remove();
61
+ }
62
+ else {
63
+ reject({ message: "camera already started" });
63
64
  }
64
65
  });
65
66
  }
66
- capture(_options) {
67
- return __awaiter(this, void 0, void 0, function* () {
68
- return new Promise((resolve, _) => {
69
- const video = document.getElementById("video");
70
- const canvas = document.createElement("canvas");
71
- // video.width = video.offsetWidth;
72
- const context = canvas.getContext("2d");
73
- canvas.width = video.videoWidth;
74
- canvas.height = video.videoHeight;
67
+ async stop() {
68
+ const video = document.getElementById("video");
69
+ if (video) {
70
+ video.pause();
71
+ const st = video.srcObject;
72
+ const tracks = st.getTracks();
73
+ for (var i = 0; i < tracks.length; i++) {
74
+ var track = tracks[i];
75
+ track.stop();
76
+ }
77
+ video.remove();
78
+ }
79
+ }
80
+ async capture(_options) {
81
+ return new Promise((resolve, _) => {
82
+ const video = document.getElementById("video");
83
+ const canvas = document.createElement("canvas");
84
+ // video.width = video.offsetWidth;
85
+ const context = canvas.getContext("2d");
86
+ canvas.width = video.videoWidth;
87
+ canvas.height = video.videoHeight;
88
+ // flip horizontally back camera isn't used
89
+ if (!this.isBackCamera) {
75
90
  context.translate(video.videoWidth, 0);
76
91
  context.scale(-1, 1);
77
- context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
78
- resolve({
79
- value: canvas
80
- .toDataURL("image/png")
81
- .replace("data:image/png;base64,", ""),
82
- });
92
+ }
93
+ context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
94
+ resolve({
95
+ value: canvas
96
+ .toDataURL("image/png")
97
+ .replace("data:image/png;base64,", ""),
83
98
  });
84
99
  });
85
100
  }
86
- getSupportedFlashModes() {
87
- return __awaiter(this, void 0, void 0, function* () {
88
- throw new Error('getSupportedFlashModes not supported under the web platform');
89
- });
101
+ async captureSample(_options) {
102
+ return this.capture(_options);
90
103
  }
91
- setFlashMode(_options) {
92
- return __awaiter(this, void 0, void 0, function* () {
93
- throw new Error('setFlashMode not supported under the web platform');
94
- });
104
+ async getSupportedFlashModes() {
105
+ throw new Error('getSupportedFlashModes not supported under the web platform');
95
106
  }
96
- flip() {
97
- return __awaiter(this, void 0, void 0, function* () {
98
- throw new Error('flip not supported under the web platform');
99
- });
107
+ async setFlashMode(_options) {
108
+ throw new Error('setFlashMode not supported under the web platform');
109
+ }
110
+ async flip() {
111
+ throw new Error('flip not supported under the web platform');
112
+ }
113
+ async setOpacity(_options) {
114
+ const video = document.getElementById("video");
115
+ if (!!video && !!_options['opacity']) {
116
+ video.style.setProperty("opacity", _options['opacity'].toString());
117
+ }
100
118
  }
101
119
  }
102
120
  const CameraPreview = new CameraPreviewWeb();
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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"}