Skip to content

Camera

Module Io.Camera

You can use the camera(s) built into your device, or an external camera connected via USB. If you do have multiple cameras on your device (eg a forward and backward-facing camera), you may need to specify its name. Use Camera.dumpDevices to print out available capture devices to the console.

Camera.start

Camera.start pipes camera data to an automatically-created <VIDEO> element.

import { Camera } from 'https://unpkg.com/ixfx/dist/io.js'
try {
const result = await Camera.start();
// Yields: { videoEl:HTMLVideoElement, dispose:()=>void }
// - videoEl is the VIDEO element, created to receive video stream
// - dispose() should be called when you want to release the camera
} catch (ex) {
// Can happen if user cancels camera request, for example.
console.error(`Video could not be started`, ex);
}

When calling Camera.start(), it will use your default camera. Constraints can be used to request a particular camera or resolution.

For example by device id:

Camera.start({
deviceId: `Logitech Superduper Cam'
});

Lower resolution access is often preferred when doing image processing since more pixels means more time spent processing.

Camera.start({
// Other available option is 'user'
facingMode: `environment`,
ideal: {
width: 1024,
height: 768
}
})

Reading frames

There are two simple approaches to read frames from the camera once it is streaming to a VIDEO element. See Video for more info.

In both cases, we get frames as ImageData. Read more on how to scan pixels.

Video.frames

Using Video.frames , we get frames via a generator.

import { Camera } from 'https://unpkg.com/ixfx/dist/io.js'
import { Video } from 'https://unpkg.com/ixfx/dist/visual.js'
try {
const { videoEl, dispose } = await Camera.start();
for await (const frame of Video.frames(videoEl)) {
// Do something with frame...
}
} catch (ex) {
// Can happen if user cancels camera request, for example.
console.error(`Video could not be started`, ex);
}
// Be sure to call dispose() when you're done with the camera

By default it will read frames as quick as possible. Sometimes this might be too fast, where images are coming in more quickly than you can process them. Use the maxIntervalMs option to slow it down, eg reading a frame every 100ms:

for await (const frame of frames(videoEl, { maxIntervalMs: 100 })) {
// Do something with frame...
}

Video.capture

Alternatively, Video.capture captures to a callback.

import { Video } from 'https://unpkg.com/ixfx/dist/visual.js'
import { Camera } from 'https://unpkg.com/ixfx/dist/io.js'
try
const { videoEl, dispose } = await Camera.start();
Video.capture(videoEl, {
maxIntervalMs: 100
onFrame(imageData => {
// Do something with pixels...
});
});
} catch (ex) {
console.error(`Video could not be started`);
}
// Be sure to call dispose() when you're done with the camera