import type { HybridObject } from 'react-native-nitro-modules'; import type { CameraPosition } from '../common-types/CameraPosition'; import type { ListenerSubscription } from '../common-types/ListenerSubscription'; import type { CameraDevice } from './CameraDevice.nitro'; import type { CameraExtension } from './CameraExtension.nitro'; /** * The {@linkcode CameraDeviceFactory} allows getting {@linkcode CameraDevice}s, * listening to device changes, and querying extensions or preferred Cameras. */ export interface CameraDeviceFactory extends HybridObject<{ ios: 'swift'; android: 'kotlin'; }> { /** * Get a list of all {@linkcode CameraDevice}s on this platform. * * This list may change as {@linkcode CameraDevice}s get plugged in/out (e.g. * {@linkcode CameraPosition | 'external'} Cameras via USB/UVC), devices * become available/unavailable (e.g. continuity Cameras), or Camera positions * change (e.g. on foldable phones). */ readonly cameraDevices: CameraDevice[]; /** * Get or set the user's default preferred camera device. * Setting a device here will persist the preference between apps. */ userPreferredCamera?: CameraDevice; /** * A list of all {@linkcode CameraDevice} combinations that are supported * in Multi-Cam {@linkcode CameraSession}s. * * This list always contains a subset of {@linkcode cameraDevices}, often * less. * * Each inner array contains one or more logical {@linkcode CameraDevice}s. * On iOS, a combination can contain a single virtual {@linkcode CameraDevice} * such as a Dual- or Triple-Camera, because that device is backed by multiple * physical Cameras. You can inspect those physical Cameras via * {@linkcode CameraDevice.physicalDevices | physicalDevices}, but pass the * returned {@linkcode CameraDevice}s directly to * {@linkcode CameraSession.configure | configure(...)}. * * If you need multiple independent inputs, choose a combination with at least * two {@linkcode CameraDevice}s. * * @discussion * For example, on many platforms only a {@linkcode CameraPosition | 'front'} * and a {@linkcode CameraPosition | 'back'} {@linkcode CameraDevice} are * supported to be used in a Multi-Cam {@linkcode CameraSession} - in this case, * the returned 2D Array looks something like this: * ```json * [ * [{ position: 'back', ... }, { position: 'front', ... }] * ] * ``` * Two {@linkcode CameraPosition | 'back'}-, or two {@linkcode CameraPosition | 'front'} * {@linkcode CameraDevice}s are often not supported together in a Multi-Cam * {@linkcode CameraSession}. * * When creating a Multi-Cam {@linkcode CameraSession}, you must ensure * that you are using Device combinations that are actually supported * on the platform, otherwise the session might fail to configure. * * @discussion * If the platform does not support Multi-Cam {@linkcode CameraSession}s, * an empty array (`[]`) will be returned. * * * @example * ```ts * if (VisionCamera.supportsMultiCamSessions) { * const deviceFactory = await VisionCamera.createDeviceFactory() * const deviceCombinations = deviceFactory.supportedMultiCamDeviceCombinations[0] * if (deviceCombinations != null) { * const connections = deviceCombinations.map((device) => { * const previewOutput = VisionCamera.createPreviewOutput() * return { * input: device, * outputs: [ * { output: previewOutput, mirrorMode: 'auto' } * ], * constraints: [] * } satisfies CameraSessionConnection * }) * * const session = await VisionCamera.createCameraSession(true) * const controllers = await session.configure(connections) * await session.start() * } * } * ``` * * @see {@linkcode CameraFactory.supportsMultiCamSessions} */ readonly supportedMultiCamDeviceCombinations: CameraDevice[][]; /** * Add a listener to be called whenever the * available {@linkcode cameraDevices} change, * for example when an external USB Camera * gets plugged in- or out- of the Device. */ addOnCameraDevicesChangedListener(listener: (newDevices: CameraDevice[]) => void): ListenerSubscription; /** * Get the {@linkcode CameraDevice} with the given unique * {@linkcode id}. * * If no device with the given {@linkcode id} is found, * this method returns `undefined`. */ getCameraForId(id: string): CameraDevice | undefined; /** * Gets a list of all vendor-specific {@linkcode CameraExtension}s * the given {@linkcode CameraDevice} supports. * * A {@linkcode CameraExtension} can be enabled when creating * a {@linkcode CameraSession} via {@linkcode CameraSession.configure | configure(...)}. */ getSupportedExtensions(camera: CameraDevice): Promise; /** * Get the platform's default {@linkcode CameraDevice} * at the given {@linkcode CameraPosition}. */ getDefaultCamera(position: CameraPosition): CameraDevice | undefined; }