Video Camera

Your browser may not support all of the functionality in this article.

Audio/Video capture has been the "Holy Grail" of web development for a long time. For many years weve had to rely on browser plugins (Flash or Silverlight) to get the job done. Come on!

HTML5 to the rescue. It might not be apparent, but the rise of HTML5 has brought a surge of access to device hardware. Geolocation (GPS), the Orientation API (accelerometer), WebGL (GPU), and the Web Audio API (audio hardware) are perfect examples. These features are ridiculously powerful, exposing high level JavaScript APIs that sit on top of the systems underlying hardware capabilities.

This tutorial introduces a new API, navigator.getUserMedia(), which allows web apps to access a users camera and microphone.

If youre not aware of its history, the way we arrived at the getUserMedia() API is an interesting tale.

Several variants of "Media Capture APIs" have evolved over the past few years. Many folks recognized the need to be able to access native devices on the web, but that led everyone and their mom to put together a new spec. Things got so messy that the W3C finally decided to form a working group. Their sole purpose? Make sense of the madness! The Device APIs Policy (DAP) Working Group has been tasked to consolidate + standardize the plethora of proposals.

If you wanted to let users take a snapshot of themselves with the webcam, thats possible with capture=camera:

The pace to find a suitable capture API accelerated in recent months thanks to a larger effort called WebRTC (Web Real Time Communications). The spec is overseen by the W3C WebRTC Working Group. Google, Opera, Mozilla, and a few others are currently working on bringing implementations to their browsers.

getUserMedia() is related to WebRTC because its the gateway into that set of APIs. It provides the means to access the users local camera/microphone stream.

In Chrome 21, this feature will be on by default. The API is also supported in Opera 12 and Firefox 17.

With navigator.getUserMedia(), we can finally tap into webcam and microphone input without a plugin. Camera access is now a call away, not an install away. Its baked directly into the browser. Excited yet?

Feature detecting is a simple check for the existence of navigator.getUserMedia:

If your app is running from SSL (https://), this permission will be persistent. That is, users wont have to grant/deny access every time.

For users that dont have support for getUserMedia(), one option is to fallback to an existing video file if the API isnt supported and/or the call fails for some reason:

One amazing use case for video capture is to render live input as a WebGL texture. Since I know absolutely nothing about WebGL (other than its sweet), Im going to suggest you give Jerome Etiennes tutorial and demo a look. It talks about how to use getUserMedia() and Three.js to render live video into WebGL.

One of my dreams is to build AutoTune in the browser with nothing more than open web technology! Were actually not too far from that reality.

As of Chrome 24, you can enable the "Web Audio Input" flag in about:flags to experiment with getUserMedia() + the Web Audio API for realtime effects. Integrating the two is still a work in progress (crbug.com/112404), but the current implementation works pretty well.

Piping microphone input to the Web Audio API looks like this:

In general, device access on the web has been a tough cookie to crack. Many people have tried, few have succeeded. Most of the early ideas have never taken hold outside of a proprietary environment nor have they gained widespread adoption.

The real problem is that the webs security model is very different from the native world. For example, I probably dont want every Joe Shmoe web site to have random access to my video camera. Its a tough problem to get right.

Bridging frameworks like PhoneGap have helped push the boundary, but theyre only a start and a temporary solution to an underlying problem. To make web apps competitive to their desktop counterparts, we need access to native devices.

getUserMedia() is but the first wave of access to new types of devices. I hope well continue to see more in the very near future!

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the Apache 2.0 License.