/** * useWebRTCWithDetection Hook * * Combined hook that provides WebRTC video calling functionality * alongside face detection and eye tracking capabilities. * * This hook allows you to: * - Make video calls using WebRTC * - Detect faces in the local camera feed using VisionCamera * - Track eye status for blink detection */ import { useState, useCallback, useRef, useEffect } from 'react'; import { useRunOnJS } from 'react-native-worklets-core'; import type { Frame } from 'react-native-vision-camera'; import { useWebRTC } from './useWebRTC'; import { useFaceDetector } from './useFaceDetector'; import { useBlinkDetection } from './useBlinkDetection'; import type { Face, EyeStatusResult } from '../types'; import type { UseWebRTCOptions, UseWebRTCResult, UseWebRTCWithDetectionOptions, } from '../webrtc/types'; // Re-export the options type export type { UseWebRTCWithDetectionOptions } from '../webrtc/types'; /** * Result type for useWebRTCWithDetection hook */ export interface UseWebRTCWithDetectionResult extends UseWebRTCResult { // Face detection /** Currently detected faces */ faces: Face[]; /** Detect faces in a frame (for use in VisionCamera frame processor) */ detectFaces: (frame: Frame) => Face[]; // Eye tracking /** Current eye status */ eyeStatus: EyeStatusResult | null; /** Process faces for eye tracking */ processEyeStatus: (faces: Face[]) => void; /** Reset eye status */ resetEyeStatus: () => void; // Combined handler for frame processor /** Process a frame for both face detection and eye tracking */ processFrame: (frame: Frame) => void; } /** * Hook combining WebRTC video calling with face detection and eye tracking * * @param options - Configuration options * @returns Combined WebRTC, face detection, and eye tracking controls * * @example * ```tsx * import { useWebRTCWithDetection } from '@arfuhad/react-native-smart-camera'; * import { Camera, useFrameProcessor } from 'react-native-vision-camera'; * import { RTCView } from 'react-native-webrtc'; * * function VideoCallWithDetection() { * const { * // WebRTC * localStream, * remoteStream, * callState, * startLocalStream, * createPeerConnection, * // Face detection * faces, * detectFaces, * // Eye tracking * eyeStatus, * // Combined handler * processFrame, * } = useWebRTCWithDetection({ * config: { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }, * faceDetection: { enabled: true, classificationMode: 'all' }, * eyeTracking: { enabled: true, eyeClosedThreshold: 0.3 }, * }); * * // Use VisionCamera for local preview + detection * // Use RTCView for remote stream * const frameProcessor = useFrameProcessor((frame) => { * 'worklet'; * processFrame(frame); * }, [processFrame]); * * return ( * * * {remoteStream && } * Faces: {faces.length} * Left Eye: {eyeStatus?.leftEye.openProbability.toFixed(2)} * * ); * } * ``` */ export function useWebRTCWithDetection( options: UseWebRTCWithDetectionOptions = {} ): UseWebRTCWithDetectionResult { const { faceDetection = {}, eyeTracking = {}, ...webrtcOptions } = options; // WebRTC hook const webrtc = useWebRTC(webrtcOptions); // Face detection state const [faces, setFaces] = useState([]); // Face detector hook const { detectFaces } = useFaceDetector({ performanceMode: faceDetection.performanceMode || 'fast', landmarkMode: faceDetection.landmarkMode || 'none', classificationMode: faceDetection.classificationMode || 'all', // Needed for eye tracking trackingEnabled: true, }); // Blink detection hook const { eyeStatus, processEyeStatus, reset: resetEyeStatus, } = useBlinkDetection({ enabled: eyeTracking.enabled !== false, eyeClosedThreshold: eyeTracking.eyeClosedThreshold ?? 0.5, }); // Handle detected faces on JS thread const handleFaces = useRunOnJS((detectedFaces: Face[]) => { setFaces(detectedFaces); // Process for eye tracking if enabled if (eyeTracking.enabled !== false) { processEyeStatus(detectedFaces); } }, [processEyeStatus, eyeTracking.enabled]); // Combined frame processor function const processFrame = useCallback((frame: Frame) => { 'worklet'; if (faceDetection.enabled === false) { return; } const detectedFaces = detectFaces(frame); handleFaces(detectedFaces); }, [detectFaces, handleFaces, faceDetection.enabled]); return { // WebRTC ...webrtc, // Face detection faces, detectFaces, // Eye tracking eyeStatus, processEyeStatus, resetEyeStatus, // Combined handler processFrame, }; } // Types are exported from the interface definition above