Web Dev Drops

How to Access Device Cameras with JavaScript (Front and Rear)

avatar
Douglas Matoso
Updated at 5/30/2020
Reading time: 4 min.

Hey folks! In this post I will show you how to access the device's cameras on a web page, via JavaScript, with support for multiple browsers and without the need for external libraries.

How to Access Device Cameras with JavaScript (Front and Rear)

How to access the camera

To access the user's camera (and/or microphone) we use the JavaScript MediaStream API. This API allows to access the video and audio captured by these devices through streams.

The first step is to check if the browser supports this API:

if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
  // ok, browser supports it
}

Support is decent in modern browsers (no Internet Explorer, of course).

Capturing the video stream

To capture the video stream generated by the camera, we use the getUserMedia method of the mediaDevices object.

This method receives an object with the types of media we are requesting (video or audio) and some requirements. To start, we can just pass {video: true} to get the video from the camera.

const videoStream = await navigator.mediaDevices.getUserMedia({ video: true })

This call will ask the user for permission to access the camera. If the user denies it, it throws an exception and does not return the stream. So it must be done inside a try/catch block to handle this case.

Page requesting to use the camera

Note that it returns a Promise, so you have to use async/await or a then block.

Video requirements

We can improve the requirements of the video by passing information about the desired resolution and minimum and maximum limits:

const constraints = {
  video: {
    width: {
      min: 1280,
      ideal: 1920,
      max: 2560,
    },
    height: {
      min: 720,
      ideal: 1080,
      max: 1440,
    },
  },
}

const videoStream = await navigator.mediaDevices.getUserMedia(constraints)

That way the stream comes in the correct proportion of width and height. If it is a cell phone in portrait mode it takes care of inverting the dimensions.

Displaying the video on the page

Okay, now that we have the stream, what can we do with it?

We can display the video on the page, in a video element:

// considering there is a
// <video autoplay id="video"></video>
// tag in the page
const video = document.querySelector('#video')
const videoStream = await navigator.mediaDevices.getUserMedia(constraints)
video.srcObject = videoStream

Note the autoplay attribute in the video tag. Without it, you need to call video.play() to actually start displaying the image.

Accessing the phone's front and rear cameras

By default getUserMedia will use the system's default video recording device. In the case of a cell phone with two cameras, it uses the front camera.

To access the rear camera, we must include facingMode: "environment" in the video requirements:

const constraints = {
  video: {
    width: { ... },
    height: { ... },
    facingMode: "environment"
  },
};

The default is facingMode: "user", which is the front camera.

Be aware that, if you want to change the camera with the video already playing, you will need to stop the current stream before replacing it with the stream from the other camera:

videoStream.getTracks().forEach((track) => {
  track.stop()
})

Taking screenshots

Another cool thing you can do is capture images (screenshots) of the video.

You can draw the current video frame on a canvas, for example:

// considering there is a
// <canvas id="canvas"></canvas>
// tag in the page
const canvas = document.querySelector('#canvas')
canvas.width = video.videoWidth
canvas.height = video.videoHeight
canvas.getContext('2d').drawImage(video, 0, 0)

You can also display the canvas content in an img element.

In the example I created for this tutorial, I added a button that creates images dynamically from the canvas and adds them to the page. Something like:

const img = document.createElement('img')
img.src = canvas.toDataURL('image/png')
screenshotsContainer.prepend(img)

Conclusion

See the running example here: https://doug2k1.github.io/javascript-camera/

And the complete source code is here: https://github.com/doug2k1/javascript-camera

If you liked this post, please share it! 😉

Tags: javascript

Comments

Comments disabled