Treehouse

Camera and Video Control with HTML5

By on  
Browser Camera

Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API, providing developers access to the user's camera.  Let me show you how to get simple camera access from within your browser!

The HTML

Please read my note about the HTML structure below:

<!--
	Ideally these elements aren't created until it's confirmed that the 
	client supports video/camera, but for the sake of illustrating the 
	elements involved, they are created with markup (not JavaScript)
-->
<video id="video" width="640" height="480" autoplay></video>
<button id="snap">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>

Each of these elements should be created once confirmation of camera support is confirmed, but for the sake of this tutorial, I wanted to show you what the elements look like with basic HTML.  Do note that the dimensions we're working with are 640x480.

The JavaScript

Since the HTML elements above are already created, the JavaScript portion will look smaller than you think:

// Put event listeners into place
window.addEventListener("DOMContentLoaded", function() {
	// Grab elements, create settings, etc.
	var canvas = document.getElementById("canvas"),
		context = canvas.getContext("2d"),
		video = document.getElementById("video"),
		videoObj = { "video": true },
		errBack = function(error) {
			console.log("Video capture error: ", error.code); 
		};

	// Put video listeners into place
	if(navigator.getUserMedia) { // Standard
		navigator.getUserMedia(videoObj, function(stream) {
			video.src = stream;
			video.play();
		}, errBack);
	} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
		navigator.webkitGetUserMedia(videoObj, function(stream){
			video.src = window.webkitURL.createObjectURL(stream);
			video.play();
		}, errBack);
	}
	else if(navigator.mozGetUserMedia) { // Firefox-prefixed
		navigator.mozGetUserMedia(videoObj, function(stream){
			video.src = window.URL.createObjectURL(stream);
			video.play();
		}, errBack);
	}
}, false);

Once it's been established that the browser supports getUserMedia, a simple method sets the video element's src to the user's live camera/webcam.  Calling the play method of the video then enacts the element's live video connection.  That's all that's required to connect your camera to the browser!

Taking a photo is only marginally more difficult.  Simply add a click listener to a generic button and and draw an image from video!

// Trigger photo take
document.getElementById("snap").addEventListener("click", function() {
	context.drawImage(video, 0, 0, 640, 480);
});

Of course you could add some sexy image filters and make a billion dollars...but I'll save that for another post.  At minimum you could convert the canvas snapshot to an image though!  I'll talk about canvas image filters in the future...

Being able to access the camera within the browser without using third party software is an incredible advancement.  Paired with canvas and a bit of JavaScript, the camera has become quickly and easily accessible.  Not only it the camera accessible, but since canvas is ultra-flexible, we'll be able to add sexy Instagram-style image filters in the future.  For now, however, simply accessing the camera in our browser moves us miles ahead.  Have fun taking images within your browser!

Post inspired by I see you getUserMedia; provided a great starting point for this post.

ydkjs-6.png

Recent Features

Incredible Demos

