LearnAccessing the Device Camera with getUserMedia

Matt West
writes on April 1, 2013

One of the funnest technologies to come to web browsers in the last couple years is the ability to access the webcam and microphone without the need for a third party plugin. When you combine these native media streams with the new CSS3 filters you have a recipe for awsomeness.

In this blog post you are going to learn how to access the device camera using getUserMedia and stream this input into a <video> element. To finish up you will play around with using CSS3 filters to add cool effects to the video.

Browser Support for getUserMedia

browser-support

Before we start it’s worth taking a look at browser support. Support for getUserMedia has been around in desktop browsers for a little while now.

Google Chrome (stable) has supported getUserMedia since v24. However the API is currently still prefixed as webkitGetUserMedia.

Firefox has support for the API through mozGetUserMedia. You may need to enable media support though. To do this go to about:config and toggle the media.navigator.enabled option to true.

Opera supports the unprefixed getUserMedia function.

Unfortunately IE and Safari don’t currently support getUserMedia.

For more detailed information on browser support check out the compatibility table on caniuse.com

Setting Up The Demo

Lets dive in and create a demo so that you can see how to use getUserMedia.

First you need to create a HTML file for your markup. Create a new file called index.html and save it in a folder that is accessible from your local development server.


Note: You cannot use getUserMedia on web pages served using file:// URLs.


Copy the following code into your index.html file. This will setup a basic web page with a <video> element and a <div> that will be used for styling purposes.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>HTML5 Demo: getUserMedia (Treehouse Blog)</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="video-container">
    <video id="camera-stream" width="500" autoplay></video>
  </div>
  <script src="script.js"></script>
</body>
</html>

Pro Tip: Adding a controls attribute to the video will allow you to pause the video stream and go fullscreen.


Now create a new stylesheet called style.css and save it in the same folder as your index.html file. Copy the following CSS code into your new stylesheet.

body {
  background: #F7F7F7;
  margin: 0;
  padding: 0;
}

#video-container {
  margin: 2em auto 0;
  width: 500px;
  padding: 2em;
  background: white;
  -webkit-box-shadow: 0 1px 10px #D9D9D9;
  -moz-box-shadow: 0 1px 10px #D9D9D9;
  -ms-box-shadow: 0 1px 10px #D9D9D9;
  -o-box-shadow: 0 1px 10px #D9D9D9;
  box-shadow: 0 1px 10px #D9D9D9;
}

Finally you need to setup a JavaScript file that will contain the code used to access the camera. Name this file script.js and save it in the same folder as your other assets. The code below will alias the vendor prefixed versions of getUserMedia so that you only need to call navigator.getUserMedia once rather than having to call of the vendor prefixed versions seperately in order to get your demo working across browsers.

window.onload = function() {

  // Normalize the various vendor prefixed versions of getUserMedia.
  navigator.getUserMedia = (navigator.getUserMedia ||
                            navigator.webkitGetUserMedia ||
                            navigator.mozGetUserMedia || 
                            navigator.msGetUserMedia);

}

Accessing The Camera

Now that you have all of your assets setup it’s time to take a look at getUserMedia in more detail.

The getUserMedia function takes three parameters:

  • constraints – This should be an object that specifies which media streams you would like to access. For example, to get both video and audio you would use: { video: true, audio: true }
  • successCallback – A function that will be called if the media stream is successfully loaded. The function will be passed a LocalMediaStream object.
  • errorCallback (optional) – A function that will be called if the media stream cannot be loaded.

Copy the following code into your script.js file, just inside the last curly brace.

// Check that the browser supports getUserMedia.
// If it doesn't show an alert, otherwise continue.
if (navigator.getUserMedia) {
  // Request the camera.
  navigator.getUserMedia(
    // Constraints
    {
      video: true
    },

    // Success Callback
    function(localMediaStream) {

    },

    // Error Callback
    function(err) {
      // Log the error to the console.
      console.log('The following error occurred when trying to use getUserMedia: ' + err);
    }
  );

} else {
  alert('Sorry, your browser does not support getUserMedia');
}

This code first does a check to see if the getUserMedia function is available in the browser. If it’s not it will show an alert to the user.

Once it has been established that the browser supports getUserMedia we issue the function call, passing in a constraints object that specifies we want a video stream; a callback function; and an error handler that will log any errors to the console.

getUserMedia Permissions Dialog

getUserMedia Permissions Dialog

When the function is called the user will be presented with a permissions dialog (like the one in the image above) giving them the ability to allow or deny access to the camera. This is a very important privacy feature which stops websites from being able to spy on users without their knowledge.

Hooking Up The Video Stream

The final thing to do in order to get your video stream working is to hook up the LocalMediaStream object to the <video> element in your HTML markup.


