expo-camera 12.1.2 → 12.2.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 (52) hide show
  1. package/CHANGELOG.md +21 -3
  2. package/README.md +3 -3
  3. package/android/build.gradle +27 -12
  4. package/android/src/main/java/expo/modules/camera/ExpoCameraView.kt +1 -1
  5. package/build/Camera.d.ts +91 -6
  6. package/build/Camera.d.ts.map +1 -0
  7. package/build/Camera.js +95 -3
  8. package/build/Camera.js.map +1 -1
  9. package/build/Camera.types.d.ts +206 -75
  10. package/build/Camera.types.d.ts.map +1 -0
  11. package/build/Camera.types.js +32 -51
  12. package/build/Camera.types.js.map +1 -1
  13. package/build/ExponentCamera.d.ts +1 -0
  14. package/build/ExponentCamera.d.ts.map +1 -0
  15. package/build/ExponentCamera.web.d.ts +1 -0
  16. package/build/ExponentCamera.web.d.ts.map +1 -0
  17. package/build/ExponentCameraManager.d.ts +1 -0
  18. package/build/ExponentCameraManager.d.ts.map +1 -0
  19. package/build/ExponentCameraManager.web.d.ts +1 -0
  20. package/build/ExponentCameraManager.web.d.ts.map +1 -0
  21. package/build/WebCameraUtils.d.ts +3 -2
  22. package/build/WebCameraUtils.d.ts.map +1 -0
  23. package/build/WebCameraUtils.js.map +1 -1
  24. package/build/WebCapabilityUtils.d.ts +1 -0
  25. package/build/WebCapabilityUtils.d.ts.map +1 -0
  26. package/build/WebConstants.d.ts +1 -0
  27. package/build/WebConstants.d.ts.map +1 -0
  28. package/build/WebUserMediaManager.d.ts +1 -0
  29. package/build/WebUserMediaManager.d.ts.map +1 -0
  30. package/build/index.d.ts +3 -1
  31. package/build/index.d.ts.map +1 -0
  32. package/build/index.js +2 -1
  33. package/build/index.js.map +1 -1
  34. package/build/useWebCameraStream.d.ts +1 -0
  35. package/build/useWebCameraStream.d.ts.map +1 -0
  36. package/build/useWebQRScanner.d.ts +2 -2
  37. package/build/useWebQRScanner.d.ts.map +1 -0
  38. package/build/useWebQRScanner.js +2 -2
  39. package/build/useWebQRScanner.js.map +1 -1
  40. package/build/utils/props.d.ts +1 -0
  41. package/build/utils/props.d.ts.map +1 -0
  42. package/ios/EXCamera.xcframework/ios-arm64/EXCamera.framework/EXCamera +0 -0
  43. package/ios/EXCamera.xcframework/ios-arm64/EXCamera.framework/Info.plist +0 -0
  44. package/ios/EXCamera.xcframework/ios-arm64_x86_64-simulator/EXCamera.framework/EXCamera +0 -0
  45. package/ios/EXCamera.xcframework/ios-arm64_x86_64-simulator/EXCamera.framework/Info.plist +0 -0
  46. package/package.json +3 -3
  47. package/plugin/src/withCamera.ts +6 -4
  48. package/src/Camera.tsx +99 -26
  49. package/src/Camera.types.ts +214 -83
  50. package/src/WebCameraUtils.ts +4 -4
  51. package/src/index.ts +17 -4
  52. package/src/useWebQRScanner.ts +3 -4
