react-native-vision-camera
Version:
VisionCamera is the fastest and most powerful Camera for react-native.
88 lines (87 loc) • 4.19 kB
JavaScript
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;
}