Skip to main content
Platform
Camera Kit Web

Lens and Camera Selectors

In your web application, you may want to implement a lens selector as well as a camera selector for users who have more than one camera available to them. In this example, lenses and video devices are rendered into their own select menus.

index.html
<html>
<head>
<title>Lens and Camera Selectors</title>
</head>
<body>
<div>
<select id="cameras"></select>
<select id="lenses"></select>
</div>
<canvas id="canvas"></canvas>
<script type="module" src="script.ts"></script>
</body>
</html>
script.ts
import {
bootstrapCameraKit,
CameraKitSession,
createMediaStreamSource,
Transform2D,
Lens,
} from '@snap/camera-kit';

let mediaStream: MediaStream;

async function init() {
const liveRenderTarget = document.getElementById(
'canvas'
) as HTMLCanvasElement;
const cameraKit = await bootstrapCameraKit({ apiToken: '<API_TOKEN>' });
const session = await cameraKit.createSession({ liveRenderTarget });
const { lenses } = await cameraKit.lensRepository.loadLensGroups([
'<LENS_GROUP_ID>',
]);

session.applyLens(lenses[0]);

await setCameraKitSource(session);

attachCamerasToSelect(session);
attachLensesToSelect(lenses, session);
}

async function setCameraKitSource(
session: CameraKitSession,
deviceId?: string
) {
if (mediaStream) {
session.pause();
mediaStream.getVideoTracks()[0].stop();
}

mediaStream = await navigator.mediaDevices.getUserMedia({
video: { deviceId },
});

const source = createMediaStreamSource(mediaStream);

await session.setSource(source);

source.setTransform(Transform2D.MirrorX);

session.play();
}

async function attachCamerasToSelect(session: CameraKitSession) {
const cameraSelect = document.getElementById('cameras') as HTMLSelectElement;
const devices = await navigator.mediaDevices.enumerateDevices();
const cameras = devices.filter(({ kind }) => kind === 'videoinput');

cameras.forEach((camera) => {
const option = document.createElement('option');

option.value = camera.deviceId;
option.text = camera.label;

cameraSelect.appendChild(option);
});

cameraSelect.addEventListener('change', (event) => {
const deviceId = (event.target as HTMLSelectElement).selectedOptions[0]
.value;

setCameraKitSource(session, deviceId);
});
}

async function attachLensesToSelect(lenses: Lens[], session: CameraKitSession) {
const lensSelect = document.getElementById('lenses') as HTMLSelectElement;

lenses.forEach((lens) => {
const option = document.createElement('option');

option.value = lens.id;
option.text = lens.name;

lensSelect.appendChild(option);
});

lensSelect.addEventListener('change', (event) => {
const lensId = (event.target as HTMLSelectElement).selectedOptions[0].value;
const lens = lenses.find((lens) => lens.id === lensId);

if (lens) session.applyLens(lens);
});
}

init();
Was this page helpful?
Yes
No