Note: The LocalMediaStream object is passed into the success callback through the  localMediaStream parameter you specified in the previous section.


Add the following code to the success callback in your getUserMedia call.

// Get a reference to the video element on the page.
var vid = document.getElementById('camera-stream');

// Create an object URL for the video stream and use this 
// to set the video source.
vid.src = window.URL.createObjectURL(localMediaStream);

Here you first get a reference to the <video> element on your web page. You then generate an object URL for the LocalMediaStream provided by getUserMedia and use this URL as the src for the video. You can use an object URL just like you would any other URL.

Now if you load up your demo page and accept the permissions dialog you should see the video feed from your camera being displayed on the page, as shown in the figure below.

getusermedia-video

Congratulations! You now know how to access the webcam without using any third-party plugins. It’s really not as hard as you might have thought.

You could stop here, but if you’re feeling a little adventurous, continue on to see how you can use CSS3 filters to add effects to the video stream.

Adding Effects with CSS3 Filters

CSS3 Filter Effects

CSS3 Filter Effects

CSS3 Filters allow you to easily add effects like grayscale, blur and sepia to your video stream. This works by using the -webkit-filter CSS rule directly on the <video> element on your web page. It’s super easy so lets give it a go!

Add the following CSS code to your style.css file. This will add a sepia effect to the video stream.

#camera-stream {
  -webkit-filter: sepia(1);
}

Now if you reload the page you should the sepia effect on the video. Pretty nifty!

Here are some other CSS3 filters for you to play around with.

-webkit-filter: blur(3px);
-webkit-filter: grayscale(1);
-webkit-filter: sepia(1);
-webkit-filter: brightness(2.5);
-webkit-filter: contrast(5);
-webkit-filter: hue-rotate(125deg);
-webkit-filter: invert(1);
-webkit-filter: saturate(3);
-webkit-filter: opacity(0.3);

Summary

I hope you’ve had as much fun playing around with getUserMedia as I did when I was writing this article!

Being able to access device hardware like the webcam and microphone without the need for third-party plugins is a big step forward for the web. There are already a number of web applications that are taking advantage of this emerging technology and I’m excited to see what developers are going to do with it in the future.

How do you plan to use getUserMedia in your projects?

