@webcam/react 1.0.1 → 1.1.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 +81 -130
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/cjs/components/Webcam/Webcam.cjs +2 -0
- package/dist/cjs/components/Webcam/Webcam.cjs.map +1 -0
- package/dist/cjs/components/Webcam/hooks/useWebcam.cjs +2 -0
- package/dist/cjs/components/Webcam/hooks/useWebcam.cjs.map +1 -0
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/utils/helpers/animationFrame.cjs +2 -0
- package/dist/cjs/utils/helpers/animationFrame.cjs.map +1 -0
- package/dist/cjs/utils/hooks/useAnimationFrame.cjs +2 -0
- package/dist/cjs/utils/hooks/useAnimationFrame.cjs.map +1 -0
- package/dist/components/Webcam/Webcam.d.ts +34 -0
- package/dist/components/Webcam/hooks/index.d.ts +1 -0
- package/dist/components/Webcam/hooks/useWebcam.d.ts +38 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/esm/components/Webcam/Webcam.mjs +51 -0
- package/dist/esm/components/Webcam/Webcam.mjs.map +1 -0
- package/dist/esm/components/Webcam/hooks/useWebcam.mjs +76 -0
- package/dist/esm/components/Webcam/hooks/useWebcam.mjs.map +1 -0
- package/dist/esm/index.mjs +5 -0
- package/dist/esm/utils/helpers/animationFrame.mjs +6 -0
- package/dist/esm/utils/helpers/animationFrame.mjs.map +1 -0
- package/dist/esm/utils/hooks/useAnimationFrame.mjs +33 -0
- package/dist/esm/utils/hooks/useAnimationFrame.mjs.map +1 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +3 -76
- package/dist/utils/helpers/animationFrame.d.ts +2 -0
- package/dist/utils/helpers/index.d.ts +1 -0
- package/dist/utils/hooks/index.d.ts +1 -0
- package/dist/utils/hooks/useAnimationFrame.d.ts +11 -0
- package/package.json +70 -72
- package/dist/cjs/components/Webcam/Webcam.js +0 -3
- package/dist/cjs/components/Webcam/Webcam.js.map +0 -1
- package/dist/cjs/components/Webcam/hooks/index.js +0 -3
- package/dist/cjs/components/Webcam/hooks/index.js.map +0 -1
- package/dist/cjs/components/Webcam/hooks/useWebcam.js +0 -3
- package/dist/cjs/components/Webcam/hooks/useWebcam.js.map +0 -1
- package/dist/cjs/components/index.js +0 -3
- package/dist/cjs/components/index.js.map +0 -1
- package/dist/cjs/index-a4e0b8ec.js +0 -3
- package/dist/cjs/index-a4e0b8ec.js.map +0 -1
- package/dist/cjs/index.js +0 -3
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/useMediaStream-4231673b.js +0 -7
- package/dist/cjs/useMediaStream-4231673b.js.map +0 -1
- package/dist/cjs/utils/helpers/animationFrame.js +0 -3
- package/dist/cjs/utils/helpers/animationFrame.js.map +0 -1
- package/dist/cjs/utils/helpers/index.js +0 -3
- package/dist/cjs/utils/helpers/index.js.map +0 -1
- package/dist/cjs/utils/hooks/index.js +0 -3
- package/dist/cjs/utils/hooks/index.js.map +0 -1
- package/dist/cjs/utils/hooks/useAnimationFrame.js +0 -3
- package/dist/cjs/utils/hooks/useAnimationFrame.js.map +0 -1
- package/dist/cjs/utils/hooks/useIsomorphicLayoutEffect.js +0 -3
- package/dist/cjs/utils/hooks/useIsomorphicLayoutEffect.js.map +0 -1
- package/dist/cjs/utils/hooks/useMediaStream.js +0 -3
- package/dist/cjs/utils/hooks/useMediaStream.js.map +0 -1
- package/dist/esm/components/Webcam/Webcam.js +0 -3
- package/dist/esm/components/Webcam/Webcam.js.map +0 -1
- package/dist/esm/components/Webcam/hooks/index.js +0 -3
- package/dist/esm/components/Webcam/hooks/index.js.map +0 -1
- package/dist/esm/components/Webcam/hooks/useWebcam.js +0 -3
- package/dist/esm/components/Webcam/hooks/useWebcam.js.map +0 -1
- package/dist/esm/components/index.js +0 -3
- package/dist/esm/components/index.js.map +0 -1
- package/dist/esm/index-022e8735.js +0 -5
- package/dist/esm/index-022e8735.js.map +0 -1
- package/dist/esm/index.js +0 -4
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/useMediaStream-4f24b75b.js +0 -6
- package/dist/esm/useMediaStream-4f24b75b.js.map +0 -1
- package/dist/esm/utils/helpers/animationFrame.js +0 -3
- package/dist/esm/utils/helpers/animationFrame.js.map +0 -1
- package/dist/esm/utils/helpers/index.js +0 -3
- package/dist/esm/utils/helpers/index.js.map +0 -1
- package/dist/esm/utils/hooks/index.js +0 -3
- package/dist/esm/utils/hooks/index.js.map +0 -1
- package/dist/esm/utils/hooks/useAnimationFrame.js +0 -3
- package/dist/esm/utils/hooks/useAnimationFrame.js.map +0 -1
- package/dist/esm/utils/hooks/useIsomorphicLayoutEffect.js +0 -3
- package/dist/esm/utils/hooks/useIsomorphicLayoutEffect.js.map +0 -1
- package/dist/esm/utils/hooks/useMediaStream.js +0 -3
- package/dist/esm/utils/hooks/useMediaStream.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,130 +1,81 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
##
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```
|
|
54
|
-
import { Webcam } from '@webcam/react';
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| frontCamera | boolean | false | should use a front camera (MediaTrackConstraints['facingFront'] === 'user') |
|
|
83
|
-
| applyConstraints | boolean | false | should new constraints be applied to the media stream |
|
|
84
|
-
| cameraResolutionMode | string | 'ideal' | video track resolution mode - `('min' \| 'max' \| 'ideal' \| 'exact')` |
|
|
85
|
-
| cameraResolutionType | string | | video track resolution size - `('UHD' \| 'QHD' \| 'FHD' \| 'HD')` |
|
|
86
|
-
| requestTimeLimit | number | | limiting the media stream request by time |
|
|
87
|
-
| onStreamRequest | function | | callback for when component requests a media stream |
|
|
88
|
-
| onStreamStart | function | | callback for when component starts a media stream |
|
|
89
|
-
| onStreamStop | function | | callback for when component stops a media stream |
|
|
90
|
-
| onStreamError | function | | callback for when component can't receive a media stream |
|
|
91
|
-
| audioConstraints | object ||[MediaStreamConstraints['audio']](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints)|
|
|
92
|
-
| videoConstraints | object ||[MediaStreamConstraints['video']](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints)|
|
|
93
|
-
| stream | object ||external [MediaStream](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream) (turns off internal media stream handling logic)|
|
|
94
|
-
|
|
95
|
-
## ✨ Contributors
|
|
96
|
-
|
|
97
|
-
<table>
|
|
98
|
-
<tr>
|
|
99
|
-
<td align="center" style="word-wrap: break-word; width: 100; height: 100">
|
|
100
|
-
<a href="https://github.com/michael-mir">
|
|
101
|
-
<img src="https://avatars.githubusercontent.com/u/88126915?v=4"
|
|
102
|
-
width="100;"
|
|
103
|
-
alt="michael-mir" />
|
|
104
|
-
<br />
|
|
105
|
-
<sub style="font-size:13px"><b>🌶️ michael-mir</b></sub>
|
|
106
|
-
</a>
|
|
107
|
-
</td>
|
|
108
|
-
<td align="center" style="word-wrap: break-word; width: 100; height: 100">
|
|
109
|
-
<a href="https://github.com/debabin">
|
|
110
|
-
<img src="https://avatars.githubusercontent.com/u/45297354?v=4"
|
|
111
|
-
width="100;"
|
|
112
|
-
alt="debabin" />
|
|
113
|
-
<br />
|
|
114
|
-
<sub style="font-size:13px"><b>🧊 debabin</b></sub>
|
|
115
|
-
</a>
|
|
116
|
-
</td>
|
|
117
|
-
<td align="center" style="word-wrap: break-word; width: 100.0; height: 100.0">
|
|
118
|
-
<a href="https://github.com/RiceWithMeat">
|
|
119
|
-
<img src="https://avatars.githubusercontent.com/u/47690223?v=4"
|
|
120
|
-
width="100;"
|
|
121
|
-
alt="RiceWithMeat" />
|
|
122
|
-
<br />
|
|
123
|
-
<sub style="font-size:13px"><b>🐘 RiceWithMeat</b></sub>
|
|
124
|
-
</a>
|
|
125
|
-
</td>
|
|
126
|
-
</tr>
|
|
127
|
-
</table>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>Webcam React</h1>
|
|
3
|
+
|
|
4
|
+
<a href="https://www.npmjs.com/package/@webcam/react"><img alt="NPM version" src="https://img.shields.io/npm/v/@webcam/react.svg?style=for-the-badge&labelColor=000000"></a>
|
|
5
|
+
<a href="https://github.com/siberiacancode/webcam/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/npm/l/@webcam/react.svg?style=for-the-badge&labelColor=000000"></a>
|
|
6
|
+
<a href="https://siberiacancode.github.io/reactuse/"><img alt="reactuse" src="https://img.shields.io/badge/reactuse-blueviolet.svg?style=for-the-badge&logo=npm&labelColor=000000&logoWidth=20"></a>
|
|
7
|
+
<a href="https://github.com/siberiacancode/webcam/discussions"><img alt="Join the community on GitHub" src="https://img.shields.io/badge/Join%20the%20community-blueviolet.svg?style=for-the-badge&logo=React&labelColor=000000&logoWidth=20"></a>
|
|
8
|
+
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
Webcam React is a powerful library that provides easy integration of webcam and media stream features into your React applications. Built with **TypeScript-first** approach, **SSR compatibility**, and **tree-shaking optimization** - everything you need to request, display, and manage camera streams in a modern React app.
|
|
12
|
+
|
|
13
|
+
## Supported Features
|
|
14
|
+
|
|
15
|
+
- **Live webcam preview** - render media streams with a simple React component
|
|
16
|
+
- **Snapshots** - capture the current frame as base64 image data
|
|
17
|
+
- **Constraint controls** - configure camera source, resolution, facing mode, and more
|
|
18
|
+
- **Stream lifecycle hooks** - react to request, start, stop, and error events
|
|
19
|
+
- **External stream support** - attach an existing `MediaStream` when needed
|
|
20
|
+
|
|
21
|
+
## Documentation
|
|
22
|
+
|
|
23
|
+
Visit https://react-webcam-ultimate.vercel.app/en/react to view the full documentation.
|
|
24
|
+
|
|
25
|
+
## Getting Started
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @webcam/react
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import React from 'react';
|
|
33
|
+
import ReactDOM from 'react-dom/client';
|
|
34
|
+
import { Webcam } from '@webcam/react';
|
|
35
|
+
|
|
36
|
+
const App = () => (
|
|
37
|
+
<Webcam
|
|
38
|
+
mirrored
|
|
39
|
+
cameraResolutionType='FHD'
|
|
40
|
+
onStreamError={(error) => console.error(error)}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
45
|
+
<React.StrictMode>
|
|
46
|
+
<App />
|
|
47
|
+
</React.StrictMode>
|
|
48
|
+
);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Create a component to use webcam snapshots:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { Webcam } from '@webcam/react';
|
|
55
|
+
|
|
56
|
+
export const Camera = () => {
|
|
57
|
+
return (
|
|
58
|
+
<Webcam mirrored>
|
|
59
|
+
{({ getSnapshot }) => (
|
|
60
|
+
<button type="button" onClick={() => getSnapshot({ quality: 0.8 })}>
|
|
61
|
+
Make photo
|
|
62
|
+
</button>
|
|
63
|
+
)}
|
|
64
|
+
</Webcam>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Reactuse
|
|
70
|
+
|
|
71
|
+
Reactuse delivers **production-ready hooks** that solve real-world problems. Built with **TypeScript-first** approach, **SSR compatibility**, and **tree-shaking optimization** - everything you need to build modern React applications. Improve your react applications with our library 📦 designed for comfort and speed.
|
|
72
|
+
|
|
73
|
+
## Documentation
|
|
74
|
+
|
|
75
|
+
Visit https://reactuse.org to view the full documentation.
|
|
76
|
+
|
|
77
|
+
## Getting Started
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm install @siberiacancode/reactuse
|
|
81
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));exports.__toESM=s;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./hooks/useWebcam.cjs");let n=require("@webcam/core"),r=require("react");r=e.__toESM(r,1);let i=require("react/jsx-runtime");var a=({ref:e,stream:a,cameraResolutionMode:o,cameraResolutionType:s,videoConstraints:c,audioConstraints:l,requestTimeLimit:u,frontCamera:d,mainCamera:f,mirrored:p=!0,muted:m=!0,style:h={},children:g,onLoadedMetadata:_,onRequest:v,onError:y,onStart:b,onStop:x,...S})=>{let C=(0,r.useRef)(null),w=e??C;return t.useWebcam(w,{stream:a,requestTimeLimit:u,onRequest:v,onError:y,onStart:b,onStop:x,videoConstraints:c,audioConstraints:l,cameraResolutionMode:o,cameraResolutionType:s,frontCamera:d,mainCamera:f,muted:m}),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`video`,{autoPlay:!0,playsInline:!0,ref:w,style:{...h,...p&&{transform:`${h.transform?`${h.transform} `:``}scaleX(-1)`}},controls:!1,muted:m,onLoadedMetadata:e=>{_?.(e),e.currentTarget.play()},...S}),typeof g==`function`?g({element:w.current,getCanvas:e=>w.current?(0,n.getVideoFrameCanvas)(w.current,{...e,mirrored:p}):void 0,getSnapshot:e=>w.current?(0,n.getWebcamSnapshot)(w.current,{...e,mirrored:p}):void 0}):g]})};exports.Webcam=a;
|
|
2
|
+
//# sourceMappingURL=Webcam.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Webcam.cjs","names":[],"sources":["../../../../src/components/Webcam/Webcam.tsx"],"sourcesContent":["import type {\n GetVideoFrameCanvasOptions,\n GetWebcamSnapshotOptions,\n MediaTrackConstraintsOptions\n} from '@webcam/core';\nimport type { ComponentProps, ReactNode, RefObject } from 'react';\n\nimport { getVideoFrameCanvas, getWebcamSnapshot } from '@webcam/core';\nimport React, { useRef } from 'react';\n\nimport { useWebcam } from './hooks';\n\nexport type WebcamRenderProps = (options: {\n getCanvas: (options?: GetVideoFrameCanvasOptions) => HTMLCanvasElement | undefined;\n getSnapshot: (options?: GetWebcamSnapshotOptions) => string | undefined;\n element: HTMLVideoElement | null;\n}) => ReactNode;\n\ninterface BaseWebcamProps\n extends Omit<ComponentProps<'video'>, 'children' | 'onError'>, MediaTrackConstraintsOptions {\n audioConstraints?: MediaTrackConstraints;\n children?: ReactNode | WebcamRenderProps;\n mirrored?: boolean;\n ref?: RefObject<HTMLVideoElement>;\n requestTimeLimit?: number;\n videoConstraints?: MediaTrackConstraints;\n onError?: (error: Error) => void;\n onRequest?: () => void;\n onStart?: (stream: MediaStream) => void;\n onStop?: (stream?: MediaStream) => void;\n}\n\ninterface WebcamPropsWithInternalStream extends BaseWebcamProps {\n stream?: undefined;\n}\n\ninterface WebcamPropsWithExternalStream extends BaseWebcamProps {\n stream?: MediaStream;\n}\n\nexport type WebcamProps = WebcamPropsWithExternalStream | WebcamPropsWithInternalStream;\n\n/**\n * Renders the Webcam component and handles the requesting and displaying of the media stream\n *\n * @param {WebcamProps} props - The props for the Webcam component\n * @return {ReactElement} The rendered Webcam component\n */\nexport const Webcam = ({\n ref,\n stream,\n cameraResolutionMode,\n cameraResolutionType,\n videoConstraints,\n audioConstraints,\n requestTimeLimit,\n frontCamera,\n mainCamera,\n mirrored = true,\n muted = true,\n style = {},\n children,\n onLoadedMetadata,\n onRequest,\n onError,\n onStart,\n onStop,\n ...props\n}: WebcamProps) => {\n const internalVideoRef = useRef<HTMLVideoElement | null>(null);\n const videoRef = ref ?? internalVideoRef;\n\n useWebcam(videoRef, {\n stream,\n requestTimeLimit,\n onRequest,\n onError,\n onStart,\n onStop,\n videoConstraints,\n audioConstraints,\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted\n });\n\n return (\n <>\n <video\n autoPlay\n playsInline\n ref={videoRef}\n style={{\n ...style,\n ...(mirrored && {\n transform: `${style.transform ? `${style.transform} ` : ''}scaleX(-1)`\n })\n }}\n controls={false}\n muted={muted}\n onLoadedMetadata={(event) => {\n onLoadedMetadata?.(event);\n event.currentTarget.play();\n }}\n {...props}\n />\n {typeof children === 'function'\n ? children({\n element: videoRef.current,\n getCanvas: (options?: GetVideoFrameCanvasOptions) =>\n videoRef.current\n ? getVideoFrameCanvas(videoRef.current, { ...options, mirrored })\n : undefined,\n getSnapshot: (options?: GetWebcamSnapshotOptions) =>\n videoRef.current\n ? getWebcamSnapshot(videoRef.current, { ...options, mirrored })\n : undefined\n })\n : children}\n </>\n );\n};\n"],"mappings":"gMAgDA,IAAa,GAAU,CACrB,MACA,SACA,uBACA,uBACA,mBACA,mBACA,mBACA,cACA,aACA,WAAW,GACX,QAAQ,GACR,QAAQ,CAAC,EACT,WACA,mBACA,YACA,UACA,UACA,SACA,GAAG,KACc,CACjB,IAAM,GAAA,EAAA,EAAA,OAAA,CAAmD,IAAI,EACvD,EAAW,GAAO,EAkBxB,OAhBA,EAAA,UAAU,EAAU,CAClB,SACA,mBACA,YACA,UACA,UACA,SACA,mBACA,mBACA,uBACA,uBACA,cACA,aACA,OACF,CAAC,GAGC,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,SAAA,GACA,YAAA,GACA,IAAK,EACL,MAAO,CACL,GAAG,EACH,GAAI,GAAY,CACd,UAAW,GAAG,EAAM,UAAY,GAAG,EAAM,UAAU,GAAK,GAAG,WAC7D,CACF,EACA,SAAU,GACH,QACP,iBAAmB,GAAU,CAC3B,IAAmB,CAAK,EACxB,EAAM,cAAc,KAAK,CAC3B,EACA,GAAI,CACL,CAAA,EACA,OAAO,GAAa,WACjB,EAAS,CACP,QAAS,EAAS,QAClB,UAAY,GACV,EAAS,SAAA,EAAA,EAAA,oBAAA,CACe,EAAS,QAAS,CAAE,GAAG,EAAS,UAAS,CAAC,EAC9D,IAAA,GACN,YAAc,GACZ,EAAS,SAAA,EAAA,EAAA,kBAAA,CACa,EAAS,QAAS,CAAE,GAAG,EAAS,UAAS,CAAC,EAC5D,IAAA,EACR,CAAC,EACD,CACJ,CAAA,CAAA,CAEN"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=require("@siberiacancode/reactuse"),t=require("@webcam/core"),n=require("react");var r=((...r)=>{let i=(0,e.isTarget)(r[0])?r[0]:void 0,{stream:a,videoConstraints:o,audioConstraints:s,cameraResolutionMode:c,cameraResolutionType:l,frontCamera:u,mainCamera:d,muted:f,onRequest:p,onError:m,onStart:h,onStop:g}=(i?r[1]:r[0])??{},_=(0,e.useRefState)(),v=i??_,y=(0,e.useMediaStream)(v,{immediately:!1,onStart:h,onStop:g,onError:m}),b=()=>(0,t.getMediaStreamConstraints)({constraints:{video:o,audio:s},options:{cameraResolutionMode:c,cameraResolutionType:l,frontCamera:u,mainCamera:d,muted:f}});return(0,e.useMount)(()=>{a||(async()=>{p?.();let e=await b();y.start(e)})()}),(0,e.useDidUpdate)(()=>{a||(async()=>{p?.();let e=await b();if(y.stream){await y.apply(e)||y.start(e);return}y.start(e)})()},[o,s,c,l,u,d,f]),(0,n.useEffect)(()=>{if(!a)return;let t=e.isTarget.getElement(v);if(t)return t.srcObject=a,h?.(a),()=>{g?.(a)}},[a,i&&e.isTarget.getRawElement(i),_.state]),(0,e.useUnmount)(()=>{a||y.stop()}),i?{stream:a??y.stream,start:y.start,apply:y.apply,stop:y.stop}:{stream:a??y.stream,start:y.start,apply:y.apply,stop:y.stop,ref:_}});exports.useWebcam=r;
|
|
2
|
+
//# sourceMappingURL=useWebcam.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWebcam.cjs","names":[],"sources":["../../../../../src/components/Webcam/hooks/useWebcam.ts"],"sourcesContent":["import type { HookTarget, StateRef, UseMediaStreamOptions } from '@siberiacancode/reactuse';\nimport type { MediaTrackConstraintsOptions } from '@webcam/core';\n\nimport {\n isTarget,\n useDidUpdate,\n useMediaStream,\n useMount,\n useRefState,\n useUnmount\n} from '@siberiacancode/reactuse';\nimport { getMediaStreamConstraints } from '@webcam/core';\nimport { useEffect } from 'react';\n\nexport interface UseWebcamParams extends MediaTrackConstraintsOptions {\n audioConstraints?: MediaTrackConstraints;\n requestTimeLimit?: number;\n stream?: MediaStream;\n videoConstraints?: MediaTrackConstraints;\n onError?: (error: Error) => void;\n onRequest?: () => void;\n onStart?: (stream: MediaStream) => void;\n onStop?: (stream?: MediaStream) => void;\n}\n\nexport interface UseWebcamReturn {\n stream?: MediaStream;\n apply: (constraints: MediaStreamConstraints) => Promise<boolean>;\n start: (constraints?: MediaStreamConstraints) => Promise<MediaStream | undefined>;\n stop: () => void;\n}\n\nexport interface UseWebcam {\n (target: HookTarget, params?: UseWebcamParams): UseWebcamReturn;\n\n (params?: UseWebcamParams): UseWebcamReturn & {\n ref: StateRef<HTMLVideoElement>;\n };\n}\n\n/**\n * @name useWebcam\n * @description - Hook that manages a webcam media stream for a video element\n *\n * @overload\n * @param {HookTarget} target The target video element the stream will be attached to\n * @param {UseWebcamParams} [params] The webcam parameters\n * @returns {UseWebcamReturn} An object containing the stream and controls\n *\n * @overload\n * @param {UseWebcamParams} [params] The webcam parameters\n * @returns {UseWebcamReturn & { ref: StateRef<HTMLVideoElement> }} An object containing the stream, controls and ref\n */\nexport const useWebcam = ((...params: any[]) => {\n const target = (isTarget(params[0]) ? params[0] : undefined) as HookTarget | undefined;\n const options = ((target ? params[1] : params[0]) as UseWebcamParams) ?? {};\n\n const {\n stream: externalStream,\n videoConstraints,\n audioConstraints,\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted,\n onRequest,\n onError,\n onStart,\n onStop\n } = options;\n\n const internalRef = useRefState<HTMLVideoElement>();\n const resolvedRef = (target ?? internalRef) as HookTarget;\n\n const mediaStream = useMediaStream(resolvedRef, {\n immediately: false,\n onStart,\n onStop,\n onError\n } satisfies UseMediaStreamOptions);\n\n const createConstraints = () =>\n getMediaStreamConstraints({\n constraints: {\n video: videoConstraints,\n audio: audioConstraints\n },\n options: {\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted\n }\n });\n\n useMount(() => {\n if (externalStream) return;\n const run = async () => {\n onRequest?.();\n const constraints = await createConstraints();\n mediaStream.start(constraints);\n };\n\n run();\n });\n\n useDidUpdate(() => {\n if (externalStream) return;\n\n const run = async () => {\n onRequest?.();\n const constraints = await createConstraints();\n\n if (mediaStream.stream) {\n const ok = await mediaStream.apply(constraints);\n if (!ok) mediaStream.start(constraints);\n return;\n }\n\n mediaStream.start(constraints);\n };\n\n run();\n }, [\n videoConstraints,\n audioConstraints,\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted\n ]);\n\n useEffect(() => {\n if (!externalStream) return;\n\n const element = isTarget.getElement(resolvedRef) as HTMLVideoElement | null;\n if (!element) return;\n\n element.srcObject = externalStream;\n onStart?.(externalStream);\n\n return () => {\n onStop?.(externalStream);\n };\n }, [externalStream, target && isTarget.getRawElement(target), internalRef.state]);\n\n useUnmount(() => {\n if (externalStream) return;\n mediaStream.stop();\n });\n\n if (target)\n return {\n stream: externalStream ?? mediaStream.stream,\n start: mediaStream.start,\n apply: mediaStream.apply,\n stop: mediaStream.stop\n };\n return {\n stream: externalStream ?? mediaStream.stream,\n start: mediaStream.start,\n apply: mediaStream.apply,\n stop: mediaStream.stop,\n ref: internalRef\n };\n}) as UseWebcam;\n"],"mappings":"uFAqDA,IAAa,IAAc,GAAG,IAAkB,CAC9C,IAAM,GAAA,EAAA,EAAA,SAAA,CAAmB,EAAO,EAAE,EAAI,EAAO,GAAK,IAAA,GAG5C,CACJ,OAAQ,EACR,mBACA,mBACA,uBACA,uBACA,cACA,aACA,QACA,YACA,UACA,UACA,WAdgB,EAAS,EAAO,GAAK,EAAO,KAA2B,CAAC,EAiBpE,GAAA,EAAA,EAAA,YAAA,CAA4C,EAC5C,EAAe,GAAU,EAEzB,GAAA,EAAA,EAAA,eAAA,CAA6B,EAAa,CAC9C,YAAa,GACb,UACA,SACA,SACF,CAAiC,EAE3B,OAAA,EAAA,EAAA,0BAAA,CACsB,CACxB,YAAa,CACX,MAAO,EACP,MAAO,CACT,EACA,QAAS,CACP,uBACA,uBACA,cACA,aACA,OACF,CACF,CAAC,EAkEH,OAhEA,EAAA,EAAA,SAAA,KAAe,CACT,IAOJ,SANwB,CACtB,IAAY,EACZ,IAAM,EAAc,MAAM,EAAkB,EAC5C,EAAY,MAAM,CAAW,CAC/B,EAEA,CAAI,CACN,CAAC,GAED,EAAA,EAAA,aAAA,KAAmB,CACb,IAeJ,SAbwB,CACtB,IAAY,EACZ,IAAM,EAAc,MAAM,EAAkB,EAE5C,GAAI,EAAY,OAAQ,CAEjB,MADY,EAAY,MAAM,CAAW,GACrC,EAAY,MAAM,CAAW,EACtC,MACF,CAEA,EAAY,MAAM,CAAW,CAC/B,EAEA,CAAI,CACN,EAAG,CACD,EACA,EACA,EACA,EACA,EACA,EACA,CACF,CAAC,GAED,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,CAAC,EAAgB,OAErB,IAAM,EAAU,EAAA,SAAS,WAAW,CAAW,EAC1C,KAKL,MAHA,GAAQ,UAAY,EACpB,IAAU,CAAc,MAEX,CACX,IAAS,CAAc,CACzB,CACF,EAAG,CAAC,EAAgB,GAAU,EAAA,SAAS,cAAc,CAAM,EAAG,EAAY,KAAK,CAAC,GAEhF,EAAA,EAAA,WAAA,KAAiB,CACX,GACJ,EAAY,KAAK,CACnB,CAAC,EAEG,EACK,CACL,OAAQ,GAAkB,EAAY,OACtC,MAAO,EAAY,MACnB,MAAO,EAAY,MACnB,KAAM,EAAY,IACpB,EACK,CACL,OAAQ,GAAkB,EAAY,OACtC,MAAO,EAAY,MACnB,MAAO,EAAY,MACnB,KAAM,EAAY,KAClB,IAAK,CACP,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./components/Webcam/hooks/useWebcam.cjs"),t=require("./components/Webcam/Webcam.cjs"),n=require("./utils/hooks/useAnimationFrame.cjs");let r=require("@webcam/core");exports.Webcam=t.Webcam,Object.defineProperty(exports,"applyMediaStreamConstraints",{enumerable:!0,get:function(){return r.applyMediaStreamConstraints}}),Object.defineProperty(exports,"canGetUserMedia",{enumerable:!0,get:function(){return r.canGetUserMedia}}),Object.defineProperty(exports,"getDevices",{enumerable:!0,get:function(){return r.getDevices}}),Object.defineProperty(exports,"getMediaStream",{enumerable:!0,get:function(){return r.getMediaStream}}),Object.defineProperty(exports,"getMediaStreamConstraints",{enumerable:!0,get:function(){return r.getMediaStreamConstraints}}),Object.defineProperty(exports,"getVideoFrameCanvas",{enumerable:!0,get:function(){return r.getVideoFrameCanvas}}),Object.defineProperty(exports,"getWebcamSnapshot",{enumerable:!0,get:function(){return r.getWebcamSnapshot}}),Object.defineProperty(exports,"stopMediaStream",{enumerable:!0,get:function(){return r.stopMediaStream}}),exports.useAnimationFrame=n.useAnimationFrame,exports.useWebcam=e.useWebcam;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame;exports.cancelAnimationFrame=t,exports.requestAnimationFrame=e;
|
|
2
|
+
//# sourceMappingURL=animationFrame.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animationFrame.cjs","names":[],"sources":["../../../../src/utils/helpers/animationFrame.ts"],"sourcesContent":["// ✅ important\n// Implementations for each browser need to be supported\nexport const requestAnimationFrame =\n window.requestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.msRequestAnimationFrame;\n\nexport const cancelAnimationFrame =\n window.cancelAnimationFrame ||\n window.mozCancelAnimationFrame ||\n window.webkitCancelAnimationFrame ||\n window.msCancelAnimationFrame;\n"],"mappings":"AAEA,IAAa,EACX,OAAO,uBACP,OAAO,0BACP,OAAO,6BACP,OAAO,wBAEI,EACX,OAAO,sBACP,OAAO,yBACP,OAAO,4BACP,OAAO"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../helpers/animationFrame.cjs");let t=require("@siberiacancode/reactuse"),n=require("react");var r=(r,i)=>{let a=(0,n.useRef)(void 0),o=(0,n.useRef)(void 0),s=(0,n.useRef)(r);(0,t.useIsomorphicLayoutEffect)(()=>{s.current=r},[r]);let c=t=>{if(t){if(o.current=t,o.current===void 0)return;s.current(t-o.current)}a.current=e.requestAnimationFrame(c)},l=()=>{a.current&&e.cancelAnimationFrame(a.current)};return(0,n.useEffect)(()=>{if(i){a.current=e.requestAnimationFrame(c);return}return l(),()=>l()},[i]),{request:c,cancel:l}};exports.useAnimationFrame=r;
|
|
2
|
+
//# sourceMappingURL=useAnimationFrame.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnimationFrame.cjs","names":[],"sources":["../../../../src/utils/hooks/useAnimationFrame.ts"],"sourcesContent":["import { useIsomorphicLayoutEffect } from '@siberiacancode/reactuse';\nimport { useEffect, useRef } from 'react';\n\nimport { cancelAnimationFrame, requestAnimationFrame } from '../helpers';\n\n/**\n * Helps request and cancel animation frame\n *\n * @param {Function} callback - frame request callback\n * @param {boolean} active - should animation frame be requested\n * @return {object} request/cancel animation frame handlers\n */\nexport const useAnimationFrame = (callback: (time: number) => void, active?: boolean) => {\n const animationFrameRequestRef = useRef<number>(undefined);\n const previousTimestampRef = useRef<number>(undefined);\n const savedHandlerRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n savedHandlerRef.current = callback;\n }, [callback]);\n\n const onFrameRequest = (timestamp?: DOMHighResTimeStamp) => {\n if (timestamp) {\n previousTimestampRef.current = timestamp;\n if (previousTimestampRef.current === undefined) return;\n savedHandlerRef.current(timestamp - previousTimestampRef.current);\n }\n\n animationFrameRequestRef.current = requestAnimationFrame(onFrameRequest);\n };\n\n const onFrameCancel = () => {\n if (!animationFrameRequestRef.current) return;\n cancelAnimationFrame(animationFrameRequestRef.current);\n };\n\n useEffect(() => {\n if (active) {\n animationFrameRequestRef.current = requestAnimationFrame(onFrameRequest);\n return;\n }\n\n onFrameCancel();\n return () => onFrameCancel();\n }, [active]);\n\n return {\n request: onFrameRequest,\n cancel: onFrameCancel\n };\n};\n"],"mappings":"8GAYA,IAAa,GAAqB,EAAkC,IAAqB,CACvF,IAAM,GAAA,EAAA,EAAA,OAAA,CAA0C,IAAA,EAAS,EACnD,GAAA,EAAA,EAAA,OAAA,CAAsC,IAAA,EAAS,EAC/C,GAAA,EAAA,EAAA,OAAA,CAAyB,CAAQ,GAEvC,EAAA,EAAA,0BAAA,KAAgC,CAC9B,EAAgB,QAAU,CAC5B,EAAG,CAAC,CAAQ,CAAC,EAEb,IAAM,EAAkB,GAAoC,CAC1D,GAAI,EAAW,CAEb,GADA,EAAqB,QAAU,EAC3B,EAAqB,UAAY,IAAA,GAAW,OAChD,EAAgB,QAAQ,EAAY,EAAqB,OAAO,CAClE,CAEA,EAAyB,QAAU,EAAA,sBAAsB,CAAc,CACzE,EAEM,MAAsB,CACrB,EAAyB,SAC9B,EAAA,qBAAqB,EAAyB,OAAO,CACvD,EAYA,OAVA,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,EAAQ,CACV,EAAyB,QAAU,EAAA,sBAAsB,CAAc,EACvE,MACF,CAGA,OADA,EAAc,MACD,EAAc,CAC7B,EAAG,CAAC,CAAM,CAAC,EAEJ,CACL,QAAS,EACT,OAAQ,CACV,CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { GetVideoFrameCanvasOptions, GetWebcamSnapshotOptions, MediaTrackConstraintsOptions } from '@webcam/core';
|
|
2
|
+
import { ComponentProps, ReactNode, RefObject, default as React } from 'react';
|
|
3
|
+
export type WebcamRenderProps = (options: {
|
|
4
|
+
getCanvas: (options?: GetVideoFrameCanvasOptions) => HTMLCanvasElement | undefined;
|
|
5
|
+
getSnapshot: (options?: GetWebcamSnapshotOptions) => string | undefined;
|
|
6
|
+
element: HTMLVideoElement | null;
|
|
7
|
+
}) => ReactNode;
|
|
8
|
+
interface BaseWebcamProps extends Omit<ComponentProps<'video'>, 'children' | 'onError'>, MediaTrackConstraintsOptions {
|
|
9
|
+
audioConstraints?: MediaTrackConstraints;
|
|
10
|
+
children?: ReactNode | WebcamRenderProps;
|
|
11
|
+
mirrored?: boolean;
|
|
12
|
+
ref?: RefObject<HTMLVideoElement>;
|
|
13
|
+
requestTimeLimit?: number;
|
|
14
|
+
videoConstraints?: MediaTrackConstraints;
|
|
15
|
+
onError?: (error: Error) => void;
|
|
16
|
+
onRequest?: () => void;
|
|
17
|
+
onStart?: (stream: MediaStream) => void;
|
|
18
|
+
onStop?: (stream?: MediaStream) => void;
|
|
19
|
+
}
|
|
20
|
+
interface WebcamPropsWithInternalStream extends BaseWebcamProps {
|
|
21
|
+
stream?: undefined;
|
|
22
|
+
}
|
|
23
|
+
interface WebcamPropsWithExternalStream extends BaseWebcamProps {
|
|
24
|
+
stream?: MediaStream;
|
|
25
|
+
}
|
|
26
|
+
export type WebcamProps = WebcamPropsWithExternalStream | WebcamPropsWithInternalStream;
|
|
27
|
+
/**
|
|
28
|
+
* Renders the Webcam component and handles the requesting and displaying of the media stream
|
|
29
|
+
*
|
|
30
|
+
* @param {WebcamProps} props - The props for the Webcam component
|
|
31
|
+
* @return {ReactElement} The rendered Webcam component
|
|
32
|
+
*/
|
|
33
|
+
export declare const Webcam: ({ ref, stream, cameraResolutionMode, cameraResolutionType, videoConstraints, audioConstraints, requestTimeLimit, frontCamera, mainCamera, mirrored, muted, style, children, onLoadedMetadata, onRequest, onError, onStart, onStop, ...props }: WebcamProps) => React.JSX.Element;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useWebcam';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { HookTarget, StateRef } from '@siberiacancode/reactuse';
|
|
2
|
+
import { MediaTrackConstraintsOptions } from '@webcam/core';
|
|
3
|
+
export interface UseWebcamParams extends MediaTrackConstraintsOptions {
|
|
4
|
+
audioConstraints?: MediaTrackConstraints;
|
|
5
|
+
requestTimeLimit?: number;
|
|
6
|
+
stream?: MediaStream;
|
|
7
|
+
videoConstraints?: MediaTrackConstraints;
|
|
8
|
+
onError?: (error: Error) => void;
|
|
9
|
+
onRequest?: () => void;
|
|
10
|
+
onStart?: (stream: MediaStream) => void;
|
|
11
|
+
onStop?: (stream?: MediaStream) => void;
|
|
12
|
+
}
|
|
13
|
+
export interface UseWebcamReturn {
|
|
14
|
+
stream?: MediaStream;
|
|
15
|
+
apply: (constraints: MediaStreamConstraints) => Promise<boolean>;
|
|
16
|
+
start: (constraints?: MediaStreamConstraints) => Promise<MediaStream | undefined>;
|
|
17
|
+
stop: () => void;
|
|
18
|
+
}
|
|
19
|
+
export interface UseWebcam {
|
|
20
|
+
(target: HookTarget, params?: UseWebcamParams): UseWebcamReturn;
|
|
21
|
+
(params?: UseWebcamParams): UseWebcamReturn & {
|
|
22
|
+
ref: StateRef<HTMLVideoElement>;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @name useWebcam
|
|
27
|
+
* @description - Hook that manages a webcam media stream for a video element
|
|
28
|
+
*
|
|
29
|
+
* @overload
|
|
30
|
+
* @param {HookTarget} target The target video element the stream will be attached to
|
|
31
|
+
* @param {UseWebcamParams} [params] The webcam parameters
|
|
32
|
+
* @returns {UseWebcamReturn} An object containing the stream and controls
|
|
33
|
+
*
|
|
34
|
+
* @overload
|
|
35
|
+
* @param {UseWebcamParams} [params] The webcam parameters
|
|
36
|
+
* @returns {UseWebcamReturn & { ref: StateRef<HTMLVideoElement> }} An object containing the stream, controls and ref
|
|
37
|
+
*/
|
|
38
|
+
export declare const useWebcam: UseWebcam;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useWebcam as e } from "./hooks/useWebcam.mjs";
|
|
2
|
+
import { getVideoFrameCanvas as t, getWebcamSnapshot as n } from "@webcam/core";
|
|
3
|
+
import { useRef as r } from "react";
|
|
4
|
+
import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/Webcam/Webcam.tsx
|
|
6
|
+
var s = ({ ref: s, stream: c, cameraResolutionMode: l, cameraResolutionType: u, videoConstraints: d, audioConstraints: f, requestTimeLimit: p, frontCamera: m, mainCamera: h, mirrored: g = !0, muted: _ = !0, style: v = {}, children: y, onLoadedMetadata: b, onRequest: x, onError: S, onStart: C, onStop: w, ...T }) => {
|
|
7
|
+
let E = r(null), D = s ?? E;
|
|
8
|
+
return e(D, {
|
|
9
|
+
stream: c,
|
|
10
|
+
requestTimeLimit: p,
|
|
11
|
+
onRequest: x,
|
|
12
|
+
onError: S,
|
|
13
|
+
onStart: C,
|
|
14
|
+
onStop: w,
|
|
15
|
+
videoConstraints: d,
|
|
16
|
+
audioConstraints: f,
|
|
17
|
+
cameraResolutionMode: l,
|
|
18
|
+
cameraResolutionType: u,
|
|
19
|
+
frontCamera: m,
|
|
20
|
+
mainCamera: h,
|
|
21
|
+
muted: _
|
|
22
|
+
}), /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("video", {
|
|
23
|
+
autoPlay: !0,
|
|
24
|
+
playsInline: !0,
|
|
25
|
+
ref: D,
|
|
26
|
+
style: {
|
|
27
|
+
...v,
|
|
28
|
+
...g && { transform: `${v.transform ? `${v.transform} ` : ""}scaleX(-1)` }
|
|
29
|
+
},
|
|
30
|
+
controls: !1,
|
|
31
|
+
muted: _,
|
|
32
|
+
onLoadedMetadata: (e) => {
|
|
33
|
+
b?.(e), e.currentTarget.play();
|
|
34
|
+
},
|
|
35
|
+
...T
|
|
36
|
+
}), typeof y == "function" ? y({
|
|
37
|
+
element: D.current,
|
|
38
|
+
getCanvas: (e) => D.current ? t(D.current, {
|
|
39
|
+
...e,
|
|
40
|
+
mirrored: g
|
|
41
|
+
}) : void 0,
|
|
42
|
+
getSnapshot: (e) => D.current ? n(D.current, {
|
|
43
|
+
...e,
|
|
44
|
+
mirrored: g
|
|
45
|
+
}) : void 0
|
|
46
|
+
}) : y] });
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { s as Webcam };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=Webcam.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Webcam.mjs","names":[],"sources":["../../../../src/components/Webcam/Webcam.tsx"],"sourcesContent":["import type {\n GetVideoFrameCanvasOptions,\n GetWebcamSnapshotOptions,\n MediaTrackConstraintsOptions\n} from '@webcam/core';\nimport type { ComponentProps, ReactNode, RefObject } from 'react';\n\nimport { getVideoFrameCanvas, getWebcamSnapshot } from '@webcam/core';\nimport React, { useRef } from 'react';\n\nimport { useWebcam } from './hooks';\n\nexport type WebcamRenderProps = (options: {\n getCanvas: (options?: GetVideoFrameCanvasOptions) => HTMLCanvasElement | undefined;\n getSnapshot: (options?: GetWebcamSnapshotOptions) => string | undefined;\n element: HTMLVideoElement | null;\n}) => ReactNode;\n\ninterface BaseWebcamProps\n extends Omit<ComponentProps<'video'>, 'children' | 'onError'>, MediaTrackConstraintsOptions {\n audioConstraints?: MediaTrackConstraints;\n children?: ReactNode | WebcamRenderProps;\n mirrored?: boolean;\n ref?: RefObject<HTMLVideoElement>;\n requestTimeLimit?: number;\n videoConstraints?: MediaTrackConstraints;\n onError?: (error: Error) => void;\n onRequest?: () => void;\n onStart?: (stream: MediaStream) => void;\n onStop?: (stream?: MediaStream) => void;\n}\n\ninterface WebcamPropsWithInternalStream extends BaseWebcamProps {\n stream?: undefined;\n}\n\ninterface WebcamPropsWithExternalStream extends BaseWebcamProps {\n stream?: MediaStream;\n}\n\nexport type WebcamProps = WebcamPropsWithExternalStream | WebcamPropsWithInternalStream;\n\n/**\n * Renders the Webcam component and handles the requesting and displaying of the media stream\n *\n * @param {WebcamProps} props - The props for the Webcam component\n * @return {ReactElement} The rendered Webcam component\n */\nexport const Webcam = ({\n ref,\n stream,\n cameraResolutionMode,\n cameraResolutionType,\n videoConstraints,\n audioConstraints,\n requestTimeLimit,\n frontCamera,\n mainCamera,\n mirrored = true,\n muted = true,\n style = {},\n children,\n onLoadedMetadata,\n onRequest,\n onError,\n onStart,\n onStop,\n ...props\n}: WebcamProps) => {\n const internalVideoRef = useRef<HTMLVideoElement | null>(null);\n const videoRef = ref ?? internalVideoRef;\n\n useWebcam(videoRef, {\n stream,\n requestTimeLimit,\n onRequest,\n onError,\n onStart,\n onStop,\n videoConstraints,\n audioConstraints,\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted\n });\n\n return (\n <>\n <video\n autoPlay\n playsInline\n ref={videoRef}\n style={{\n ...style,\n ...(mirrored && {\n transform: `${style.transform ? `${style.transform} ` : ''}scaleX(-1)`\n })\n }}\n controls={false}\n muted={muted}\n onLoadedMetadata={(event) => {\n onLoadedMetadata?.(event);\n event.currentTarget.play();\n }}\n {...props}\n />\n {typeof children === 'function'\n ? children({\n element: videoRef.current,\n getCanvas: (options?: GetVideoFrameCanvasOptions) =>\n videoRef.current\n ? getVideoFrameCanvas(videoRef.current, { ...options, mirrored })\n : undefined,\n getSnapshot: (options?: GetWebcamSnapshotOptions) =>\n videoRef.current\n ? getWebcamSnapshot(videoRef.current, { ...options, mirrored })\n : undefined\n })\n : children}\n </>\n );\n};\n"],"mappings":";;;;;AAgDA,IAAa,KAAU,EACrB,QACA,WACA,yBACA,yBACA,qBACA,qBACA,qBACA,gBACA,eACA,cAAW,IACX,WAAQ,IACR,WAAQ,CAAC,GACT,aACA,qBACA,cACA,YACA,YACA,WACA,GAAG,QACc;CACjB,IAAM,IAAmB,EAAgC,IAAI,GACvD,IAAW,KAAO;CAkBxB,OAhBA,EAAU,GAAU;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAGC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,SAAD;EACE,UAAA;EACA,aAAA;EACA,KAAK;EACL,OAAO;GACL,GAAG;GACH,GAAI,KAAY,EACd,WAAW,GAAG,EAAM,YAAY,GAAG,EAAM,UAAU,KAAK,GAAG,YAC7D;EACF;EACA,UAAU;EACH;EACP,mBAAmB,MAAU;GAE3B,AADA,IAAmB,CAAK,GACxB,EAAM,cAAc,KAAK;EAC3B;EACA,GAAI;CACL,CAAA,GACA,OAAO,KAAa,aACjB,EAAS;EACP,SAAS,EAAS;EAClB,YAAY,MACV,EAAS,UACL,EAAoB,EAAS,SAAS;GAAE,GAAG;GAAS;EAAS,CAAC,IAC9D,KAAA;EACN,cAAc,MACZ,EAAS,UACL,EAAkB,EAAS,SAAS;GAAE,GAAG;GAAS;EAAS,CAAC,IAC5D,KAAA;CACR,CAAC,IACD,CACJ,EAAA,CAAA;AAEN"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { isTarget as e, useDidUpdate as t, useMediaStream as n, useMount as r, useRefState as i, useUnmount as a } from "@siberiacancode/reactuse";
|
|
2
|
+
import { getMediaStreamConstraints as o } from "@webcam/core";
|
|
3
|
+
import { useEffect as s } from "react";
|
|
4
|
+
//#region src/components/Webcam/hooks/useWebcam.ts
|
|
5
|
+
var c = ((...c) => {
|
|
6
|
+
let l = e(c[0]) ? c[0] : void 0, { stream: u, videoConstraints: d, audioConstraints: f, cameraResolutionMode: p, cameraResolutionType: m, frontCamera: h, mainCamera: g, muted: _, onRequest: v, onError: y, onStart: b, onStop: x } = (l ? c[1] : c[0]) ?? {}, S = i(), C = l ?? S, w = n(C, {
|
|
7
|
+
immediately: !1,
|
|
8
|
+
onStart: b,
|
|
9
|
+
onStop: x,
|
|
10
|
+
onError: y
|
|
11
|
+
}), T = () => o({
|
|
12
|
+
constraints: {
|
|
13
|
+
video: d,
|
|
14
|
+
audio: f
|
|
15
|
+
},
|
|
16
|
+
options: {
|
|
17
|
+
cameraResolutionMode: p,
|
|
18
|
+
cameraResolutionType: m,
|
|
19
|
+
frontCamera: h,
|
|
20
|
+
mainCamera: g,
|
|
21
|
+
muted: _
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return r(() => {
|
|
25
|
+
u || (async () => {
|
|
26
|
+
v?.();
|
|
27
|
+
let e = await T();
|
|
28
|
+
w.start(e);
|
|
29
|
+
})();
|
|
30
|
+
}), t(() => {
|
|
31
|
+
u || (async () => {
|
|
32
|
+
v?.();
|
|
33
|
+
let e = await T();
|
|
34
|
+
if (w.stream) {
|
|
35
|
+
await w.apply(e) || w.start(e);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
w.start(e);
|
|
39
|
+
})();
|
|
40
|
+
}, [
|
|
41
|
+
d,
|
|
42
|
+
f,
|
|
43
|
+
p,
|
|
44
|
+
m,
|
|
45
|
+
h,
|
|
46
|
+
g,
|
|
47
|
+
_
|
|
48
|
+
]), s(() => {
|
|
49
|
+
if (!u) return;
|
|
50
|
+
let t = e.getElement(C);
|
|
51
|
+
if (t) return t.srcObject = u, b?.(u), () => {
|
|
52
|
+
x?.(u);
|
|
53
|
+
};
|
|
54
|
+
}, [
|
|
55
|
+
u,
|
|
56
|
+
l && e.getRawElement(l),
|
|
57
|
+
S.state
|
|
58
|
+
]), a(() => {
|
|
59
|
+
u || w.stop();
|
|
60
|
+
}), l ? {
|
|
61
|
+
stream: u ?? w.stream,
|
|
62
|
+
start: w.start,
|
|
63
|
+
apply: w.apply,
|
|
64
|
+
stop: w.stop
|
|
65
|
+
} : {
|
|
66
|
+
stream: u ?? w.stream,
|
|
67
|
+
start: w.start,
|
|
68
|
+
apply: w.apply,
|
|
69
|
+
stop: w.stop,
|
|
70
|
+
ref: S
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
//#endregion
|
|
74
|
+
export { c as useWebcam };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=useWebcam.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWebcam.mjs","names":[],"sources":["../../../../../src/components/Webcam/hooks/useWebcam.ts"],"sourcesContent":["import type { HookTarget, StateRef, UseMediaStreamOptions } from '@siberiacancode/reactuse';\nimport type { MediaTrackConstraintsOptions } from '@webcam/core';\n\nimport {\n isTarget,\n useDidUpdate,\n useMediaStream,\n useMount,\n useRefState,\n useUnmount\n} from '@siberiacancode/reactuse';\nimport { getMediaStreamConstraints } from '@webcam/core';\nimport { useEffect } from 'react';\n\nexport interface UseWebcamParams extends MediaTrackConstraintsOptions {\n audioConstraints?: MediaTrackConstraints;\n requestTimeLimit?: number;\n stream?: MediaStream;\n videoConstraints?: MediaTrackConstraints;\n onError?: (error: Error) => void;\n onRequest?: () => void;\n onStart?: (stream: MediaStream) => void;\n onStop?: (stream?: MediaStream) => void;\n}\n\nexport interface UseWebcamReturn {\n stream?: MediaStream;\n apply: (constraints: MediaStreamConstraints) => Promise<boolean>;\n start: (constraints?: MediaStreamConstraints) => Promise<MediaStream | undefined>;\n stop: () => void;\n}\n\nexport interface UseWebcam {\n (target: HookTarget, params?: UseWebcamParams): UseWebcamReturn;\n\n (params?: UseWebcamParams): UseWebcamReturn & {\n ref: StateRef<HTMLVideoElement>;\n };\n}\n\n/**\n * @name useWebcam\n * @description - Hook that manages a webcam media stream for a video element\n *\n * @overload\n * @param {HookTarget} target The target video element the stream will be attached to\n * @param {UseWebcamParams} [params] The webcam parameters\n * @returns {UseWebcamReturn} An object containing the stream and controls\n *\n * @overload\n * @param {UseWebcamParams} [params] The webcam parameters\n * @returns {UseWebcamReturn & { ref: StateRef<HTMLVideoElement> }} An object containing the stream, controls and ref\n */\nexport const useWebcam = ((...params: any[]) => {\n const target = (isTarget(params[0]) ? params[0] : undefined) as HookTarget | undefined;\n const options = ((target ? params[1] : params[0]) as UseWebcamParams) ?? {};\n\n const {\n stream: externalStream,\n videoConstraints,\n audioConstraints,\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted,\n onRequest,\n onError,\n onStart,\n onStop\n } = options;\n\n const internalRef = useRefState<HTMLVideoElement>();\n const resolvedRef = (target ?? internalRef) as HookTarget;\n\n const mediaStream = useMediaStream(resolvedRef, {\n immediately: false,\n onStart,\n onStop,\n onError\n } satisfies UseMediaStreamOptions);\n\n const createConstraints = () =>\n getMediaStreamConstraints({\n constraints: {\n video: videoConstraints,\n audio: audioConstraints\n },\n options: {\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted\n }\n });\n\n useMount(() => {\n if (externalStream) return;\n const run = async () => {\n onRequest?.();\n const constraints = await createConstraints();\n mediaStream.start(constraints);\n };\n\n run();\n });\n\n useDidUpdate(() => {\n if (externalStream) return;\n\n const run = async () => {\n onRequest?.();\n const constraints = await createConstraints();\n\n if (mediaStream.stream) {\n const ok = await mediaStream.apply(constraints);\n if (!ok) mediaStream.start(constraints);\n return;\n }\n\n mediaStream.start(constraints);\n };\n\n run();\n }, [\n videoConstraints,\n audioConstraints,\n cameraResolutionMode,\n cameraResolutionType,\n frontCamera,\n mainCamera,\n muted\n ]);\n\n useEffect(() => {\n if (!externalStream) return;\n\n const element = isTarget.getElement(resolvedRef) as HTMLVideoElement | null;\n if (!element) return;\n\n element.srcObject = externalStream;\n onStart?.(externalStream);\n\n return () => {\n onStop?.(externalStream);\n };\n }, [externalStream, target && isTarget.getRawElement(target), internalRef.state]);\n\n useUnmount(() => {\n if (externalStream) return;\n mediaStream.stop();\n });\n\n if (target)\n return {\n stream: externalStream ?? mediaStream.stream,\n start: mediaStream.start,\n apply: mediaStream.apply,\n stop: mediaStream.stop\n };\n return {\n stream: externalStream ?? mediaStream.stream,\n start: mediaStream.start,\n apply: mediaStream.apply,\n stop: mediaStream.stop,\n ref: internalRef\n };\n}) as UseWebcam;\n"],"mappings":";;;;AAqDA,IAAa,MAAc,GAAG,MAAkB;CAC9C,IAAM,IAAU,EAAS,EAAO,EAAE,IAAI,EAAO,KAAK,KAAA,GAG5C,EACJ,QAAQ,GACR,qBACA,qBACA,yBACA,yBACA,gBACA,eACA,UACA,cACA,YACA,YACA,eAdgB,IAAS,EAAO,KAAK,EAAO,OAA2B,CAAC,GAiBpE,IAAc,EAA8B,GAC5C,IAAe,KAAU,GAEzB,IAAc,EAAe,GAAa;EAC9C,aAAa;EACb;EACA;EACA;CACF,CAAiC,GAE3B,UACJ,EAA0B;EACxB,aAAa;GACX,OAAO;GACP,OAAO;EACT;EACA,SAAS;GACP;GACA;GACA;GACA;GACA;EACF;CACF,CAAC;CAkEH,OAhEA,QAAe;EACT,MAOJ,YANwB;GACtB,IAAY;GACZ,IAAM,IAAc,MAAM,EAAkB;GAC5C,EAAY,MAAM,CAAW;EAC/B,EAEA,CAAI;CACN,CAAC,GAED,QAAmB;EACb,MAeJ,YAbwB;GACtB,IAAY;GACZ,IAAM,IAAc,MAAM,EAAkB;GAE5C,IAAI,EAAY,QAAQ;IAEtB,AAAK,MADY,EAAY,MAAM,CAAW,KACrC,EAAY,MAAM,CAAW;IACtC;GACF;GAEA,EAAY,MAAM,CAAW;EAC/B,EAEA,CAAI;CACN,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAED,QAAgB;EACd,IAAI,CAAC,GAAgB;EAErB,IAAM,IAAU,EAAS,WAAW,CAAW;EAC1C,OAKL,OAHA,EAAQ,YAAY,GACpB,IAAU,CAAc,SAEX;GACX,IAAS,CAAc;EACzB;CACF,GAAG;EAAC;EAAgB,KAAU,EAAS,cAAc,CAAM;EAAG,EAAY;CAAK,CAAC,GAEhF,QAAiB;EACX,KACJ,EAAY,KAAK;CACnB,CAAC,GAEG,IACK;EACL,QAAQ,KAAkB,EAAY;EACtC,OAAO,EAAY;EACnB,OAAO,EAAY;EACnB,MAAM,EAAY;CACpB,IACK;EACL,QAAQ,KAAkB,EAAY;EACtC,OAAO,EAAY;EACnB,OAAO,EAAY;EACnB,MAAM,EAAY;EAClB,KAAK;CACP;AACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { useWebcam as e } from "./components/Webcam/hooks/useWebcam.mjs";
|
|
2
|
+
import { Webcam as t } from "./components/Webcam/Webcam.mjs";
|
|
3
|
+
import { useAnimationFrame as n } from "./utils/hooks/useAnimationFrame.mjs";
|
|
4
|
+
import { applyMediaStreamConstraints as r, canGetUserMedia as i, getDevices as a, getMediaStream as o, getMediaStreamConstraints as s, getVideoFrameCanvas as c, getWebcamSnapshot as l, stopMediaStream as u } from "@webcam/core";
|
|
5
|
+
export { t as Webcam, r as applyMediaStreamConstraints, i as canGetUserMedia, a as getDevices, o as getMediaStream, s as getMediaStreamConstraints, c as getVideoFrameCanvas, l as getWebcamSnapshot, u as stopMediaStream, n as useAnimationFrame, e as useWebcam };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/utils/helpers/animationFrame.ts
|
|
2
|
+
var e = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame, t = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { t as cancelAnimationFrame, e as requestAnimationFrame };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=animationFrame.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animationFrame.mjs","names":[],"sources":["../../../../src/utils/helpers/animationFrame.ts"],"sourcesContent":["// ✅ important\n// Implementations for each browser need to be supported\nexport const requestAnimationFrame =\n window.requestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.msRequestAnimationFrame;\n\nexport const cancelAnimationFrame =\n window.cancelAnimationFrame ||\n window.mozCancelAnimationFrame ||\n window.webkitCancelAnimationFrame ||\n window.msCancelAnimationFrame;\n"],"mappings":";AAEA,IAAa,IACX,OAAO,yBACP,OAAO,4BACP,OAAO,+BACP,OAAO,yBAEI,IACX,OAAO,wBACP,OAAO,2BACP,OAAO,8BACP,OAAO"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { cancelAnimationFrame as e, requestAnimationFrame as t } from "../helpers/animationFrame.mjs";
|
|
2
|
+
import { useIsomorphicLayoutEffect as n } from "@siberiacancode/reactuse";
|
|
3
|
+
import { useEffect as r, useRef as i } from "react";
|
|
4
|
+
//#region src/utils/hooks/useAnimationFrame.ts
|
|
5
|
+
var a = (a, o) => {
|
|
6
|
+
let s = i(void 0), c = i(void 0), l = i(a);
|
|
7
|
+
n(() => {
|
|
8
|
+
l.current = a;
|
|
9
|
+
}, [a]);
|
|
10
|
+
let u = (e) => {
|
|
11
|
+
if (e) {
|
|
12
|
+
if (c.current = e, c.current === void 0) return;
|
|
13
|
+
l.current(e - c.current);
|
|
14
|
+
}
|
|
15
|
+
s.current = t(u);
|
|
16
|
+
}, d = () => {
|
|
17
|
+
s.current && e(s.current);
|
|
18
|
+
};
|
|
19
|
+
return r(() => {
|
|
20
|
+
if (o) {
|
|
21
|
+
s.current = t(u);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
return d(), () => d();
|
|
25
|
+
}, [o]), {
|
|
26
|
+
request: u,
|
|
27
|
+
cancel: d
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { a as useAnimationFrame };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=useAnimationFrame.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnimationFrame.mjs","names":[],"sources":["../../../../src/utils/hooks/useAnimationFrame.ts"],"sourcesContent":["import { useIsomorphicLayoutEffect } from '@siberiacancode/reactuse';\nimport { useEffect, useRef } from 'react';\n\nimport { cancelAnimationFrame, requestAnimationFrame } from '../helpers';\n\n/**\n * Helps request and cancel animation frame\n *\n * @param {Function} callback - frame request callback\n * @param {boolean} active - should animation frame be requested\n * @return {object} request/cancel animation frame handlers\n */\nexport const useAnimationFrame = (callback: (time: number) => void, active?: boolean) => {\n const animationFrameRequestRef = useRef<number>(undefined);\n const previousTimestampRef = useRef<number>(undefined);\n const savedHandlerRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n savedHandlerRef.current = callback;\n }, [callback]);\n\n const onFrameRequest = (timestamp?: DOMHighResTimeStamp) => {\n if (timestamp) {\n previousTimestampRef.current = timestamp;\n if (previousTimestampRef.current === undefined) return;\n savedHandlerRef.current(timestamp - previousTimestampRef.current);\n }\n\n animationFrameRequestRef.current = requestAnimationFrame(onFrameRequest);\n };\n\n const onFrameCancel = () => {\n if (!animationFrameRequestRef.current) return;\n cancelAnimationFrame(animationFrameRequestRef.current);\n };\n\n useEffect(() => {\n if (active) {\n animationFrameRequestRef.current = requestAnimationFrame(onFrameRequest);\n return;\n }\n\n onFrameCancel();\n return () => onFrameCancel();\n }, [active]);\n\n return {\n request: onFrameRequest,\n cancel: onFrameCancel\n };\n};\n"],"mappings":";;;;AAYA,IAAa,KAAqB,GAAkC,MAAqB;CACvF,IAAM,IAA2B,EAAe,KAAA,CAAS,GACnD,IAAuB,EAAe,KAAA,CAAS,GAC/C,IAAkB,EAAO,CAAQ;CAEvC,QAAgC;EAC9B,EAAgB,UAAU;CAC5B,GAAG,CAAC,CAAQ,CAAC;CAEb,IAAM,KAAkB,MAAoC;EAC1D,IAAI,GAAW;GAEb,IADA,EAAqB,UAAU,GAC3B,EAAqB,YAAY,KAAA,GAAW;GAChD,EAAgB,QAAQ,IAAY,EAAqB,OAAO;EAClE;EAEA,EAAyB,UAAU,EAAsB,CAAc;CACzE,GAEM,UAAsB;EACrB,EAAyB,WAC9B,EAAqB,EAAyB,OAAO;CACvD;CAYA,OAVA,QAAgB;EACd,IAAI,GAAQ;GACV,EAAyB,UAAU,EAAsB,CAAc;GACvE;EACF;EAGA,OADA,EAAc,SACD,EAAc;CAC7B,GAAG,CAAC,CAAM,CAAC,GAEJ;EACL,SAAS;EACT,QAAQ;CACV;AACF"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { useWebcam } from './components/Webcam/hooks';
|
|
2
|
+
export { Webcam } from './components/Webcam/Webcam';
|
|
3
|
+
export { useAnimationFrame } from './utils/hooks';
|
|
4
|
+
export { applyMediaStreamConstraints, canGetUserMedia, getDevices, getMediaStream, getMediaStreamConstraints, getVideoFrameCanvas, getWebcamSnapshot, stopMediaStream } from '@webcam/core';
|