Using a device’s camera in web apps is already possible via the MediaDevices API for quite a while now. It all starts with requesting user’s permission via a call to MediaDevices.getUserMedia()
which based on your constraints gives you access to the tracks containing the requested types of media.
But since a device may not have only one media input and/or output you probably want to select a specific device for your needs. That’s where MediaDevices.enumerateDevices()
comes into play.
The API returns a list of objects with each having four properties:
- deviceId: identifier for the device
- groupId: identifier for the group of devices which belong to the same physical device
- kind: if it’s a video input, audio input, or audio output
- label: (usually) a human-readable label describing the device
Let’s say we want to get all video inputs. The code for this would be:
const getDevices = async () => {
/* Make sure mediaDevices.getUserMedia() did run before. */
const mediaDevices = await navigator.mediaDevices.enumerateDevices();
return mediaDevices.filter( ( device ) => device.kind === 'videoinput' );
};
Code language: JavaScript (javascript)
Previously you got only two devices on iOS with this snippet, one for the front camera and one for the back camera although current iPhones have multiple camera lenses on the back available.
Now, with iOS 16.3, Apple has decided to open this up and you get access to all cameras!
This is super helpful if you want to use the camera for scanning close items like barcodes on tickets. In such cases you get far better results with the Ultra Wide lens due to the missing focus of the default back camera.
It’s demo time
Click “Start/stop camera” and give it a try! (No data is shared, it all stays on your device!)
Have you already used the MediaDevices API before? Know any other secrets you can share? I still cannot believe that there’s no identifier whether a device is a front or back camera – Looking for the string “front” in the label is not an option, I learnt this this hard way. 🤓