Camera and Video Control with HTML5
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);
}
}, 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.
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!
Hi Daivd,
This is really nice. we dont need to use flash anymore for this.
Thanks for your effort.
Hi Daivd, This is really nice. we dont need to use flash anymore for this.
Thanks for your effort.
Hi Daivd, This is really nice. we dont need to use flash anymore for this.
Thanks for your effort.
It works with Chrome Version 23.0.1271.64 as well, no need for Canary.
and Opera 12.10. Thank you, David, for this
Chrome 22.0.1229.94 m and Opera 12.10. Thank you, David, for this post.
Can we add other feature liks adding some butter to apply the effects (color filter, fish-eye lens effect) to the snap photo?
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…!
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.
@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.
@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
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.
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???
Hy! I have webcam streaming site with red5 rtmp server. It possible stream audio and wideo to rtmp with html5?
@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.
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
Can we add some butter to this? I like popcorn and butter.
Hi David,
is it possible to access my mobile phone’s camera to stream the video on the page?
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)?
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.
very lightweight and cool example !
One more vote for a response to Celu! Thanks. :D
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?
thanks. good code. this run
good stuff code is working fine
@Theodore have you found a way to save megapixels? I need the same thing for a CRM and HR system.
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.
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…
I want to get video from two camera in one computer
How to stop webcam, thank you.
Hi thanx for the code.But if you can please suggest how we can use it in other browsers i-e firefox,internet explorer?
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