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.
Contents
Browser Support for getUserMedia
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 aLocalMediaStream
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.
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.
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 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?
Profilbook sediakan script for live strem harga Rp 500.000.00 ….
Profilbook menyediakan aneka informasi untuk anda…
Profilbook live stream …visit live stream..!!!!
profilbook…
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.
on server side u need to make sures is being served on https server. cause of the security..
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?
it needs to be on a https server.
secure.
How can i detect whether browser denyed the camera acces in getUserMedia()
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?
Unfortunately, I don’t think you can use getUserMedia without https. Sorry 🙁
Hi @Matt
Great Article, i have a question is: how to get media from scanners device?
Thanks,
Linh Tong
This is so cool! Great job! Is there a way to access the rear facing camera?!
It’s not working. Could not understand Hooking up the video stream.
What should be the src in the video element.
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… 🙁
I’d say yes it’s possible but it’s not something I’ve done.
There are a few demos of doing facial recognition. That might be a good place to start from.
http://wesbos.com/demos/html5-face-detection/
Thank you Matt!
Great tutorial. Is there any way to capture the video for a pre-determined time and upload to the server?
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?
Check out his answer on stack overflow:
http://stackoverflow.com/questions/18625007/enable-rear-camera-with-html5/19055195#19055195
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?
Hi Josef,
getUserMedia includes success and error callbacks so you could display the shaded div just before your call to getUserMedia and then remove this overlay in the success/error callbacks.
Chrome and Firefox will ask the user for permission every time the page is loaded.
Hope this helps! 🙂
Thanks @mattantwest:disqus! I solved it, and now have the overlay translucent div working nicely. I am planning to package this up as an independent widget and hopefully put it up on github, when I get a moment.
Awesome! Be sure to post the link here if you put it on github 🙂
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
Wonderful! Thanks.
Nice tutorial! Do you know why the css styles are missing when I capture an image using ctx.drawImage ?
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 ?
Good Article! Matt can I capture and store audio and video both in one media file like mp4, webm, etc…?
Hi Sanjay,
Check out this post 🙂
http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia
Hi Matt,
Thanks for reply. I tried it but there is an issue with it, If I am recording video more than 30 seconds then.webm file only plays for 30-32 seconds. This issue is same with RecordRTC plugin developed by “Muaz Khan”. Any clue to resolve this?
I haven’t used this so I’m not sure how to work around that.
If you find a solution be sure to let me know 🙂
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.
Hi Poojith,
Take a look at this post 🙂
http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia
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.
Hi Mindundi,
Sure, check out this demo: http://neave.github.io/face-detection/
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!
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);
}
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?
Chrome on Android should support getUserMedia, but Chrome on iOS doesn’t have support yet.
how to save that recorded video file into a folder
Take a look at this tutorial 🙂
http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia
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!
Awesome! Nice work Justin 🙂
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.
This is available in Chrome on Android but not on iOS yet.
I want to konw how can i get user’s front-facing camera ….thanks
it is not working from my side. can you please send the codes? thanks
is it play live stream from built in webcam from my laptop???
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?
friend ,,by running as it is code r u getting stream on browser???
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.
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!
nice one
Great post…
Website
Design Services
cool trick – i like it