@arfuhad/react-native-smart-camera 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +341 -0
- package/README.md +154 -0
- package/android/build.gradle +89 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/smartcamera/ImageLoader.kt +106 -0
- package/android/src/main/java/expo/modules/smartcamera/MLKitFaceDetector.kt +273 -0
- package/android/src/main/java/expo/modules/smartcamera/SmartCameraModule.kt +205 -0
- package/android/src/main/java/expo/modules/smartcamera/SmartCameraView.kt +153 -0
- package/android/src/main/java/expo/modules/smartcamera/WebRTCFrameBridge.kt +184 -0
- package/app.plugin.js +17 -0
- package/build/SmartCamera.d.ts +17 -0
- package/build/SmartCamera.d.ts.map +1 -0
- package/build/SmartCamera.js +270 -0
- package/build/SmartCamera.js.map +1 -0
- package/build/SmartCameraModule.d.ts +112 -0
- package/build/SmartCameraModule.d.ts.map +1 -0
- package/build/SmartCameraModule.js +121 -0
- package/build/SmartCameraModule.js.map +1 -0
- package/build/SmartCameraView.d.ts +8 -0
- package/build/SmartCameraView.d.ts.map +1 -0
- package/build/SmartCameraView.js +7 -0
- package/build/SmartCameraView.js.map +1 -0
- package/build/detection/blinkProcessor.d.ts +23 -0
- package/build/detection/blinkProcessor.d.ts.map +1 -0
- package/build/detection/blinkProcessor.js +90 -0
- package/build/detection/blinkProcessor.js.map +1 -0
- package/build/detection/faceDetector.d.ts +16 -0
- package/build/detection/faceDetector.d.ts.map +1 -0
- package/build/detection/faceDetector.js +46 -0
- package/build/detection/faceDetector.js.map +1 -0
- package/build/detection/index.d.ts +4 -0
- package/build/detection/index.d.ts.map +1 -0
- package/build/detection/index.js +4 -0
- package/build/detection/index.js.map +1 -0
- package/build/detection/staticImageDetector.d.ts +25 -0
- package/build/detection/staticImageDetector.d.ts.map +1 -0
- package/build/detection/staticImageDetector.js +48 -0
- package/build/detection/staticImageDetector.js.map +1 -0
- package/build/hooks/index.d.ts +5 -0
- package/build/hooks/index.d.ts.map +1 -0
- package/build/hooks/index.js +5 -0
- package/build/hooks/index.js.map +1 -0
- package/build/hooks/useBlinkDetection.d.ts +39 -0
- package/build/hooks/useBlinkDetection.d.ts.map +1 -0
- package/build/hooks/useBlinkDetection.js +67 -0
- package/build/hooks/useBlinkDetection.js.map +1 -0
- package/build/hooks/useFaceDetection.d.ts +46 -0
- package/build/hooks/useFaceDetection.d.ts.map +1 -0
- package/build/hooks/useFaceDetection.js +80 -0
- package/build/hooks/useFaceDetection.js.map +1 -0
- package/build/hooks/useSmartCamera.d.ts +31 -0
- package/build/hooks/useSmartCamera.d.ts.map +1 -0
- package/build/hooks/useSmartCamera.js +75 -0
- package/build/hooks/useSmartCamera.js.map +1 -0
- package/build/hooks/useSmartCameraWebRTC.d.ts +58 -0
- package/build/hooks/useSmartCameraWebRTC.d.ts.map +1 -0
- package/build/hooks/useSmartCameraWebRTC.js +160 -0
- package/build/hooks/useSmartCameraWebRTC.js.map +1 -0
- package/build/index.d.ts +14 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +20 -0
- package/build/index.js.map +1 -0
- package/build/types.d.ts +478 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/utils/index.d.ts +98 -0
- package/build/utils/index.d.ts.map +1 -0
- package/build/utils/index.js +276 -0
- package/build/utils/index.js.map +1 -0
- package/build/webrtc/WebRTCBridge.d.ts +55 -0
- package/build/webrtc/WebRTCBridge.d.ts.map +1 -0
- package/build/webrtc/WebRTCBridge.js +113 -0
- package/build/webrtc/WebRTCBridge.js.map +1 -0
- package/build/webrtc/index.d.ts +3 -0
- package/build/webrtc/index.d.ts.map +1 -0
- package/build/webrtc/index.js +2 -0
- package/build/webrtc/index.js.map +1 -0
- package/build/webrtc/types.d.ts +64 -0
- package/build/webrtc/types.d.ts.map +1 -0
- package/build/webrtc/types.js +5 -0
- package/build/webrtc/types.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/MLKitFaceDetector.swift +310 -0
- package/ios/SmartCamera.podspec +33 -0
- package/ios/SmartCameraModule.swift +225 -0
- package/ios/SmartCameraView.swift +146 -0
- package/ios/WebRTCFrameBridge.swift +150 -0
- package/package.json +91 -0
- package/plugin/build/index.d.ts +28 -0
- package/plugin/build/index.js +33 -0
- package/plugin/build/withSmartCameraAndroid.d.ts +9 -0
- package/plugin/build/withSmartCameraAndroid.js +108 -0
- package/plugin/build/withSmartCameraIOS.d.ts +11 -0
- package/plugin/build/withSmartCameraIOS.js +92 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Face, FaceDetectionOptions, UseFaceDetectionResult } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Options for useFaceDetection hook
|
|
4
|
+
*/
|
|
5
|
+
export interface UseFaceDetectionOptions extends FaceDetectionOptions {
|
|
6
|
+
/** Whether detection is enabled. Default: true */
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
/** Maximum number of faces to track. Default: 5 */
|
|
9
|
+
maxFaces?: number;
|
|
10
|
+
/** Callback when faces change */
|
|
11
|
+
onFacesChanged?: (faces: Face[]) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Hook for managing face detection state
|
|
15
|
+
*
|
|
16
|
+
* Use this hook to get face detection results outside of the SmartCamera component.
|
|
17
|
+
*
|
|
18
|
+
* @param options - Face detection options
|
|
19
|
+
* @returns Face detection state
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* function FaceTracker() {
|
|
24
|
+
* const { faces, isDetecting } = useFaceDetection({
|
|
25
|
+
* performanceMode: 'fast',
|
|
26
|
+
* classificationMode: 'all',
|
|
27
|
+
* onFacesChanged: (faces) => {
|
|
28
|
+
* console.log('Detected faces:', faces.length);
|
|
29
|
+
* },
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* return (
|
|
33
|
+
* <View>
|
|
34
|
+
* <Text>Faces detected: {faces.length}</Text>
|
|
35
|
+
* {faces.map((face, i) => (
|
|
36
|
+
* <Text key={i}>
|
|
37
|
+
* Smiling: {(face.smilingProbability ?? 0) * 100}%
|
|
38
|
+
* </Text>
|
|
39
|
+
* ))}
|
|
40
|
+
* </View>
|
|
41
|
+
* );
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function useFaceDetection(options?: UseFaceDetectionOptions): UseFaceDetectionResult;
|
|
46
|
+
//# sourceMappingURL=useFaceDetection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFaceDetection.d.ts","sourceRoot":"","sources":["../../src/hooks/useFaceDetection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,iCAAiC;IACjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,sBAAsB,CAsD9F"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for managing face detection state
|
|
4
|
+
*
|
|
5
|
+
* Use this hook to get face detection results outside of the SmartCamera component.
|
|
6
|
+
*
|
|
7
|
+
* @param options - Face detection options
|
|
8
|
+
* @returns Face detection state
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* function FaceTracker() {
|
|
13
|
+
* const { faces, isDetecting } = useFaceDetection({
|
|
14
|
+
* performanceMode: 'fast',
|
|
15
|
+
* classificationMode: 'all',
|
|
16
|
+
* onFacesChanged: (faces) => {
|
|
17
|
+
* console.log('Detected faces:', faces.length);
|
|
18
|
+
* },
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* return (
|
|
22
|
+
* <View>
|
|
23
|
+
* <Text>Faces detected: {faces.length}</Text>
|
|
24
|
+
* {faces.map((face, i) => (
|
|
25
|
+
* <Text key={i}>
|
|
26
|
+
* Smiling: {(face.smilingProbability ?? 0) * 100}%
|
|
27
|
+
* </Text>
|
|
28
|
+
* ))}
|
|
29
|
+
* </View>
|
|
30
|
+
* );
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function useFaceDetection(options = {}) {
|
|
35
|
+
const { enabled = true, maxFaces = 5, onFacesChanged } = options;
|
|
36
|
+
const [faces, setFaces] = useState([]);
|
|
37
|
+
const [isDetecting, setIsDetecting] = useState(false);
|
|
38
|
+
const facesRef = useRef([]);
|
|
39
|
+
const callbackRef = useRef(onFacesChanged);
|
|
40
|
+
// Keep callback ref updated
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
callbackRef.current = onFacesChanged;
|
|
43
|
+
}, [onFacesChanged]);
|
|
44
|
+
// Update faces (called from frame processor via native bridge)
|
|
45
|
+
const updateFaces = useCallback((newFaces) => {
|
|
46
|
+
// Limit number of faces
|
|
47
|
+
const limitedFaces = newFaces.slice(0, maxFaces);
|
|
48
|
+
// Only update if faces changed
|
|
49
|
+
const facesChanged = limitedFaces.length !== facesRef.current.length ||
|
|
50
|
+
limitedFaces.some((face, i) => face.trackingId !== facesRef.current[i]?.trackingId);
|
|
51
|
+
if (facesChanged) {
|
|
52
|
+
facesRef.current = limitedFaces;
|
|
53
|
+
setFaces(limitedFaces);
|
|
54
|
+
callbackRef.current?.(limitedFaces);
|
|
55
|
+
}
|
|
56
|
+
}, [maxFaces]);
|
|
57
|
+
// Detection state management
|
|
58
|
+
const startDetecting = useCallback(() => {
|
|
59
|
+
setIsDetecting(true);
|
|
60
|
+
}, []);
|
|
61
|
+
const stopDetecting = useCallback(() => {
|
|
62
|
+
setIsDetecting(false);
|
|
63
|
+
setFaces([]);
|
|
64
|
+
facesRef.current = [];
|
|
65
|
+
}, []);
|
|
66
|
+
// Effect to manage detection state based on enabled prop
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (enabled) {
|
|
69
|
+
startDetecting();
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
stopDetecting();
|
|
73
|
+
}
|
|
74
|
+
}, [enabled, startDetecting, stopDetecting]);
|
|
75
|
+
return {
|
|
76
|
+
faces,
|
|
77
|
+
isDetecting,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=useFaceDetection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFaceDetection.js","sourceRoot":"","sources":["../../src/hooks/useFaceDetection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAmC,EAAE;IACpE,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,QAAQ,GAAG,CAAC,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAEjE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;IAE3C,4BAA4B;IAC5B,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,OAAO,GAAG,cAAc,CAAC;IACvC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,+DAA+D;IAC/D,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,QAAgB,EAAE,EAAE;QACnD,wBAAwB;QACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEjD,+BAA+B;QAC/B,MAAM,YAAY,GAChB,YAAY,CAAC,MAAM,KAAK,QAAQ,CAAC,OAAO,CAAC,MAAM;YAC/C,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAEtF,IAAI,YAAY,EAAE,CAAC;YACjB,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC;YAChC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACvB,WAAW,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,6BAA6B;IAC7B,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,cAAc,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;QACrC,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,QAAQ,CAAC,EAAE,CAAC,CAAC;QACb,QAAQ,CAAC,OAAO,GAAG,EAAE,CAAC;IACxB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,yDAAyD;IACzD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,cAAc,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,aAAa,EAAE,CAAC;QAClB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC,CAAC;IAE7C,OAAO;QACL,KAAK;QACL,WAAW;KACZ,CAAC;AACJ,CAAC","sourcesContent":["import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { Face, FaceDetectionOptions, UseFaceDetectionResult } from '../types';\n\n/**\n * Options for useFaceDetection hook\n */\nexport interface UseFaceDetectionOptions extends FaceDetectionOptions {\n /** Whether detection is enabled. Default: true */\n enabled?: boolean;\n \n /** Maximum number of faces to track. Default: 5 */\n maxFaces?: number;\n \n /** Callback when faces change */\n onFacesChanged?: (faces: Face[]) => void;\n}\n\n/**\n * Hook for managing face detection state\n * \n * Use this hook to get face detection results outside of the SmartCamera component.\n * \n * @param options - Face detection options\n * @returns Face detection state\n * \n * @example\n * ```tsx\n * function FaceTracker() {\n * const { faces, isDetecting } = useFaceDetection({\n * performanceMode: 'fast',\n * classificationMode: 'all',\n * onFacesChanged: (faces) => {\n * console.log('Detected faces:', faces.length);\n * },\n * });\n * \n * return (\n * <View>\n * <Text>Faces detected: {faces.length}</Text>\n * {faces.map((face, i) => (\n * <Text key={i}>\n * Smiling: {(face.smilingProbability ?? 0) * 100}%\n * </Text>\n * ))}\n * </View>\n * );\n * }\n * ```\n */\nexport function useFaceDetection(options: UseFaceDetectionOptions = {}): UseFaceDetectionResult {\n const { enabled = true, maxFaces = 5, onFacesChanged } = options;\n \n const [faces, setFaces] = useState<Face[]>([]);\n const [isDetecting, setIsDetecting] = useState(false);\n const facesRef = useRef<Face[]>([]);\n const callbackRef = useRef(onFacesChanged);\n\n // Keep callback ref updated\n useEffect(() => {\n callbackRef.current = onFacesChanged;\n }, [onFacesChanged]);\n\n // Update faces (called from frame processor via native bridge)\n const updateFaces = useCallback((newFaces: Face[]) => {\n // Limit number of faces\n const limitedFaces = newFaces.slice(0, maxFaces);\n \n // Only update if faces changed\n const facesChanged = \n limitedFaces.length !== facesRef.current.length ||\n limitedFaces.some((face, i) => face.trackingId !== facesRef.current[i]?.trackingId);\n \n if (facesChanged) {\n facesRef.current = limitedFaces;\n setFaces(limitedFaces);\n callbackRef.current?.(limitedFaces);\n }\n }, [maxFaces]);\n\n // Detection state management\n const startDetecting = useCallback(() => {\n setIsDetecting(true);\n }, []);\n\n const stopDetecting = useCallback(() => {\n setIsDetecting(false);\n setFaces([]);\n facesRef.current = [];\n }, []);\n\n // Effect to manage detection state based on enabled prop\n useEffect(() => {\n if (enabled) {\n startDetecting();\n } else {\n stopDetecting();\n }\n }, [enabled, startDetecting, stopDetecting]);\n\n return {\n faces,\n isDetecting,\n };\n}\n\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { UseSmartCameraResult, CameraDevice } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for managing SmartCamera state and permissions
|
|
4
|
+
*
|
|
5
|
+
* @returns Camera state, permission handlers, and device info
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* function CameraScreen() {
|
|
10
|
+
* const {
|
|
11
|
+
* hasPermission,
|
|
12
|
+
* requestPermission,
|
|
13
|
+
* device,
|
|
14
|
+
* switchCamera,
|
|
15
|
+
* currentCamera
|
|
16
|
+
* } = useSmartCamera();
|
|
17
|
+
*
|
|
18
|
+
* if (!hasPermission) {
|
|
19
|
+
* return <Button onPress={requestPermission} title="Grant Permission" />;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* return <SmartCamera camera={currentCamera} />;
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function useSmartCamera(): UseSmartCameraResult;
|
|
27
|
+
/**
|
|
28
|
+
* Get all available camera devices
|
|
29
|
+
*/
|
|
30
|
+
export declare function getAvailableCameras(): Promise<CameraDevice[]>;
|
|
31
|
+
//# sourceMappingURL=useSmartCamera.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSmartCamera.d.ts","sourceRoot":"","sources":["../../src/hooks/useSmartCamera.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,oBAAoB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAqCrD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAWnE"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import { useCameraDevice, useCameraPermission, Camera } from 'react-native-vision-camera';
|
|
3
|
+
/**
|
|
4
|
+
* Hook for managing SmartCamera state and permissions
|
|
5
|
+
*
|
|
6
|
+
* @returns Camera state, permission handlers, and device info
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* function CameraScreen() {
|
|
11
|
+
* const {
|
|
12
|
+
* hasPermission,
|
|
13
|
+
* requestPermission,
|
|
14
|
+
* device,
|
|
15
|
+
* switchCamera,
|
|
16
|
+
* currentCamera
|
|
17
|
+
* } = useSmartCamera();
|
|
18
|
+
*
|
|
19
|
+
* if (!hasPermission) {
|
|
20
|
+
* return <Button onPress={requestPermission} title="Grant Permission" />;
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* return <SmartCamera camera={currentCamera} />;
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function useSmartCamera() {
|
|
28
|
+
const [currentCamera, setCurrentCamera] = useState('front');
|
|
29
|
+
const { hasPermission, requestPermission: requestCameraPermission } = useCameraPermission();
|
|
30
|
+
const nativeDevice = useCameraDevice(currentCamera);
|
|
31
|
+
// Map native device to our CameraDevice type
|
|
32
|
+
const device = useMemo(() => {
|
|
33
|
+
if (!nativeDevice)
|
|
34
|
+
return undefined;
|
|
35
|
+
return {
|
|
36
|
+
id: nativeDevice.id,
|
|
37
|
+
name: nativeDevice.name,
|
|
38
|
+
position: nativeDevice.position === 'front' ? 'front' : 'back',
|
|
39
|
+
hasFlash: nativeDevice.hasFlash,
|
|
40
|
+
hasTorch: nativeDevice.hasTorch,
|
|
41
|
+
supportsLowLightBoost: nativeDevice.supportsLowLightBoost,
|
|
42
|
+
};
|
|
43
|
+
}, [nativeDevice]);
|
|
44
|
+
// Request camera permission
|
|
45
|
+
const requestPermission = useCallback(async () => {
|
|
46
|
+
const result = await requestCameraPermission();
|
|
47
|
+
return result;
|
|
48
|
+
}, [requestCameraPermission]);
|
|
49
|
+
// Switch between front and back camera
|
|
50
|
+
const switchCamera = useCallback(() => {
|
|
51
|
+
setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));
|
|
52
|
+
}, []);
|
|
53
|
+
return {
|
|
54
|
+
hasPermission,
|
|
55
|
+
requestPermission,
|
|
56
|
+
device,
|
|
57
|
+
switchCamera,
|
|
58
|
+
currentCamera,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get all available camera devices
|
|
63
|
+
*/
|
|
64
|
+
export async function getAvailableCameras() {
|
|
65
|
+
const devices = await Camera.getAvailableCameraDevices();
|
|
66
|
+
return devices.map((device) => ({
|
|
67
|
+
id: device.id,
|
|
68
|
+
name: device.name,
|
|
69
|
+
position: device.position === 'front' ? 'front' : 'back',
|
|
70
|
+
hasFlash: device.hasFlash,
|
|
71
|
+
hasTorch: device.hasTorch,
|
|
72
|
+
supportsLowLightBoost: device.supportsLowLightBoost,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=useSmartCamera.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSmartCamera.js","sourceRoot":"","sources":["../../src/hooks/useSmartCamera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAG1F;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAe,OAAO,CAAC,CAAC;IAC1E,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,GAAG,mBAAmB,EAAE,CAAC;IAC5F,MAAM,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IAEpD,6CAA6C;IAC7C,MAAM,MAAM,GAA6B,OAAO,CAAC,GAAG,EAAE;QACpD,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QAEpC,OAAO;YACL,EAAE,EAAE,YAAY,CAAC,EAAE;YACnB,IAAI,EAAE,YAAY,CAAC,IAAI;YACvB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YAC9D,QAAQ,EAAE,YAAY,CAAC,QAAQ;YAC/B,QAAQ,EAAE,YAAY,CAAC,QAAQ;YAC/B,qBAAqB,EAAE,YAAY,CAAC,qBAAqB;SAC1D,CAAC;IACJ,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,4BAA4B;IAC5B,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,IAAsB,EAAE;QACjE,MAAM,MAAM,GAAG,MAAM,uBAAuB,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAE9B,uCAAuC;IACvC,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;QACpC,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,aAAa;QACb,iBAAiB;QACjB,MAAM;QACN,YAAY;QACZ,aAAa;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,yBAAyB,EAAE,CAAC;IAEzD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;QACxD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;KACpD,CAAC,CAAC,CAAC;AACN,CAAC","sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport { useCameraDevice, useCameraPermission, Camera } from 'react-native-vision-camera';\nimport type { CameraFacing, UseSmartCameraResult, CameraDevice } from '../types';\n\n/**\n * Hook for managing SmartCamera state and permissions\n * \n * @returns Camera state, permission handlers, and device info\n * \n * @example\n * ```tsx\n * function CameraScreen() {\n * const { \n * hasPermission, \n * requestPermission, \n * device, \n * switchCamera,\n * currentCamera \n * } = useSmartCamera();\n * \n * if (!hasPermission) {\n * return <Button onPress={requestPermission} title=\"Grant Permission\" />;\n * }\n * \n * return <SmartCamera camera={currentCamera} />;\n * }\n * ```\n */\nexport function useSmartCamera(): UseSmartCameraResult {\n const [currentCamera, setCurrentCamera] = useState<CameraFacing>('front');\n const { hasPermission, requestPermission: requestCameraPermission } = useCameraPermission();\n const nativeDevice = useCameraDevice(currentCamera);\n\n // Map native device to our CameraDevice type\n const device: CameraDevice | undefined = useMemo(() => {\n if (!nativeDevice) return undefined;\n\n return {\n id: nativeDevice.id,\n name: nativeDevice.name,\n position: nativeDevice.position === 'front' ? 'front' : 'back',\n hasFlash: nativeDevice.hasFlash,\n hasTorch: nativeDevice.hasTorch,\n supportsLowLightBoost: nativeDevice.supportsLowLightBoost,\n };\n }, [nativeDevice]);\n\n // Request camera permission\n const requestPermission = useCallback(async (): Promise<boolean> => {\n const result = await requestCameraPermission();\n return result;\n }, [requestCameraPermission]);\n\n // Switch between front and back camera\n const switchCamera = useCallback(() => {\n setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));\n }, []);\n\n return {\n hasPermission,\n requestPermission,\n device,\n switchCamera,\n currentCamera,\n };\n}\n\n/**\n * Get all available camera devices\n */\nexport async function getAvailableCameras(): Promise<CameraDevice[]> {\n const devices = await Camera.getAvailableCameraDevices();\n \n return devices.map((device) => ({\n id: device.id,\n name: device.name,\n position: device.position === 'front' ? 'front' : 'back',\n hasFlash: device.hasFlash,\n hasTorch: device.hasTorch,\n supportsLowLightBoost: device.supportsLowLightBoost,\n }));\n}\n\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { WebRTCConfig, UseSmartCameraWebRTCResult, CameraFacing } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Options for useSmartCameraWebRTC hook
|
|
4
|
+
*/
|
|
5
|
+
export interface UseSmartCameraWebRTCOptions extends Omit<WebRTCConfig, 'enabled'> {
|
|
6
|
+
/** Initial camera facing. Default: 'front' */
|
|
7
|
+
initialCamera?: CameraFacing;
|
|
8
|
+
/** Callback when streaming state changes */
|
|
9
|
+
onStreamingStateChange?: (isStreaming: boolean) => void;
|
|
10
|
+
/** Callback when an error occurs */
|
|
11
|
+
onError?: (error: Error) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Hook for managing WebRTC streaming with SmartCamera
|
|
15
|
+
*
|
|
16
|
+
* This hook provides control over WebRTC video streaming, allowing you to
|
|
17
|
+
* start/stop streaming and switch cameras while streaming.
|
|
18
|
+
*
|
|
19
|
+
* @param options - WebRTC configuration options
|
|
20
|
+
* @returns WebRTC streaming controls and state
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* function VideoCall() {
|
|
25
|
+
* const peerConnection = useRef(new RTCPeerConnection(config)).current;
|
|
26
|
+
*
|
|
27
|
+
* const {
|
|
28
|
+
* videoTrack,
|
|
29
|
+
* isStreaming,
|
|
30
|
+
* startStreaming,
|
|
31
|
+
* stopStreaming,
|
|
32
|
+
* switchCamera,
|
|
33
|
+
* } = useSmartCameraWebRTC({
|
|
34
|
+
* peerConnection,
|
|
35
|
+
* mode: 'call',
|
|
36
|
+
* videoConstraints: {
|
|
37
|
+
* width: 1280,
|
|
38
|
+
* height: 720,
|
|
39
|
+
* frameRate: 30,
|
|
40
|
+
* },
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* return (
|
|
44
|
+
* <View>
|
|
45
|
+
* <SmartCamera
|
|
46
|
+
* webrtc={{ enabled: isStreaming, peerConnection, mode: 'call' }}
|
|
47
|
+
* />
|
|
48
|
+
* <Button
|
|
49
|
+
* onPress={isStreaming ? stopStreaming : startStreaming}
|
|
50
|
+
* title={isStreaming ? 'End Call' : 'Start Call'}
|
|
51
|
+
* />
|
|
52
|
+
* </View>
|
|
53
|
+
* );
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function useSmartCameraWebRTC(options?: UseSmartCameraWebRTCOptions): UseSmartCameraWebRTCResult;
|
|
58
|
+
//# sourceMappingURL=useSmartCameraWebRTC.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSmartCameraWebRTC.d.ts","sourceRoot":"","sources":["../../src/hooks/useSmartCameraWebRTC.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAQvF;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC;IAChF,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,CAAC;IAE7B,4CAA4C;IAC5C,sBAAsB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IAExD,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,2BAAgC,GACxC,0BAA0B,CAiI5B"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
2
|
+
import { initializeWebRTC, startWebRTCStream, stopWebRTCStream, addWebRTCStateChangeListener, } from '../SmartCameraModule';
|
|
3
|
+
/**
|
|
4
|
+
* Hook for managing WebRTC streaming with SmartCamera
|
|
5
|
+
*
|
|
6
|
+
* This hook provides control over WebRTC video streaming, allowing you to
|
|
7
|
+
* start/stop streaming and switch cameras while streaming.
|
|
8
|
+
*
|
|
9
|
+
* @param options - WebRTC configuration options
|
|
10
|
+
* @returns WebRTC streaming controls and state
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* function VideoCall() {
|
|
15
|
+
* const peerConnection = useRef(new RTCPeerConnection(config)).current;
|
|
16
|
+
*
|
|
17
|
+
* const {
|
|
18
|
+
* videoTrack,
|
|
19
|
+
* isStreaming,
|
|
20
|
+
* startStreaming,
|
|
21
|
+
* stopStreaming,
|
|
22
|
+
* switchCamera,
|
|
23
|
+
* } = useSmartCameraWebRTC({
|
|
24
|
+
* peerConnection,
|
|
25
|
+
* mode: 'call',
|
|
26
|
+
* videoConstraints: {
|
|
27
|
+
* width: 1280,
|
|
28
|
+
* height: 720,
|
|
29
|
+
* frameRate: 30,
|
|
30
|
+
* },
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* return (
|
|
34
|
+
* <View>
|
|
35
|
+
* <SmartCamera
|
|
36
|
+
* webrtc={{ enabled: isStreaming, peerConnection, mode: 'call' }}
|
|
37
|
+
* />
|
|
38
|
+
* <Button
|
|
39
|
+
* onPress={isStreaming ? stopStreaming : startStreaming}
|
|
40
|
+
* title={isStreaming ? 'End Call' : 'Start Call'}
|
|
41
|
+
* />
|
|
42
|
+
* </View>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function useSmartCameraWebRTC(options = {}) {
|
|
48
|
+
const { peerConnection, mode = 'call', videoConstraints = { width: 1280, height: 720, frameRate: 30 }, initialCamera = 'front', onStreamingStateChange, onError, } = options;
|
|
49
|
+
const [videoTrack, setVideoTrack] = useState(null);
|
|
50
|
+
const [isStreaming, setIsStreaming] = useState(false);
|
|
51
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
52
|
+
const [currentCamera, setCurrentCamera] = useState(initialCamera);
|
|
53
|
+
const peerConnectionRef = useRef(peerConnection);
|
|
54
|
+
const callbacksRef = useRef({ onStreamingStateChange, onError });
|
|
55
|
+
const isMounted = useRef(true);
|
|
56
|
+
// Keep refs updated
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
peerConnectionRef.current = peerConnection;
|
|
59
|
+
callbacksRef.current = { onStreamingStateChange, onError };
|
|
60
|
+
}, [peerConnection, onStreamingStateChange, onError]);
|
|
61
|
+
// Track mounted state
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
isMounted.current = true;
|
|
64
|
+
return () => {
|
|
65
|
+
isMounted.current = false;
|
|
66
|
+
};
|
|
67
|
+
}, []);
|
|
68
|
+
// Subscribe to WebRTC state changes
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const subscription = addWebRTCStateChangeListener((state) => {
|
|
71
|
+
if (isMounted.current) {
|
|
72
|
+
setIsStreaming(state.isStreaming);
|
|
73
|
+
callbacksRef.current.onStreamingStateChange?.(state.isStreaming);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return () => {
|
|
77
|
+
subscription.remove();
|
|
78
|
+
};
|
|
79
|
+
}, []);
|
|
80
|
+
// Initialize WebRTC on first use
|
|
81
|
+
const ensureInitialized = useCallback(async () => {
|
|
82
|
+
if (isInitialized)
|
|
83
|
+
return;
|
|
84
|
+
try {
|
|
85
|
+
await initializeWebRTC();
|
|
86
|
+
if (isMounted.current) {
|
|
87
|
+
setIsInitialized(true);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
92
|
+
callbacksRef.current.onError?.(err);
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
95
|
+
}, [isInitialized]);
|
|
96
|
+
// Start streaming
|
|
97
|
+
const startStreaming = useCallback(async () => {
|
|
98
|
+
try {
|
|
99
|
+
// Ensure WebRTC is initialized
|
|
100
|
+
await ensureInitialized();
|
|
101
|
+
// Start the WebRTC stream with video constraints
|
|
102
|
+
await startWebRTCStream({
|
|
103
|
+
width: videoConstraints.width ?? 1280,
|
|
104
|
+
height: videoConstraints.height ?? 720,
|
|
105
|
+
frameRate: videoConstraints.frameRate ?? 30,
|
|
106
|
+
});
|
|
107
|
+
if (isMounted.current) {
|
|
108
|
+
setIsStreaming(true);
|
|
109
|
+
callbacksRef.current.onStreamingStateChange?.(true);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
114
|
+
callbacksRef.current.onError?.(err);
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
}, [videoConstraints, ensureInitialized]);
|
|
118
|
+
// Stop streaming
|
|
119
|
+
const stopStreaming = useCallback(() => {
|
|
120
|
+
try {
|
|
121
|
+
stopWebRTCStream();
|
|
122
|
+
if (isMounted.current) {
|
|
123
|
+
setVideoTrack(null);
|
|
124
|
+
setIsStreaming(false);
|
|
125
|
+
callbacksRef.current.onStreamingStateChange?.(false);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
130
|
+
callbacksRef.current.onError?.(err);
|
|
131
|
+
}
|
|
132
|
+
}, []);
|
|
133
|
+
// Switch camera while streaming
|
|
134
|
+
const switchCamera = useCallback(() => {
|
|
135
|
+
setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));
|
|
136
|
+
// The camera switch will be handled by the SmartCamera component
|
|
137
|
+
// when the camera prop changes
|
|
138
|
+
}, []);
|
|
139
|
+
// Cleanup on unmount
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
return () => {
|
|
142
|
+
if (isStreaming) {
|
|
143
|
+
try {
|
|
144
|
+
stopWebRTCStream();
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Ignore cleanup errors
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}, [isStreaming]);
|
|
152
|
+
return {
|
|
153
|
+
videoTrack,
|
|
154
|
+
isStreaming,
|
|
155
|
+
startStreaming,
|
|
156
|
+
stopStreaming,
|
|
157
|
+
switchCamera,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=useSmartCameraWebRTC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSmartCameraWebRTC.js","sourceRoot":"","sources":["../../src/hooks/useSmartCameraWebRTC.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { WebRTCConfig, UseSmartCameraWebRTCResult, CameraFacing } from '../types';\nimport {\n initializeWebRTC,\n startWebRTCStream,\n stopWebRTCStream,\n addWebRTCStateChangeListener,\n} from '../SmartCameraModule';\n\n/**\n * Options for useSmartCameraWebRTC hook\n */\nexport interface UseSmartCameraWebRTCOptions extends Omit<WebRTCConfig, 'enabled'> {\n /** Initial camera facing. Default: 'front' */\n initialCamera?: CameraFacing;\n \n /** Callback when streaming state changes */\n onStreamingStateChange?: (isStreaming: boolean) => void;\n \n /** Callback when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * Hook for managing WebRTC streaming with SmartCamera\n * \n * This hook provides control over WebRTC video streaming, allowing you to\n * start/stop streaming and switch cameras while streaming.\n * \n * @param options - WebRTC configuration options\n * @returns WebRTC streaming controls and state\n * \n * @example\n * ```tsx\n * function VideoCall() {\n * const peerConnection = useRef(new RTCPeerConnection(config)).current;\n * \n * const {\n * videoTrack,\n * isStreaming,\n * startStreaming,\n * stopStreaming,\n * switchCamera,\n * } = useSmartCameraWebRTC({\n * peerConnection,\n * mode: 'call',\n * videoConstraints: {\n * width: 1280,\n * height: 720,\n * frameRate: 30,\n * },\n * });\n * \n * return (\n * <View>\n * <SmartCamera \n * webrtc={{ enabled: isStreaming, peerConnection, mode: 'call' }}\n * />\n * <Button \n * onPress={isStreaming ? stopStreaming : startStreaming} \n * title={isStreaming ? 'End Call' : 'Start Call'} \n * />\n * </View>\n * );\n * }\n * ```\n */\nexport function useSmartCameraWebRTC(\n options: UseSmartCameraWebRTCOptions = {}\n): UseSmartCameraWebRTCResult {\n const {\n peerConnection,\n mode = 'call',\n videoConstraints = { width: 1280, height: 720, frameRate: 30 },\n initialCamera = 'front',\n onStreamingStateChange,\n onError,\n } = options;\n\n const [videoTrack, setVideoTrack] = useState<MediaStreamTrack | null>(null);\n const [isStreaming, setIsStreaming] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [currentCamera, setCurrentCamera] = useState<CameraFacing>(initialCamera);\n \n const peerConnectionRef = useRef(peerConnection);\n const callbacksRef = useRef({ onStreamingStateChange, onError });\n const isMounted = useRef(true);\n\n // Keep refs updated\n useEffect(() => {\n peerConnectionRef.current = peerConnection;\n callbacksRef.current = { onStreamingStateChange, onError };\n }, [peerConnection, onStreamingStateChange, onError]);\n\n // Track mounted state\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n // Subscribe to WebRTC state changes\n useEffect(() => {\n const subscription = addWebRTCStateChangeListener((state) => {\n if (isMounted.current) {\n setIsStreaming(state.isStreaming);\n callbacksRef.current.onStreamingStateChange?.(state.isStreaming);\n }\n });\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n // Initialize WebRTC on first use\n const ensureInitialized = useCallback(async (): Promise<void> => {\n if (isInitialized) return;\n\n try {\n await initializeWebRTC();\n if (isMounted.current) {\n setIsInitialized(true);\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n callbacksRef.current.onError?.(err);\n throw err;\n }\n }, [isInitialized]);\n\n // Start streaming\n const startStreaming = useCallback(async (): Promise<void> => {\n try {\n // Ensure WebRTC is initialized\n await ensureInitialized();\n\n // Start the WebRTC stream with video constraints\n await startWebRTCStream({\n width: videoConstraints.width ?? 1280,\n height: videoConstraints.height ?? 720,\n frameRate: videoConstraints.frameRate ?? 30,\n });\n\n if (isMounted.current) {\n setIsStreaming(true);\n callbacksRef.current.onStreamingStateChange?.(true);\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n callbacksRef.current.onError?.(err);\n throw err;\n }\n }, [videoConstraints, ensureInitialized]);\n\n // Stop streaming\n const stopStreaming = useCallback((): void => {\n try {\n stopWebRTCStream();\n if (isMounted.current) {\n setVideoTrack(null);\n setIsStreaming(false);\n callbacksRef.current.onStreamingStateChange?.(false);\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n callbacksRef.current.onError?.(err);\n }\n }, []);\n\n // Switch camera while streaming\n const switchCamera = useCallback((): void => {\n setCurrentCamera((prev) => (prev === 'front' ? 'back' : 'front'));\n // The camera switch will be handled by the SmartCamera component\n // when the camera prop changes\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (isStreaming) {\n try {\n stopWebRTCStream();\n } catch {\n // Ignore cleanup errors\n }\n }\n };\n }, [isStreaming]);\n\n return {\n videoTrack,\n isStreaming,\n startStreaming,\n stopStreaming,\n switchCamera,\n };\n}\n"]}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { SmartCamera } from './SmartCamera';
|
|
2
|
+
export { default as SmartCameraModule } from './SmartCameraModule';
|
|
3
|
+
export { detectFacesInImage, updateFaceDetectionOptions, initializeWebRTC, startWebRTCStream, stopWebRTCStream, pushWebRTCFrame, isWebRTCStreaming, addFaceDetectionListener, addBlinkDetectionListener, addErrorListener, addWebRTCStateChangeListener, Constants, } from './SmartCameraModule';
|
|
4
|
+
export type { PerformanceMode, LandmarkMode, ContourMode, ClassificationMode, CameraFacing, FaceDetectionOptions, FrameProcessorOptions, StaticImageOptions, FaceDetectionConfig, Point, Bounds, FaceLandmarks, ContourType, FaceContours, Face, BlinkEvent, WebRTCMode, VideoConstraints, WebRTCConfig, SmartCameraProps, SmartCameraErrorCode, SmartCameraError, UseSmartCameraWebRTCResult, UseFaceDetectionResult, UseBlinkDetectionResult, UseSmartCameraResult, CameraDevice, Orientation, OutputOrientation, } from './types';
|
|
5
|
+
export { useSmartCamera, getAvailableCameras } from './hooks/useSmartCamera';
|
|
6
|
+
export { useFaceDetection } from './hooks/useFaceDetection';
|
|
7
|
+
export { useBlinkDetection } from './hooks/useBlinkDetection';
|
|
8
|
+
export { useSmartCameraWebRTC } from './hooks/useSmartCameraWebRTC';
|
|
9
|
+
export { detectFaces } from './detection/faceDetector';
|
|
10
|
+
export { processBlinkFromFaces, resetBlinkStates, getEyeState } from './detection/blinkProcessor';
|
|
11
|
+
export { detectFacesInImage as detectFacesInImageAsync } from './detection/staticImageDetector';
|
|
12
|
+
export { createFpsLimiter, debounce, throttle, createObjectPool, createSmartCameraError, safeExecute, validateFaceDetectionOptions, createPerformanceMonitor, } from './utils';
|
|
13
|
+
export { WebRTCBridge, getWebRTCBridge } from './webrtc';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGnE,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,4BAA4B,EAC5B,SAAS,GACV,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EAEV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EAGnB,KAAK,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,IAAI,EAGJ,UAAU,EAGV,UAAU,EACV,gBAAgB,EAChB,YAAY,EAGZ,gBAAgB,EAGhB,oBAAoB,EACpB,gBAAgB,EAGhB,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EAGpB,YAAY,EAGZ,WAAW,EACX,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGlG,OAAO,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAGhG,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Main component
|
|
2
|
+
export { SmartCamera } from './SmartCamera';
|
|
3
|
+
export { default as SmartCameraModule } from './SmartCameraModule';
|
|
4
|
+
// Native module functions
|
|
5
|
+
export { detectFacesInImage, updateFaceDetectionOptions, initializeWebRTC, startWebRTCStream, stopWebRTCStream, pushWebRTCFrame, isWebRTCStreaming, addFaceDetectionListener, addBlinkDetectionListener, addErrorListener, addWebRTCStateChangeListener, Constants, } from './SmartCameraModule';
|
|
6
|
+
// Hooks
|
|
7
|
+
export { useSmartCamera, getAvailableCameras } from './hooks/useSmartCamera';
|
|
8
|
+
export { useFaceDetection } from './hooks/useFaceDetection';
|
|
9
|
+
export { useBlinkDetection } from './hooks/useBlinkDetection';
|
|
10
|
+
export { useSmartCameraWebRTC } from './hooks/useSmartCameraWebRTC';
|
|
11
|
+
// Frame processors
|
|
12
|
+
export { detectFaces } from './detection/faceDetector';
|
|
13
|
+
export { processBlinkFromFaces, resetBlinkStates, getEyeState } from './detection/blinkProcessor';
|
|
14
|
+
// Static image detection
|
|
15
|
+
export { detectFacesInImage as detectFacesInImageAsync } from './detection/staticImageDetector';
|
|
16
|
+
// Utilities
|
|
17
|
+
export { createFpsLimiter, debounce, throttle, createObjectPool, createSmartCameraError, safeExecute, validateFaceDetectionOptions, createPerformanceMonitor, } from './utils';
|
|
18
|
+
// WebRTC Bridge
|
|
19
|
+
export { WebRTCBridge, getWebRTCBridge } from './webrtc';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,0BAA0B;AAC1B,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,4BAA4B,EAC5B,SAAS,GACV,MAAM,qBAAqB,CAAC;AAoD7B,QAAQ;AACR,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,mBAAmB;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAElG,yBAAyB;AACzB,OAAO,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAEhG,YAAY;AACZ,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAEjB,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC","sourcesContent":["// Main component\nexport { SmartCamera } from './SmartCamera';\nexport { default as SmartCameraModule } from './SmartCameraModule';\n\n// Native module functions\nexport {\n detectFacesInImage,\n updateFaceDetectionOptions,\n initializeWebRTC,\n startWebRTCStream,\n stopWebRTCStream,\n pushWebRTCFrame,\n isWebRTCStreaming,\n addFaceDetectionListener,\n addBlinkDetectionListener,\n addErrorListener,\n addWebRTCStateChangeListener,\n Constants,\n} from './SmartCameraModule';\n\n// Types\nexport type {\n // Face Detection Options\n PerformanceMode,\n LandmarkMode,\n ContourMode,\n ClassificationMode,\n CameraFacing,\n FaceDetectionOptions,\n FrameProcessorOptions,\n StaticImageOptions,\n FaceDetectionConfig,\n\n // Face Detection Results\n Point,\n Bounds,\n FaceLandmarks,\n ContourType,\n FaceContours,\n Face,\n\n // Blink Detection\n BlinkEvent,\n\n // WebRTC\n WebRTCMode,\n VideoConstraints,\n WebRTCConfig,\n\n // Component Props\n SmartCameraProps,\n\n // Error Handling\n SmartCameraErrorCode,\n SmartCameraError,\n\n // Hook Return Types\n UseSmartCameraWebRTCResult,\n UseFaceDetectionResult,\n UseBlinkDetectionResult,\n UseSmartCameraResult,\n\n // Camera Device\n CameraDevice,\n\n // Orientation\n Orientation,\n OutputOrientation,\n} from './types';\n\n// Hooks\nexport { useSmartCamera, getAvailableCameras } from './hooks/useSmartCamera';\nexport { useFaceDetection } from './hooks/useFaceDetection';\nexport { useBlinkDetection } from './hooks/useBlinkDetection';\nexport { useSmartCameraWebRTC } from './hooks/useSmartCameraWebRTC';\n\n// Frame processors\nexport { detectFaces } from './detection/faceDetector';\nexport { processBlinkFromFaces, resetBlinkStates, getEyeState } from './detection/blinkProcessor';\n\n// Static image detection\nexport { detectFacesInImage as detectFacesInImageAsync } from './detection/staticImageDetector';\n\n// Utilities\nexport {\n createFpsLimiter,\n debounce,\n throttle,\n createObjectPool,\n createSmartCameraError,\n safeExecute,\n validateFaceDetectionOptions,\n createPerformanceMonitor,\n} from './utils';\n\n// WebRTC Bridge\nexport { WebRTCBridge, getWebRTCBridge } from './webrtc';\n"]}
|