Filtering a webcam using getUserMedia and HTML5 canvas
With the recent release of Opera 12 which has webcam support with the getUserMedia API, I decided to have a look at this API myself and see how easy it is to use. As it turns out, it’s ridicously simple.
The getUserMedia API itself is not yet complete and approved, and most of it is informing browser vendors how to implement the API and is largely irrelevant to the front-end developer.
Getting a webcam stream
There is a JavaScript API defined within the specification, but the most important question you’re probably wondering is “how do I actually ask the browser to get me the webcam stream?”. First of all it’s best to check if the browser actually supports getUserMedia and this is done my simply asking:
if (navigator.getUserMedia) {
// do stuff
}
else {
// boo
}
Once you have established that the browser does support getUserMedia you then ask it to obtain a stream from the video. The browser must ask the user to allow access to the webcam by the web page, and this is usually done via a popup box (but may of course vary across browsers when more implement the API). Once the user has given permission for their webcam to be accessed, you then do the following:
navigator.getUserMedia({video:true, audio:false}, success, error);
Where video:true indicates that we want video access and audio:false indicates that we don’t want audio (retrieving audio isn’t supported by any browser yet), and success is the function to call when a webcam stream is successfuly received, and the function error will be called when no stream is received.
The success function received an argument which points to the webcam stream, and this can now be assigned to the src attribute of an already defined HTML5 video element for display:
function success(stream) {
document.getElementById('myVideo').src = stream;
}
The webcam image will now start streaming via the video element.
There are a number of JavaScript coding examples in the specification itself which you can look at.
HTML5 canvas
Since the webcam is now being streamed through a normal video element, we can also manipulate that through HTML5‘s canvas element and API.
Chapter 9 of my book, HTML5 Multimedia Develop and Design shows you how a video can be displayed and manipulated and through a HTML5 canvas element. The book’s website has some code examples of how this can be achieved.
Webcam filters demo
Of course the webcam is now streaming through a video element so we can do the same. I have put together a small application that shows how different filters, such as greyscale, brighten and blur, can be applied to a webcam using the getUserMedia API and HTML5 canvas.
I won’t go into the code, as it’s commented well enough and you can look at it there. Some of the more advanced filters were taken from HTML5 Rocks as a lot of that stuff is simply over my head!
10 Responses
Nice article Mr Devlin
The latest gUM spec has a slightly different syntax for passing parameters into the API – it’;s now a JSON format
navigator.getUserMedia(‘video’, success, error);
is now
navigator.getUserMedia({video: true, audio: true}, success, error);
This is supported by Opera 12 desktop, Opera Mobile 12 and Chrome 20+ (rg, Canary builds)
Thanks Bruce. I did see that but for some reason didn’t register it. I shall update the article, thanks!
Nice article, and the demo is really interesting.
I think your navigator.getUserMedia(‘video’); is missing some params?
Thanks Ciaran, I have changed it based on Bruce’s comment above, is that what you were referring to?
Pingback: HTML5 多媒体的十个常见问题和解答 | 5迷3道 | HTML5和CSS3的真材实料
Pingback: [转]HTML5 多媒体的十个常见问题和解答 | 纵贯线
Pingback: HTML5音频和视频处理的普遍问题和解答
Thanks for the article! Using this I have been able to add face recognition to a webcam stream. Obviously not with any fancy frame rates though.
If you’re interested, I wrote a short post including a demo at my blog:
http://blog.rubenvandeven.com/webcam-face-detection-using-a-html5-canvas/
Nice job Ian, your example works like a charm… until I add a second camera to the machine. The script returns an error code 1. I removed the newly-added cam and it still return ec 1. I think there must be something wrong when getUserMedia reading the system cam array setting.
And I googled there is no explanation for what actually is error 1.
lithatog, since the spec is still in a state of flux, it’s no surprise that it doesn’t work. I don’t have two cameras so am unable to test it (although it works on my Android phone which has two cameras).
Error code 1 is the only error that’s returned at the moment, and it’s defined as PERMISSION_DENIED, but I’m not sure how accurate that is. This is mentioned in the spec at: NavigatorUserMediaError and NavigatorUserMediaErrorCallback.