UNPKG

react-native-vision-camera

Version:

VisionCamera is the fastest and most powerful Camera for react-native.

88 lines (87 loc) 4.19 kB
import { useEffect, useMemo } from 'react'; import { getCameraDevice } from '../devices/getCameraDevice'; import { useCameraController } from './internal/useCameraController'; import { useCameraControllerConfiguration } from './internal/useCameraControllerConfiguration'; import { useCameraSession } from './internal/useCameraSession'; import { useCameraSessionIsRunning } from './internal/useCameraSessionIsRunning'; import { useListenerSubscription } from './internal/useListenerSubscription'; import { useCameraDevices } from './useCameraDevices'; import { useOrientation } from './useOrientation'; function defaultOnErrorHandler(error) { console.error(error); } /** * Use the Camera. * * This creates a {@linkcode CameraSession}, manages * the input and outputs (including orientation and * mirror modes), wraps listeners as stable React * callbacks, and returns a {@linkcode CameraController}. * * @example * ```ts * const camera = useCamera({ * isActive: true, * device: 'back', * outputs: [] * }) * ``` */ export function useCamera({ isActive, device, outputs = [], constraints, onSessionConfigSelected, mirrorMode, onConfigured, orientationSource = 'device', onStarted, onStopped, onError = defaultOnErrorHandler, onInterruptionStarted, onInterruptionEnded, onSubjectAreaChanged, enableDistortionCorrection, enableLowLightBoost, enableSmoothAutoFocus, getInitialExposureBias, getInitialZoom, }) { // 1. Create session const session = useCameraSession({ enableMultiCamSupport: false }); // 2. Update output orientations const orientationSourceOrUndefined = orientationSource === 'custom' ? undefined : orientationSource; const orientation = useOrientation(orientationSourceOrUndefined); useEffect(() => { if (orientation == null) return; for (const output of outputs) { output.outputOrientation = orientation; } }, [orientation, outputs]); // 3. Get the input - either find one via position, or use the user provided one const devices = useCameraDevices(); const input = useMemo(() => { if (typeof device === 'string') { // The user passed a `CameraPosition` (e.g. "back") - try to find a device ourselves const position = device; const foundDevice = getCameraDevice(devices, position); if (foundDevice == null) { throw new Error(`This device does not have any "${position}" Cameras!`); } return foundDevice; } else { // The user passed an actual device. return as-is. return device; } }, [device, devices]); // 4. Configure the session with the input + outputs to create a `CameraController` const controller = useCameraController(session, input, outputs, { mirrorMode: mirrorMode, onConfigured: onConfigured, getInitialExposureBias: getInitialExposureBias, getInitialZoom: getInitialZoom, constraints: constraints, onSessionConfigSelected: onSessionConfigSelected, }); // 5. Configure the Controller with some settings useCameraControllerConfiguration(controller, { enableSmoothAutoFocus: enableSmoothAutoFocus, enableDistortionCorrection: enableDistortionCorrection, enableLowLightBoost: enableLowLightBoost, }); // 6. Start (or stop) the Session if we have a Controller and `isActive` is true. const hasController = controller != null; useCameraSessionIsRunning(session, isActive && hasController); // 7. Set up listeners and delegate to JS useListenerSubscription(session, 'addOnStartedListener', onStarted); useListenerSubscription(session, 'addOnStoppedListener', onStopped); useListenerSubscription(session, 'addOnErrorListener', onError); useListenerSubscription(session, 'addOnInterruptionStartedListener', onInterruptionStarted); useListenerSubscription(session, 'addOnInterruptionEndedListener', onInterruptionEnded); useListenerSubscription(controller, 'addSubjectAreaChangedListener', onSubjectAreaChanged); // 8. Give the user the controller return controller; }