58 Responses to “Accessing the Device Camera with getUserMedia”

  1. Profilbook sediakan script for live strem harga Rp 500.000.00 ….

  2. Profilbook menyediakan aneka informasi untuk anda…

  3. Profilbook live stream …visit live stream..!!!!

  4. Hi Matt West,

    I developed my VMS application which has Photo Capturing functionality & unit tested on Google Chrome (my favorite browser). Now during testing phase, I recognized that it will not work on Internet Explorer 11. I am tired up looking for solution so that it will work perfectly on IE also. I don’t want to look up for whole new solution for this. Can you help me, how to figure out this?

    Thanks in Advance.

  5. Hi Matt,

    This article is really useful. This code is only working on localhost. On client system, it is loading page but not showing camera streaming. How can I use it on client system which have camera?

  6. How can i detect whether browser denyed the camera acces in getUserMedia()

  7. Melanie Banks on April 16, 2017 at 7:56 am said:

    At the beginning you said we can’t use this code with web pages served using file:// URLs. So if we have a file:// URL, how do we go around this?

  8. linh tong on May 31, 2016 at 11:58 pm said:

    Hi @Matt

    Great Article, i have a question is: how to get media from scanners device?

    Thanks,
    Linh Tong

  9. Brandon L on January 31, 2016 at 10:35 am said:

    This is so cool! Great job! Is there a way to access the rear facing camera?!

  10. It’s not working. Could not understand Hooking up the video stream.
    What should be the src in the video element.

  11. Hi @Matt,

    do you know is there a way for receiving video to be analyzed and converted into a mathematical representation of movements into points for example.. ?

    This would be like wireframe the person that camera capture and then save the movements in points straam… 🙁

  12. Adam Hunter on September 12, 2013 at 3:25 am said:

    Great tutorial. Is there any way to capture the video for a pre-determined time and upload to the server?

  13. Hey MAtt, this is an awesome post..thanks a lot for this help..
    now i am writing a streaming application on a mobile device but using the javascript libraries.
    i see here that you are accessing the front camera.
    i wanted to access the back camera..
    how can i achieve that?any help or pointers regarding the same?

  14. Hello Matt, great article, thanks! I have a question regarding CSS and alerting the user to the allow button. Is there a way to detect that the chrome prompt has been activated and then cover the screen with a dimmed out DIV that has one arrow pointing to the allow button. I have on many occasions had human error not understand where the allow button is.. this is really a usability query. Any ideas on how to achieve this?

  15. Hey Matt,

    I am very new to HTML5 and I have to built something similar for a client but for some reason I am not getting this right. can you help me with this? http://rbbiapps.com/test/camera/index2.html.. The idea would is to upload the pic/video to a server owned by the client. Is this possible?

    Thank you

  16. Brabbit on August 21, 2013 at 8:21 am said:

    Wonderful! Thanks.

  17. Nice tutorial! Do you know why the css styles are missing when I capture an image using ctx.drawImage ?

  18. This is fantastic! Thanks so much for posting this. Does this also work with just photos? I need to be able to take a photo with a device camera within a web based app I am building. Would you just reference ?

  19. Sanjay Rathod on July 29, 2013 at 9:24 am said:

    Good Article! Matt can I capture and store audio and video both in one media file like mp4, webm, etc…?

  20. Poojith Jain on July 27, 2013 at 1:28 pm said:

    Hi Matt, as a newbie to HTML5 and Javascript, I could follow your post easily as it’s extremely apprehensible. I’m glad to get the webcam feed along with the audio. But, I’ve got a query- how do I record and play the video (which can possibly be used later)? As of now, it’s just taking the feed from the webcam. Please help.
    Thanks.

  21. Mindundi on July 23, 2013 at 3:57 pm said:

    Nice article!
    Do you think it would be possible to process the captured media for face detection and set up some kind of interaction based on the head tilt? That processing, could it be done in JS or it would need to be on server side?
    Thank you veru much.

  22. Amnon Ribak on July 16, 2013 at 6:21 am said:

    I must be missing something.. after spending long time to get a browser that supports getUserMedia, i get the page appearing as expected, with an empty box for video. the request to authorize video capture does not show.

    Can someone help here?

    • Hey (realize this thread is really old) but I’m having the same problem you had, the page loads with the box and everything but nothing else happens, browser doesn’t ask for permission to use camera or anything. I’ve tested it on browsers that don’t support it and I get the alert(‘not supported’) message so I’m not sure whats going wrong.

      Were you ever able to fix it?
      Thanks!

      • Cole Jackowski on March 23, 2016 at 6:55 am said:

        Hey Shane, there’s a chance you might be using a browser that gives a PermissionDeniedError if your site’s not using HTTPS. If you’re using a mobile browser and can’t (easily) see the console output, try enumerating the error object into an alert message like so:

        // Error Callback
        function(err) {
        // Log the error to the console.
        var message = ”;
        for (key in err) {
        message += key + ‘: ‘ + err[key] + ” \n”;
        }
        alert(message);
        }

  23. Ricardo Aranibar Leon on July 15, 2013 at 6:26 pm said:

    hi Matt, I probe in tablet and I have this message: getUserMedia() not support in your browser. I installed in my tablet google chrome how I can resolve this problem for tablet?

  24. manohar on July 7, 2013 at 12:35 am said:

    how to save that recorded video file into a folder

  25. Matt, really informative article. Thanks for putting this together! I threw the demo code into codepen.io to see it in action: http://codepen.io/justinklemm/pen/cDrFo . It works perfectly. Cheers!

  26. Elvin Turner on June 4, 2013 at 5:23 am said:

    Matt, would this work on ANY mobile device that runs Chrome (for example)? I run a site that currently uses Flash to capture video and audio from users but need to make the jump something that tablet users can use. The advice I’ve had so far is to develop an app as HTML5 is too wobbly when it comes to camera/mic access but I’d be interested in your view. Thanks.

  27. I want to konw how can i get user’s front-facing camera ….thanks

  28. tonicam on May 21, 2013 at 11:08 pm said:

    it is not working from my side. can you please send the codes? thanks

  29. is it play live stream from built in webcam from my laptop???

  30. Hi, this article is very nice, i checked out this example, it works, but it shows my video stream mirrored horizontal, how can i fix it?

  31. Dinesh on April 5, 2013 at 2:49 am said:

    Hi Matt! Amazing stuff! Really amazing! I have been a big fan of HTML5. However, can you just give me starting point on how to proceed if I want to upload this video on server in real time?

    • My initial thought would be to use websockets to create a bi-directional connection between the browser and the server and then stream camera input through this connection.
      You might also want to look into WebRTC.

  32. Nice! That is really cool! I don’t have any use for this other than to play with it and make something for fun. It’s good to know though!

  33. Vieenay on April 2, 2013 at 8:27 am said:

    nice one

  34. Maarten Gubbens on April 2, 2013 at 5:13 am said:

    Great post…
    Website
    Design Services

Leave a Reply

You must be logged in to post a comment.

Want to learn more about Javascript?

Learn how to use JavaScript to add interactivity to websites.

Learn more