2021-02-20 09:05:02 -07:00
|
|
|
import { useEffect, useState } from 'react';
|
2021-02-20 15:20:28 -07:00
|
|
|
import { CameraRuntimeError } from 'src/CameraError';
|
|
|
|
import { sortDevices } from 'src/utils/FormatFilter';
|
2021-02-20 09:05:02 -07:00
|
|
|
import { Camera } from '../Camera';
|
|
|
|
import { CameraDevice, LogicalCameraDeviceType, parsePhysicalDeviceTypes, PhysicalCameraDeviceType } from '../CameraDevice';
|
|
|
|
|
2021-02-20 15:20:28 -07:00
|
|
|
/**
|
|
|
|
* Gets the best available `CameraDevice`. Devices with more cameras are preferred.
|
|
|
|
*
|
2021-02-20 15:23:38 -07:00
|
|
|
* @returns The best matching `CameraDevice`.
|
2021-02-20 15:20:28 -07:00
|
|
|
* @throws `CameraRuntimeError` if no device was found.
|
|
|
|
* @example
|
2021-02-20 15:23:38 -07:00
|
|
|
* const device = useCameraDevice()
|
2021-02-20 15:20:28 -07:00
|
|
|
* // ...
|
|
|
|
* return <Camera device={device} />
|
|
|
|
*/
|
|
|
|
export function useCameraDevice(): CameraDevice;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a `CameraDevice` for the requested device type.
|
|
|
|
*
|
2021-02-20 15:23:38 -07:00
|
|
|
* @returns A `CameraDevice` for the requested device type.
|
|
|
|
* @throws `CameraRuntimeError` if no device was found.
|
2021-02-20 15:20:28 -07:00
|
|
|
* @example
|
|
|
|
* const device = useCameraDevice('wide-angle-camera')
|
|
|
|
* // ...
|
|
|
|
* return <Camera device={device} />
|
|
|
|
*/
|
|
|
|
export function useCameraDevice(deviceType: PhysicalCameraDeviceType | LogicalCameraDeviceType): CameraDevice | undefined;
|
|
|
|
|
|
|
|
export function useCameraDevice(deviceType?: PhysicalCameraDeviceType | LogicalCameraDeviceType): CameraDevice | undefined {
|
2021-02-20 09:05:02 -07:00
|
|
|
const [device, setDevice] = useState<CameraDevice>();
|
|
|
|
|
|
|
|
useEffect(() => {
|
2021-02-20 15:20:28 -07:00
|
|
|
let isMounted = true;
|
|
|
|
|
2021-02-20 09:05:02 -07:00
|
|
|
const loadDevice = async (): Promise<void> => {
|
|
|
|
const devices = await Camera.getAvailableCameraDevices();
|
2021-02-20 15:20:28 -07:00
|
|
|
if (!isMounted) return;
|
|
|
|
|
2021-02-20 15:23:38 -07:00
|
|
|
let bestMatch: CameraDevice | undefined;
|
2021-02-20 15:20:28 -07:00
|
|
|
if (deviceType == null) {
|
|
|
|
// use any device
|
|
|
|
const sorted = devices.sort(sortDevices);
|
2021-02-20 15:23:38 -07:00
|
|
|
bestMatch = sorted[0];
|
2021-02-20 15:20:28 -07:00
|
|
|
} else {
|
|
|
|
// use specified device (type)
|
2021-02-20 15:23:38 -07:00
|
|
|
bestMatch = devices.find((d) => {
|
2021-02-20 15:20:28 -07:00
|
|
|
const parsedType = parsePhysicalDeviceTypes(d.devices);
|
|
|
|
return parsedType === deviceType;
|
|
|
|
});
|
|
|
|
}
|
2021-02-20 15:23:38 -07:00
|
|
|
if (bestMatch == null) throw new CameraRuntimeError('device/no-device', 'No Camera device was found!');
|
|
|
|
setDevice(bestMatch);
|
2021-02-20 09:05:02 -07:00
|
|
|
};
|
|
|
|
loadDevice();
|
2021-02-20 15:20:28 -07:00
|
|
|
|
|
|
|
return () => {
|
|
|
|
isMounted = false;
|
|
|
|
};
|
2021-02-20 09:05:02 -07:00
|
|
|
}, [deviceType]);
|
|
|
|
|
|
|
|
return device;
|
2021-02-20 15:20:28 -07:00
|
|
|
}
|