Discussion

  1. My friend, you are an inexhaustible source of source code, all more useful to each other! I follow you for a long time and I appreciate all the effort you put into your research and development! I say a big thank you!

    • henry

      How would I go about recording video for say about 20 seconds?

  2. Hi Daivd,

    This is really nice. we dont need to use flash anymore for this.
    Thanks for your effort.

  3. Hi Daivd, This is really nice. we dont need to use flash anymore for this.
    Thanks for your effort.

  4. Hi Daivd, This is really nice. we dont need to use flash anymore for this.
    Thanks for your effort.

  5. Olivier

    It works with Chrome Version 23.0.1271.64 as well, no need for Canary.

  6. Igor

    and Opera 12.10. Thank you, David, for this

  7. Igor

    Chrome 22.0.1229.94 m and Opera 12.10. Thank you, David, for this post.

  8. keung

    Can we add other feature liks adding some butter to apply the effects (color filter, fish-eye lens effect) to the snap photo?

  9. balclutha

    can you demo this exactly with the audio element instead of video?
    i’m trying to :
    1 – access user’s microphone
    2 – record something
    3 – upon completion of audio recording have it display (with controls) under the recording area
    4 – and here’s the hard part – record again (and again) and have them show up under each other with the ability to toggle/play/mute each track
    5 – voila! an HTML5 audio multitracker!
    6 – i understand that getting them to play in sync will require some work – but – a man can dream…!

  10. Paul Hernandez

    Hi David, I want to know if it’s possible to access an external camera – i.e a broadcast quality camera? I’m looking to maybe develop some interactive products for live events, using broadcast camera(s) with maybe HTML5 /Canvas. Would be great to get your advice on this.

    Paul.

  11. @Paul

    You should be able to access whatever camera the user has selected as the default in their operating system, be it a laptop internal camera, a FireWire or USB webcam, a digital video camera over FireWire, or a broadcast quality camera.

    Perhaps the better questions you should be asking are, “Are there limits to the supported resolution and framerate?” and “Is it possible to provide for in-browser selection of one or more of multiple available cameras?”

    As far as I can tell, 1) the limits are in the user’s hardware’s ability to process and render video at acceptable framerates and 2) it is not currently possible to provide for in-browser camera selection. So, as long as the OS recognizes your broadcast quality camera as a proper video input, you should be able to use it with this technology. My advice: try it. Get something like the camera you’ll be using, hook it up, and test it out on the demo page linked to in this article.

  12. @Paul

    I take #2 back: it looks like Chromium supports in-browser camera selection. I just tested it and it works perfectly in Chromium/Chrome as of 23.x

  13. could these stream be sent to server or saved or record on local file?

    • At the very least, you could take screenshots at intervals and send them to the server with WebSockets or basic AJAX.

  14. Dhananjay

    When i am trying to execute this code in my webpage it shows error in console i.e “Video capture error: 1″ what is this error???

    • I got the same error. Please help me

  15. igabo

    Hy! I have webcam streaming site with red5 rtmp server. It possible stream audio and wideo to rtmp with html5?

  16. Jomis

    @Dhananjay
    It means permission error. Try making sure no other app is using the camera, and that your page is being served by a server like nodejs or whatever.

  17. Wang

    Hi David.

    I do appreciate ur effort on source code and the beatiful demo!!!

    the demo can be well performed in chrome version 23. as well as the source code in WAMP server.

    i am now preparing my theis for a topic which may use ur source code. sure I will note in the theis the code is ur artwork.

    best regard
    Wang , a chinese students, one of ur beneficiary

  18. Johny Jonson

    Can we add some butter to this? I like popcorn and butter.

  19. Celu

    Hi David,

    is it possible to access my mobile phone’s camera to stream the video on the page?

  20. Hi David,

    I have a similar question like Celu: Is is now possible (e.g. in webkit browsers) to take snapshops on mobile phones (without resorting to Phonegap)?

    • I recommend that you check out the web camera API, although web RTC should also be available (in Firefox and Chrome for Android). Neither API is available on other mobile browser though.

  21. Satheesh

    Hello friend,
    I need your help as soon as possible.

    When I click the button, it should initiate an event to capture an image with preview and transfer it to the server.

  22. very lightweight and cool example !

  23. jim

    One more vote for a response to Celu! Thanks. :D

  24. Theodore

    I want to be able to take high-resolution images from the admin panel of the Magento eCommerce system. This is so I can avoid having to save pictures to disk, fathom out what I called them and then attach them to products. I think what you have here will do the job, massively streamlining the process.

    However, how do I capture megapixels instead of VGA?

    The backend form on Magento can be slow, ugly and lacking a preview, however, it will have to be functional. Can I declare the canvas object to be off-screen so that I have a simple ‘take photo’ button?

  25. thanks. good code. this run

  26. svarup desai

    good stuff code is working fine

  27. Omer Barlas

    @Theodore have you found a way to save megapixels? I need the same thing for a CRM and HR system.

  28. Omer Barlas

    I found the way for saving megapixels. You don’t need to display your canvas to the end user, just setup your camera view
    and set your canvas like . This way the canvas does not take a huge part of the screen, if you want to display the photo taken you can return the image object to another DIV after saving it through AJAX call.

    The only problem is that you have to know your camera’s capabilities, because you can’t adjust the canvas size according to the camera’s capability automagically, or I just didn’t try enough.

  29. jay

    Hi, I use js get the canvas iamge and send image to server like this:

    Your browser does not support the HTML5 canvas tag.

    navigator.webkitGetUserMedia({video:true},function(stream){
            document.getElementById("video").src = webkitURL.createObjectURL(stream);
        },
    ....
    
        var video_element = document.getElementById('video'); 
        var canvas = document.getElementById("myCanvas");
        var ctx=canvas.getContext("2d"); 
        ctx.drawImage(video_element,0, 0, 640,480, 0,0, 320,240);
    ....
    var data = imgData.substr(22); 
    $.post(qurl,{ 'dataImg' : data ,   ...
    

    But why the image’s clarity is very poor? use the native app can get picture very good…

  30. Panchotiya Vipul

    I want to get video from two camera in one computer

  31. Sara

    How to stop webcam, thank you.

  32. Ayesha

    Hi thanx for the code.But if you can please suggest how we can use it in other browsers i-e firefox,internet explorer?

    • Firefox works! IE is still a little behind but the team has started a little work on getUserMedia().

  33. I tried to capture video from webcam and upload it into server,

    below URL working with local storage. I want to capture and upload to the server. can you give me your suggestion, I am stuck with almost a week.

    Sample : http://html5-demos.appspot.com/static/getusermedia/record-user-webm.html

  34. Steph

    Hi,

    How can I bind the display with a button click please? I don’t want the display starting at page open…
    Thanks

  35. arun

    google chrome not allow to access webcam

  36. arun

    Please help me i want to develops video conference site please help me….

  37. Amy

    Hi,
    Please help me .
    How to close camera which is opened in browser? Can I use javascript or jquery ?Give your suggest and source code.
    Thanks

  38. Vishal

    Sir, i am getting error- HTTP “Content-Type” of “text/html” is not supported. Load of media resource http://localhost/project/ failed. I am using angular.js framework.

  39. I also did the same experiment few months back . Its so great to get access the user’s hardware using front end code . Here is my experiment link http://99mobileworld.com/take-your-picture-using-your-webcam-by-web-rtc . I applied a bit css to make frames around it

  40. sarahjohn

    How can i stop the camera taking feed continously using the getusermedia??

  41. rishikesh

    Why I am getting following error:
    “Video capture error: 1 ”

    Please suggest me.

  42. kumar

    it looks really good… I have a small question, will this work in IE or only for Chrome

  43. I do not understand! i want a clean code! to copy pase and undertand

  44. nisham

    how can i use getusermedia api without using canvas?

  45. Ali

    I connected two USB webcam to my local computer ,I tried to connect both of them and display the image from both camera in same time . But no luck ,

    Do you have any suggestion ?

  46. amit

    I m getting nothing on chrome and my chrome version is 29.0.1547.57. please help me

  47. Pablo Colla

    How would it be possible to send the image to the server ? After the user takes the snapshot send it to the server ?

  48. reddy

    I used the same code u referred above..page shows as blank, and it is not even showing any error message like browser supports getusermedia or not

  49. Saulius

    Do you know any solution for iOS? The demo works fine with Chrome on Android 4.2.2 but dosn’t work with either Chrome or Safari on iOS :(

  50. hi, i add the html and the javascript part into one file, and open it in the web browser but nothing happens.
    please explain how to make it work.

  51. Gustavo M. Severo

    Hi David!

    I followed your tutorial of “Camera and Video Control with html5″, but my
    test didn’t work!
    Everything works, but after to click on “Snap Photo”, nothing happens! No photo appears in the page.
    Do you have an email I can send my codes?

    Here is the link to my codes:
    https://github.com/GugaSevero/html5_media

    I’m waiting for your replay.

    Thank you so much for your attention.

  52. Naresh

    hello David
    i want to open mobile camera in to php or html page from where i can take snap and upload it in mysql DB.
    this same application is working in my laptop but when i open it in my phone its not working.
    so can you plz send me a code how to do this

  53. Cathy

    Hi David,

    This code works beautifully for me on a pc, but I want to be able to use this same kind of method on an android tablet using the back camera. How do I do this??

  54. Wafa

    Hi,
    Thanks for the code. Actually I need to connect my PC with USB hub which connected with four cameras and I want to display what the camera captured. Please help me I need it as soon if you can

  55. rodrigo7x

    Hi Dave,

    This is a great tutorial. Do you have an example on flipping the video horizontally, say onclick event? I have looked this up and all points to scale(-1, 1); but this doesn’t seem to work on when used just before the context.drawImage(videoElement, 0, 0, 640, 480); nothing happens. Any suggestions?

  56. hey david, great is there any way to make this work on firefox in any way?
    otherwise, is there a way to provide – so to say – a fallback image in case this is not working?

    thanks in advance!

  57. surendra

    HTML5 captured video is just playing for 30 seconds although it has been captured for more than 2 mins.

    Any thoughts???

    Thanks for your help in Advance.

  58. veeraselvam

    sir,
    This coding works well. but i can’t get video from mobile. please mobile script.

  59. fahmeed

    Hi, this code is working very well on form load but i need it to be done on button click event.Any suggestion?
    Thanks in advance!

  60. Weslei

    Parabéns… Excelente conteúdo.

  61. Arpan

    Hi Sir, I have captured video for more than 1 minute (without audio,because getUserMedia does not support audio with video) but when I am going to play the video it runs only for 32 seconds. Can You solve this problem.

    Thanks for your help in Advance.

  62. Hi, it is a brilliant post, thanks a lot!!!
    I’d like to make a question though…
    I tried it and works fine for me in a computer browser, but does not on ipad, phone, etc, the browser does not even show the (url wants to use your camera allow or deny),
    do I need to do that using a input with capture=camera yes or yes in these devices?

    thanks in advance and thanks for the article!!

  63. João

    Hi.

    This code is very good. I tested the code in a html site opened in a Android Cell Phone. I have one question about this, the code invokes the front camera of the cell. I needs to invoke the main camera. How can I get this? Any ideas?

    Thanks a lot!

  64. Hi,
    Excellent work! quite straightforward and clear code. I am trying to acquire images from user’s scanner. It is possible to do that starting from this code?

    thnaks in advance!

  65. Rebeca

    Good job. Would you put how to do the same, but with a mobile camera? Thanks

  66. Mubashar

    Great job. Can we use the same code in jquery mobile if yes what will be change? I am new to web development. I really need it.

  67. Reynan

    Thanks you david. But i want to ask something. I use this for accessing mobile camera. how to change the dafault camera? i need to use the main camera instead of rear camera. Thank you in advance.

  68. Duazo

    Good day Magnificent Work!! but I’m having a hard time implementing your code can anyone give me link to download please..

  69. rud

    Hi David, very nice example !!!
    One question tho, is it possible to control the camera’s flash ? like toggle on/off, or possibly the camera’s focus point ?

  70. Well this would have been so useful when I made my motion detector with getUserMedia :D http://motion-detector.nikhazy-dizajn.hu/

    This is an easy and good tutorial, I had hard time to get it work back than.

    I have no time to make it better, but it is so good to see you made article about getUserMedia. I bookmark this for the future.

  71. Reynan

    Hello David. I just want to ask how can i change dynamically the resolution of snap photo in a scenario like responsive website?

    how can i dynamically change resolution here? i already make my video and canvas responsive depending on the web browser size.

    document.getElementById("snap").addEventListener("click", function() {
    	context.drawImage(video, 0, 0, 640, 480);
    });
  72. BETEPAH

    Hellow! Is there any way to capture video and audio (audio is very interested) on devices with iOS (iPhone, iPad)?
    There are in fact no support nor GetUserMedia or flash. So…

  73. kike chan

    Hi,

    Reading mozilla docs I found a solution for firefox

    } else if(navigator.mozGetUserMedia) { // Moz-prefixed
    	navigator.mozGetUserMedia(videoObj, function(stream){
    		if (video.mozSrcObject !== undefined) {
    				video.mozSrcObject = stream;
    		} else {
    				video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
    		};
    		// video.src = window.URL.createObjectURL(stream);
    		video.play();
    	}, errBack);
    }
    
  74. Igor

    There seems to be some part missing, because the code from this page does not do anything. No errors, nothing. I tried to take the code from the demo page (that works when opened on your site) and open it standalone and it doesn’t work either. Is there a server side code or some external Javascript that supposed to initiate the video? Thanks.

  75. Just checked this in Firefox Nightly and Chrome — what browser is this not working in?

    • Igor

      It work find but only on your demo page. If I just take the code and the HTML above to a stand along HTML page – nothing works in any browser. “video.play()” never happens. That’s why I’m asking – is there any piece of code missing in your explanations above? Any external Javascript that you didn’t mention?

  76. Igor

    My bad – it does work in FF, but not in Chrome or IE.

  77. Igor

    Update: It looks like Chrome and IE need the page with this code to be loaded from a server, not an html in a file system. That’s very odd, it’s not documented anywhere.

  78. oseroke

    Hello David,
    Thanks for the article. Really simple and useful.

    Like Cathy, Joao and Reynan have asked, how can we invoke the rear camera on mobile phones for this project?

    Thank you very much.

  79. Vic

    Can’t get it to work in Firefox 33.0.1..even with your code update. Any clues?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!