Camera Devices

Understanding what Camera Devices are, what capabilities they have, and how to connect them to a Camera Session

A CameraDevice is a camera lens on your phone that can be used as an input for a CameraSession. The CameraDevice type reports supported Camera features such as zoom ranges, available resolutions, supported FPS ranges, device-specific metadata and more.

In most cases, the default 'back' Camera Device is the most fitting:

const device = useCameraDevice("back")
const device = await getDefaultCameraDevice("back")

Camera Device Types

Physical Device Types

There are effectively three different physical Device Types (see DeviceType):

  • 'ultra-wide-angle': A physical Camera with an ultra-wide field of view, like a fish-eye view. Often referred to as "the 0.5x Camera".
  • 'wide-angle': A physical Camera with a wide field of view suitable for everyday mobile photography. Often referred to as "the 1x Camera", or "the default Camera".
  • 'telephoto': A physical Camera with a narrow field of view suitable for large zooms. Often referred to as "the 3x Camera" or "the 5x Camera".

Virtual Devices

Some CameraDevices consist of two or more physical devices to make up a single "virtual" device, like the triple camera - which consists of the ultra-wide-angle, the wide-angle and the telephoto Camera. Virtual CameraDevices support automatically switching over between physical devices to provide a "zoom-out" experience like in this Google Pixel Ad:

Example of swapping cameras for zoom level use-case (from Pixel 3 Ad)

Individual Capabilities (Constraints)

A CameraDevice exposes its individually supported capabilities such as Resolutions, Photo HDR, Video HDR, FPS Ranges, Video Stabilization Modes and more.

const device = ...
console.log(device.getSupportedResolutions('video'))
console.log(device.getSupportedResolutions('photo'))
console.log(device.supportedPixelFormats)
console.log(device.supportedFPSRanges)
console.log(device.supportsPhotoHDR)
console.log(device.supportsVideoStabilizationMode('cinematic'))

As mentioned in the "Constraints API", these features are individually supported, but not guaranteed to be supported when combined with other features. VisionCamera requires you to use Constraints to safely combine features, and finds a best matching Camera configuration automatically.

Tip

See "Constraints API" for more information.

Selecting a custom Camera Device

The Camera Device used for your Camera Session affects available features and resolutions, where more powerful devices tend to have a bigger starting time performance impact.

For simple Camera use-cases, it's often a good idea to just select a single physical Camera - which loads faster than a bigger virtual Camera, and supports most available resolutions.

Select a specific Camera Device by criteria

You can also select a specific Camera Device that matches your criteria (e.g. Triple-Camera):

const device = useCameraDevice("back", {
  physicalDevices: ['ultra-wide-angle', 'wide-angle', 'telephoto']
})
const devices = getAllCameraDevices()
const device = getCameraDevice(devices, "back", {
  physicalDevices: ['ultra-wide-angle', 'wide-angle', 'telephoto']
})

The Triple-Camera then lists all of its constituent physical devices;

for (const physicalDevice of device.physicalDevices) {
  console.log(physicalDevice.type)
}
// Output:
//   'wide-angle'
//   'ultra-wide-angle'
//   'triple'

Getting all Camera Devices

If you want to filter out Camera Devices yourself, you can get all available Camera devices on the system:

const devices = useCameraDevices()
let devices = getAllCameraDevices()
addOnCameraDevicesChangedListener((d) => {
  devices = d
})

External Devices

VisionCamera allows using external Cameras, as long as they implement the platform's Camera API - most USB Cameras that implement the UVC protocol do this. On iPad, Mac, and Android this often works seamlessly:

const device = useCameraDevice("external")

As an external Camera is plugged in or plugged out from the device, the useCameraDevice(...) hook automatically updates.

const devices = getAllCameraDevices()
let device = getCameraDevice(devices, "external")
addOnCameraDevicesChangedListener((d) => {
  device = getCameraDevice(d, "external")
})

As an external Camera is plugged in or plugged out from the device, the addOnCameraDevicesChangedListener(...) listener fires and you can call getCameraDevice(...) again to possibly detect new devices, or avoid using removed devices.

Using the Camera Device

To use your CameraDevice, pass it to your Camera's Configuration:

function App() {
  const device = useCameraDevice('back')

  return (
    <Camera
      style={StyleSheet.absoluteFill}
      isActive={true}
      device={device}
    />
  )
}
function App() {
  const device = useCameraDevice('back')
  const camera = useCamera({
    isActive: true,
    device: device,
  })
}
const session = await VisionCamera.createCameraSession(false)
const device = await getDefaultCameraDevice('back')
await session.configure([
  {
    input: device,
    outputs: [],
    constraints: []
  }
], {})
await session.start()