advance hook: useCameraDevices
This commit is contained in:
		| @@ -57,7 +57,8 @@ npx pod-install | |||||||
|  |  | ||||||
| ```tsx | ```tsx | ||||||
| function App() { | function App() { | ||||||
|   const device = useCameraDevice('wide-angle-camera') |   const devices = useCameraDevices('wide-angle-camera') | ||||||
|  |   const device = devices.back | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <Camera |     <Camera | ||||||
|   | |||||||
| @@ -1,9 +1,19 @@ | |||||||
| import { useEffect, useState } from 'react'; | import { useEffect, useState } from 'react'; | ||||||
| import { CameraRuntimeError } from 'src/CameraError'; | import type { CameraPosition } from 'src/CameraPosition'; | ||||||
| import { sortDevices } from 'src/utils/FormatFilter'; | import { sortDevices } from 'src/utils/FormatFilter'; | ||||||
| import { Camera } from '../Camera'; | import { Camera } from '../Camera'; | ||||||
| import { CameraDevice, LogicalCameraDeviceType, parsePhysicalDeviceTypes, PhysicalCameraDeviceType } from '../CameraDevice'; | import { CameraDevice, LogicalCameraDeviceType, parsePhysicalDeviceTypes, PhysicalCameraDeviceType } from '../CameraDevice'; | ||||||
| 
 | 
 | ||||||
|  | type CameraDevices = { | ||||||
|  |   [key in CameraPosition]: CameraDevice | undefined; | ||||||
|  | }; | ||||||
|  | const DefaultCameraDevices: CameraDevices = { | ||||||
|  |   back: undefined, | ||||||
|  |   external: undefined, | ||||||
|  |   front: undefined, | ||||||
|  |   unspecified: undefined, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Gets the best available `CameraDevice`. Devices with more cameras are preferred. |  * Gets the best available `CameraDevice`. Devices with more cameras are preferred. | ||||||
|  * |  * | ||||||
| @@ -14,7 +24,7 @@ import { CameraDevice, LogicalCameraDeviceType, parsePhysicalDeviceTypes, Physic | |||||||
|  * // ...
 |  * // ...
 | ||||||
|  * return <Camera device={device} /> |  * return <Camera device={device} /> | ||||||
|  */ |  */ | ||||||
| export function useCameraDevice(): CameraDevice; | export function useCameraDevices(): CameraDevices; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Gets a `CameraDevice` for the requested device type. |  * Gets a `CameraDevice` for the requested device type. | ||||||
| @@ -26,32 +36,31 @@ export function useCameraDevice(): CameraDevice; | |||||||
|  * // ...
 |  * // ...
 | ||||||
|  * return <Camera device={device} /> |  * return <Camera device={device} /> | ||||||
|  */ |  */ | ||||||
| export function useCameraDevice(deviceType: PhysicalCameraDeviceType | LogicalCameraDeviceType): CameraDevice | undefined; | export function useCameraDevices(deviceType: PhysicalCameraDeviceType | LogicalCameraDeviceType): CameraDevices; | ||||||
| 
 | 
 | ||||||
| export function useCameraDevice(deviceType?: PhysicalCameraDeviceType | LogicalCameraDeviceType): CameraDevice | undefined { | export function useCameraDevices(deviceType?: PhysicalCameraDeviceType | LogicalCameraDeviceType): CameraDevices { | ||||||
|   const [device, setDevice] = useState<CameraDevice>(); |   const [cameraDevices, setCameraDevices] = useState<CameraDevices>(DefaultCameraDevices); | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     let isMounted = true; |     let isMounted = true; | ||||||
| 
 | 
 | ||||||
|     const loadDevice = async (): Promise<void> => { |     const loadDevice = async (): Promise<void> => { | ||||||
|       const devices = await Camera.getAvailableCameraDevices(); |       let devices = await Camera.getAvailableCameraDevices(); | ||||||
|       if (!isMounted) return; |       if (!isMounted) return; | ||||||
| 
 | 
 | ||||||
|       let bestMatch: CameraDevice | undefined; |       devices = devices.sort(sortDevices); | ||||||
|       if (deviceType == null) { |       if (deviceType != null) { | ||||||
|         // use any device
 |         devices = devices.filter((d) => { | ||||||
|         const sorted = devices.sort(sortDevices); |  | ||||||
|         bestMatch = sorted[0]; |  | ||||||
|       } else { |  | ||||||
|         // use specified device (type)
 |  | ||||||
|         bestMatch = devices.find((d) => { |  | ||||||
|           const parsedType = parsePhysicalDeviceTypes(d.devices); |           const parsedType = parsePhysicalDeviceTypes(d.devices); | ||||||
|           return parsedType === deviceType; |           return parsedType === deviceType; | ||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|       if (bestMatch == null) throw new CameraRuntimeError('device/no-device', 'No Camera device was found!'); |       setCameraDevices({ | ||||||
|       setDevice(bestMatch); |         back: devices.find((d) => d.position === 'back'), | ||||||
|  |         external: devices.find((d) => d.position === 'external'), | ||||||
|  |         front: devices.find((d) => d.position === 'front'), | ||||||
|  |         unspecified: devices.find((d) => d.position === 'unspecified'), | ||||||
|  |       }); | ||||||
|     }; |     }; | ||||||
|     loadDevice(); |     loadDevice(); | ||||||
| 
 | 
 | ||||||
| @@ -60,5 +69,5 @@ export function useCameraDevice(deviceType?: PhysicalCameraDeviceType | LogicalC | |||||||
|     }; |     }; | ||||||
|   }, [deviceType]); |   }, [deviceType]); | ||||||
| 
 | 
 | ||||||
|   return device; |   return cameraDevices; | ||||||
| } | } | ||||||
| @@ -10,6 +10,6 @@ export * from './Point'; | |||||||
| export * from './Snapshot'; | export * from './Snapshot'; | ||||||
| export * from './TemporaryFile'; | export * from './TemporaryFile'; | ||||||
| export * from './VideoFile'; | export * from './VideoFile'; | ||||||
| export * from './hooks/useCameraDevice'; | export * from './hooks/useCameraDevices'; | ||||||
| export * from './hooks/useCameraFormat'; | export * from './hooks/useCameraFormat'; | ||||||
| export * from './utils/FormatFilter'; | export * from './utils/FormatFilter'; | ||||||
|   | |||||||
| @@ -91,8 +91,8 @@ export const sortFormatsByResolution = (left: CameraDeviceFormat, right: CameraD | |||||||
|   let rightPoints = right.photoHeight * right.photoWidth; |   let rightPoints = right.photoHeight * right.photoWidth; | ||||||
|  |  | ||||||
|   if (left.videoHeight != null && left.videoWidth != null && right.videoHeight != null && right.videoWidth != null) { |   if (left.videoHeight != null && left.videoWidth != null && right.videoHeight != null && right.videoWidth != null) { | ||||||
|     leftPoints += left.videoWidth * left.videoHeight ?? 0; |     leftPoints += left.videoWidth * left.videoHeight; | ||||||
|     rightPoints += right.videoWidth * right.videoHeight ?? 0; |     rightPoints += right.videoWidth * right.videoHeight; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // "returns a negative value if left is better than one" |   // "returns a negative value if left is better than one" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user