@@ -7,85 +7,63 @@ import {
7
7
  import { ViewProps } from 'react-native';
8
8
 
9
9
  export enum CameraType {
10
- /**
11
- * @platforms ios, android, web
12
- */
13
10
  front = 'front',
14
- /**
15
- * @platforms ios, android, web
16
- */
17
11
  back = 'back',
18
12
  }
19
13
 
20
14
  export enum FlashMode {
21
- /**
22
- * @platforms ios, android, web
23
- */
24
15
  on = 'on',
25
- /**
26
- * @platforms ios, android, web
27
- */
28
16
  off = 'off',
29
- /**
30
- * @platforms ios, android, web
31
- */
32
17
  auto = 'auto',
33
- /**
34
- * @platforms ios, android, web
35
- */
36
18
  torch = 'torch',
37
19
  }
38
20
 
39
21
  export enum AutoFocus {
40
- /**
41
- * @platforms ios, android, web
42
- */
43
22
  on = 'on',
44
- /**
45
- * @platforms ios, android, web
46
- */
47
23
  off = 'off',
48
24
  /**
49
- * @platforms web
25
+ * @platform web
50
26
  */
51
27
  auto = 'auto',
52
28
  /**
53
- * @platforms web
29
+ * @platform web
54
30
  */
55
31
  singleShot = 'singleShot',
56
32
  }
57
33
 
58
34
  export enum WhiteBalance {
59
- /**
60
- * @platforms ios, android, web
61
- */
62
35
  auto = 'auto',
63
36
  /**
64
- * @platforms ios, android
37
+ * @platform android
38
+ * @platform ios
65
39
  */
66
40
  sunny = 'sunny',
67
41
  /**
68
- * @platforms ios, android
42
+ * @platform android
43
+ * @platform ios
69
44
  */
70
45
  cloudy = 'cloudy',
71
46
  /**
72
- * @platforms ios, android
47
+ * @platform android
48
+ * @platform ios
73
49
  */
74
50
  shadow = 'shadow',
75
51
  /**
76
- * @platforms ios, android
52
+ * @platform android
53
+ * @platform ios
77
54
  */
78
55
  incandescent = 'incandescent',
79
56
  /**
80
- * @platforms ios, android
57
+ * @platform android
58
+ * @platform ios
81
59
  */
82
60
  fluorescent = 'fluorescent',
83
61
  /**
84
- * @platforms web
62
+ * @platform web
85
63
  */
86
64
  continuous = 'continuous',
87
65
  /**
88
- * @platforms web
66
+ * @platform web
89
67
  */
90
68
  manual = 'manual',
91
69
  }
@@ -97,30 +75,34 @@ export enum ImageType {
97
75
 
98
76
  /**
99
77
  * This option specifies what codec to use when recording a video.
78
+ * @platform ios
100
79
  */
101
80
  export enum VideoCodec {
102
- /**
103
- * @platforms ios
104
- */
105
81
  H264 = 'avc1',
106
- /**
107
- * @platforms ios
108
- */
109
82
  HEVC = 'hvc1',
110
- /**
111
- * @platforms ios
112
- */
113
83
  JPEG = 'jpeg',
114
- /**
115
- * @platforms ios
116
- */
117
84
  AppleProRes422 = 'apcn',
118
- /**
119
- * @platforms ios
120
- */
121
85
  AppleProRes4444 = 'ap4h',
122
86
  }
123
87
 
88
+ // @needsAudit
89
+ export enum VideoStabilization {
90
+ off = 'off',
91
+ standard = 'standard',
92
+ cinematic = 'cinematic',
93
+ auto = 'auto',
94
+ }
95
+
96
+ // @needsAudit
97
+ export enum VideoQuality {
98
+ '2160p' = '2160p',
99
+ '1080p' = '1080p',
100
+ '720p' = '720p',
101
+ '480p' = '480p',
102
+ '4:3' = '4:3',
103
+ }
104
+
105
+ // @needsAudit
124
106
  export type ImageParameters = {
125
107
  imageType: ImageType;
126
108
  quality: number | null;
@@ -146,53 +128,109 @@ export type WebCameraSettings = Partial<{
146
128
  zoom: number;
147
129
  }>;
148
130
 
149
- export type CapturedPicture = {
131
+ export type CameraCapturedPicture = {
150
132
  width: number;
151
133
  height: number;
152
134
  uri: string;
153
135
  base64?: string;
154
- // note(bacon): The types are currently only defined for web.
155
- exif?: Partial<MediaTrackSettings>;
136
+ exif?: Partial<MediaTrackSettings> | any;
156
137
  };
157
138
 
139
+ // @needsAudit @docsMissing
158
140
  export type CameraPictureOptions = {
141
+ /**
142
+ * Specify the quality of compression, from 0 to 1. 0 means compress for small size, 1 means compress for maximum quality.
143
+ */
159
144
  quality?: number;
145
+ /**
146
+ * Whether to also include the image data in Base64 format.
147
+ */
160
148
  base64?: boolean;
149
+ /**
150
+ * Whether to also include the EXIF data for the image.
151
+ */
161
152
  exif?: boolean;
153
+ /**
154
+ * A callback invoked when picture is saved. If set, the promise of this method will resolve immediately with no data after picture is captured.
155
+ * The data that it should contain will be passed to this callback. If displaying or processing a captured photo right after taking it
156
+ * is not your case, this callback lets you skip waiting for it to be saved.
157
+ * @param picture
158
+ */
162
159
  onPictureSaved?: (picture: CameraCapturedPicture) => void;
163
160
  // TODO(Bacon): Is it possible to implement this in the browser?
161
+ /**
162
+ * If set to `true`, camera skips orientation adjustment and returns an image straight from the device's camera.
163
+ * If enabled, `quality` option is discarded (processing pipeline is skipped as a whole).
164
+ * Although enabling this option reduces image delivery time significantly, it may cause the image to appear in a wrong orientation
165
+ * in the `Image` component (at the time of writing, it does not respect EXIF orientation of the images).
166
+ * > **Note**: Enabling `skipProcessing` would cause orientation uncertainty. `Image` component does not respect EXIF
167
+ * > stored orientation information, that means obtained image would be displayed wrongly (rotated by 90°, 180° or 270°).
168
+ * > Different devices provide different orientations. For example some Sony Xperia or Samsung devices don't provide
169
+ * > correctly oriented images by default. To always obtain correctly oriented image disable `skipProcessing` option.
170
+ */
164
171
  skipProcessing?: boolean;
165
- // Web-only
172
+ /**
173
+ * @platform web
174
+ */
166
175
  scale?: number;
176
+ /**
177
+ * @platform web
178
+ */
167
179
  imageType?: ImageType;
180
+ /**
181
+ * @platform web
182
+ */
168
183
  isImageMirror?: boolean;
169
- // internal
184
+ /**
185
+ * @hidden
186
+ */
170
187
  id?: number;
188
+ /**
189
+ * @hidden
190
+ */
171
191
  fastMode?: boolean;
172
192
  };
173
193
 
194
+ // @needsAudit
174
195
  export type CameraRecordingOptions = {
196
+ /**
197
+ * Maximum video duration in seconds.
198
+ */
175
199
  maxDuration?: number;
200
+ /**
201
+ * Maximum video file size in bytes.
202
+ */
176
203
  maxFileSize?: number;
204
+ /**
205
+ * Specify the quality of recorded video. Usage: `Camera.Constants.VideoQuality.<value>`,
206
+ * possible values: for 16:9 resolution `2160p`, `1080p`, `720p`, `480p` : `Android only` and for 4:3 `4:3` (the size is 640x480).
207
+ * If the chosen quality is not available for a device, the highest available is chosen.
208
+ */
177
209
  quality?: number | string;
210
+ /**
211
+ * If present, video will be recorded with no sound.
212
+ */
178
213
  mute?: boolean;
214
+ /**
215
+ * If `true`, the recorded video will be flipped along the vertical axis. iOS flips videos recorded with the front camera by default,
216
+ * but you can reverse that back by setting this to `true`. On Android, this is handled in the user's device settings.
217
+ * @platform ios
218
+ */
179
219
  mirror?: boolean;
180
- // Android
220
+ /**
221
+ * Only works if `useCamera2Api` is set to `true`. This option specifies a desired video bitrate. For example, `5*1000*1000` would be 5Mbps.
222
+ * @platform android
223
+ */
181
224
  videoBitrate?: number;
182
- // iOS
225
+ /**
226
+ * This option specifies what codec to use when recording the video. See [`Camera.Constants.VideoCodec`](#video-codec) for the possible values.
227
+ * @platform ios
228
+ */
183
229
  codec?: VideoCodec;
184
230
  };
185
231
 
186
- export type CameraCapturedPicture = {
187
- width: number;
188
- height: number;
189
- uri: string;
190
- base64?: string;
191
- exif?: any;
192
- };
193
-
194
232
  export type PictureSavedListener = (event: {
195
- nativeEvent: { data: CapturedPicture; id: number };
233
+ nativeEvent: { data: CameraCapturedPicture; id: number };
196
234
  }) => void;
197
235
 
198
236
  export type CameraReadyListener = () => void;
@@ -201,17 +239,26 @@ export type MountErrorListener = (event: { nativeEvent: CameraMountError }) => v
201
239
 
202
240
  export type CameraMountError = { message: string };
203
241
 
204
- type Point = {
242
+ export type Point = {
205
243
  x: number;
206
244
  y: number;
207
245
  };
208
246
 
209
247
  export type BarCodePoint = Point;
210
248
 
249
+ // @needsAudit
211
250
  export type BarCodeScanningResult = {
251
+ /**
252
+ * The barcode type.
253
+ */
212
254
  type: string;
255
+ /**
256
+ * The information encoded in the bar code.
257
+ */
213
258
  data: string;
214
- /** @platform web */
259
+ /**
260
+ * Corner points of the bounding box.
261
+ */
215
262
  cornerPoints?: BarCodePoint[];
216
263
  };
217
264
 
@@ -244,32 +291,118 @@ export type Face = {
244
291
  export type FaceDetectionResult = { faces: Face[] };
245
292
 
246
293
  export type ConstantsType = {
247
- Type: typeof CameraType;
248
- FlashMode: typeof FlashMode;
249
- AutoFocus: typeof AutoFocus;
250
- WhiteBalance: typeof WhiteBalance;
251
- VideoQuality: any;
252
- VideoStabilization: any;
253
- VideoCodec: typeof VideoCodec;
294
+ Type: CameraType;
295
+ FlashMode: FlashMode;
296
+ AutoFocus: AutoFocus;
297
+ WhiteBalance: WhiteBalance;
298
+ VideoQuality: VideoQuality;
299
+ VideoStabilization: VideoStabilization;
300
+ VideoCodec: VideoCodec;
254
301
  };
255
302
 
303
+ // @needsAudit
256
304
  export type CameraProps = ViewProps & {
257
- type?: number | keyof typeof CameraType;
258
- flashMode?: number | keyof typeof FlashMode;
259
- whiteBalance?: number | keyof typeof WhiteBalance;
260
- autoFocus?: boolean | number | keyof typeof AutoFocus;
305
+ /**
306
+ * Camera facing. Use one of `Camera.Constants.Type`. When `Type.front`, use the front-facing camera.
307
+ * When `Type.back`, use the back-facing camera.
308
+ * @default Type.back
309
+ */
310
+ type?: number | CameraType;
311
+ /**
312
+ * Camera flash mode. Use one of `Camera.Constants.FlashMode`. When `on`, the flash on your device will
313
+ * turn on when taking a picture, when `off`, it won't. Setting to `auto` will fire flash if required,
314
+ * `torch` turns on flash during the preview.
315
+ * @default FlashMode.off
316
+ */
317
+ flashMode?: number | FlashMode;
318
+ /**
319
+ * Camera white balance. Use one of [`Camera.Constants.WhiteBalance`](#whitebalance). If a device does not support any of these values previous one is used.
320
+ */
321
+ whiteBalance?: number | WhiteBalance;
322
+ /**
323
+ * State of camera auto focus. Use one of [`Camera.Constants.AutoFocus`](#autofocus). When `on`,
324
+ * auto focus will be enabled, when `off`, it won't and focus will lock as it was in the moment of change,
325
+ * but it can be adjusted on some devices via `focusDepth` prop.
326
+ */
327
+ autoFocus?: boolean | number | AutoFocus;
328
+ /**
329
+ * A value between `0` and `1` being a percentage of device's max zoom. `0` - not zoomed, `1` - maximum zoom.
330
+ * @default 0
331
+ */
261
332
  zoom?: number;
333
+ /**
334
+ * A string representing aspect ratio of the preview, eg. `4:3`, `16:9`, `1:1`. To check if a ratio is supported
335
+ * by the device use [`getSupportedRatiosAsync`](#getsupportedratiosasync).
336
+ * @default 4:3.
337
+ * @platform android
338
+ */
262
339
  ratio?: string;
340
+ /**
341
+ * Distance to plane of the sharpest focus. A value between `0` and `1` where: `0` - infinity focus, `1` - focus as close as possible.
342
+ * For Android this is available only for some devices and when `useCamera2Api` is set to `true`.
343
+ * @default 0
344
+ */
263
345
  focusDepth?: number;
264
- onCameraReady?: Function;
346
+ /**
347
+ * Callback invoked when camera preview has been set.
348
+ */
349
+ onCameraReady?: () => void;
350
+ /**
351
+ * Whether to use Android's Camera2 API. See `Note` at the top of this page.
352
+ * @platform android
353
+ */
265
354
  useCamera2Api?: boolean;
355
+ /**
356
+ * A string representing the size of pictures [`takePictureAsync`](#takepictureasync) will take.
357
+ * Available sizes can be fetched with [`getAvailablePictureSizesAsync`](#getavailablepicturesizesasync).
358
+ */
266
359
  pictureSize?: string;
360
+ /**
361
+ * The video stabilization mode used for a video recording. Use one of [`Camera.Constants.VideoStabilization`](#videostabilization).
362
+ * You can read more about each stabilization type in [Apple Documentation](https://developer.apple.com/documentation/avfoundation/avcapturevideostabilizationmode).
363
+ * @platform ios
364
+ */
267
365
  videoStabilizationMode?: number;
366
+ /**
367
+ * Callback invoked when camera preview could not been started.
368
+ * @param event Error object that contains a `message`.
369
+ */
268
370
  onMountError?: (event: CameraMountError) => void;
371
+ /**
372
+ * Settings exposed by [`BarCodeScanner`](bar-code-scanner) module. Supported settings: **barCodeTypes**.
373
+ * @example
374
+ * ```tsx
375
+ * <Camera
376
+ * barCodeScannerSettings={{
377
+ * barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
378
+ * }}
379
+ * />
380
+ * ```
381
+ */
269
382
  barCodeScannerSettings?: object;
383
+ /**
384
+ * Callback that is invoked when a bar code has been successfully scanned. The callback is provided with
385
+ * an object of the [`BarCodeScanningResult`](#barcodescanningresult) shape, where the `type`
386
+ * refers to the bar code type that was scanned and the `data` is the information encoded in the bar code
387
+ * (in this case of QR codes, this is often a URL). See [`BarCodeScanner.Constants.BarCodeType`](bar-code-scanner#supported-formats)
388
+ * for supported values.
389
+ * @param scanningResult
390
+ */
270
391
  onBarCodeScanned?: (scanningResult: BarCodeScanningResult) => void;
392
+ /**
393
+ * A settings object passed directly to an underlying module providing face detection features.
394
+ * See [`DetectionOptions`](facedetector/#detectionoptions) in FaceDetector documentation for details.
395
+ */
271
396
  faceDetectorSettings?: object;
397
+ /**
398
+ * Callback invoked with results of face detection on the preview. See [FaceDetector documentation](facedetector/#detectionresult) for details.
399
+ * @param faces
400
+ */
272
401
  onFacesDetected?: (faces: FaceDetectionResult) => void;
402
+ /**
403
+ * A URL for an image to be shown while the camera is loading.
404
+ * @platform web
405
+ */
273
406
  poster?: string;
274
407
  };
275
408
 
@@ -294,10 +427,8 @@ export type CameraNativeProps = {
294
427
  faceDetectorSettings?: object;
295
428
  barCodeScannerEnabled?: boolean;
296
429
  faceDetectorEnabled?: boolean;
297
- // Android
298
430
  ratio?: string;
299
431
  useCamera2Api?: boolean;
300
- // Web
301
432
  poster?: string;
302
433
  };
303
434
 
@@ -3,7 +3,7 @@ import invariant from 'invariant';
3
3
 
4
4
  import {
5
5
  CameraType,
6
- CapturedPicture,
6
+ CameraCapturedPicture,
7
7
  ImageSize,
8
8
  ImageType,
9
9
  WebCameraSettings,
@@ -248,10 +248,10 @@ export function capture(
248
248
  video: HTMLVideoElement,
249
249
  settings: MediaTrackSettings,
250
250
  config: CameraPictureOptions
251
- ): CapturedPicture {
251
+ ): CameraCapturedPicture {
252
252
  const base64 = captureImage(video, config);
253
253
 
254
- const capturedPicture: CapturedPicture = {
254
+ const capturedPicture: CameraCapturedPicture = {
255
255
  uri: base64,
256
256
  base64,
257
257
  width: 0,
@@ -384,7 +384,7 @@ export function setVideoSource(
384
384
  } else if (typeof (video as any).mozSrcObject !== 'undefined') {
385
385
  (video as any).mozSrcObject = stream;
386
386
  } else if (stream && createObjectURL) {
387
- video.src = createObjectURL(stream);
387
+ video.src = createObjectURL(stream as MediaSource | Blob);
388
388
  }
389
389
 
390
390
  if (!stream) {
package/src/index.ts CHANGED
@@ -7,15 +7,28 @@ export {
7
7
  requestCameraPermissionsAsync,
8
8
  getMicrophonePermissionsAsync,
9
9
  requestMicrophonePermissionsAsync,
10
+ } from './Camera';
11
+
12
+ export {
13
+ BarCodePoint,
14
+ BarCodeScanningResult,
10
15
  CameraCapturedPicture,
16
+ CameraMountError,
11
17
  CameraNativeProps,
12
18
  CameraPictureOptions,
13
19
  CameraProps,
14
20
  CameraRecordingOptions,
21
+ ConstantsType,
22
+ FaceDetectionResult,
15
23
  PermissionResponse,
16
24
  PermissionStatus,
17
25
  PermissionExpiration,
18
- BarCodeScanningResult,
19
- FaceDetectionResult,
20
- CameraMountError,
21
- } from './Camera';
26
+ Point,
27
+ AutoFocus,
28
+ FlashMode,
29
+ CameraType,
30
+ VideoCodec,
31
+ VideoQuality,
32
+ VideoStabilization,
33
+ WhiteBalance,
34
+ } from './Camera.types';
@@ -1,20 +1,19 @@
1
1
  import { useWorker } from '@koale/useworker';
2
2
  import * as React from 'react';
3
3
 
4
- import { CameraPictureOptions } from './Camera';
5
- import { BarCodeScanningResult, MountErrorListener } from './Camera.types';
4
+ import { BarCodeScanningResult, CameraPictureOptions, MountErrorListener } from './Camera.types';
6
5
  import { captureImageData } from './WebCameraUtils';
7
6
 
8
7
  const qrWorkerMethod = ({ data, width, height }: ImageData): any => {
9
8
  // eslint-disable-next-line no-undef
10
9
  const decoded = (self as any).jsQR(data, width, height, {
11
- inversionAttempts: 'dontInvert',
10
+ inversionAttempts: 'attemptBoth',
12
11
  });
13
12
 
14
13
  let parsed;
15
14
  try {
16
15
  parsed = JSON.parse(decoded);
17
- } catch (err) {
16
+ } catch {
18
17
  parsed = decoded;
19
18
  }
20
19