getUserMedia: Accessing the Camera and Privacy UI

In 2011, one of the most discussed aspects of HTML5 was whether web applications would "kill" native apps that are written for specific devices in platform-dependent languages. Two years ago, access to a device's Global Positioning System was only possible through native code; now, it's trivially easy to access via a Web app using the W3C Geolocation API.

Opera co-chaired the Geolocation Working Group, and today we're advancing the Web further towards feature-parity with native applications. We're not there yet, but we're getting closer.

We were the first browser to give developers JavaScript access to a device's media capture facilities on Android, and then on desktop. This latest desktop build adds a privacy UI.

getUserMedia began life as the <device> element in the HTML5 specification. It was renamed, and then rehoused with the W3C WebRTC Working Group. The spec allows access to camera and microphone, but this build accesses camera alone.

Accessing the API

navigator.getUserMedia requires two arguments, and optionally a third. The first argument tells the device which media you require access to, and is passed as a JavaScript object. So, if you only require access to the microphone, the first argument would be {audio: true}; for video-chatting, you would use {audio: true, video: true}.

Which camera is used is left to the device: "User agents are encouraged to default to using the user's primary or system default camera and/or microphone (as appropriate) to generate the media stream."

Devices with more than one camera generally have a mechanism that allow the user to choose which one is used, so this gives the user control. Note also that the spec says "User agents may allow users to use any media source, including pre-recorded media files."

The second argument is the success callback - the code to be executed assuming that the user allows access and the device supports your request.

There is an optional third argument. This is the failure callback - the code to be executed if something went wrong. It's optional, but only optional in the same way as washing your hands before you eat is optional: if you don't do it, you leave yourself open to all sorts of bugs and your mum will shout at you.

Of course, it's important to do feature detection before making an API call to ensure that the browser and device are capable, but even if feature detection is passed, there is still much that can cause failure: the user could deny permission; the user (or device) could turn off the camera via a hardware switch, for example.

So here's how we recommend you use the API:

navigator.getUserMedia({audio: true, video: true}, success, error);

 function success(stream) {
  // ... use 'stream' ...
  }

  function error(){
  //display fallback content
  }

Changes from previous versions

Older Opera.Labs getUserMedia implementations used an earlier version of the specification, in which the options were passed as a string rather than a JavaScript object. This Labs build supports the older version and the new version. We plan to remove support for the older syntax.

User Experience

Allowing a website access to the camera and microphone has obvious privacy implications. The Geolocation specification requires that the user be informed which domain name is requesting access (because it may be in an iframe and therefore not corresponding with the address bar that a user can see).

The getUserMedia specification currently has nothing to say on this matter, but we are experimenting with a UI that will easily allow the user to see all permissions she has granted a particular site at once (camera, microphone, geolocation etc), as well as its security record.

Assume that you've come to a site that wants media access. You'll see a notification callout, pointing to the address bar badge next to the URL, which tells you that the site is asking for camera access and asking you to confirm or deny.

notification callout

Figure 1: Notification callout when a site requires access to your camera

Information about the site's security record is provided by Netcraft and Phishtank. As with current desktop versions of Opera, clicking on the badge provides information about a site, and choosing "details" from the dialogue allows you to report a site for phishing or fraud.

review and amend permissions

Figure 2: The site's security information. "Details" allows you to report phishing etc

New in this Labs build is a second tab, with a tickmark. This is where you can review and amend all the permissions you have granted a site.

Here's an example of a site that I've granted both camera and Geolocation access to.

multiple permissions

Figure 3: Permissions you've granted the current site, with chance to amend them

If a site iframes content from another URL which requests access, you'll also be alerted to that. Please note that we're continually trying to improve this UI. We're interested in any feedback you have about this.

Show me the demos!

So that's the theory. What can we do with this new facility? We've enjoyed copying video into <canvas>, then manipulating the pixel data with JavaScript:

Now you show us yours!

This is where you take over. We'd love to see what you make with getUserMedia. Please let us know in the comments or tweet us at @odevrel.

What's next?

Of course, Webaroids and magic moustaches are fun, but unlikely to change the face of the Web. However, getUserMedia is part of a wider spec called WebRTC 1.0 Real-time Communication Between Browsers which includes a Peer-to-Peer API. The goal is in-browser video conferencing and is an initiative begun by Google and supported by Mozilla and Opera - read more at the WebRTC blog.