Stream Your Webcam to a Browser in JavaScript

Colin Ihrig
Share

Opera Software recently released version 12 of its flagship web browser. With its latest release, Opera became the first of the major browsers to begin supporting the W3C’s Multimedia Stream API. The Stream API, also referred to as the getUserMedia API, allows the user’s camera and microphone inputs to be streamed to a browser window. Once passed to the browser, the stream is typically used as the “src” attribute of a <video> element. Because the Stream API is still a widely unsupported draft, it is likely to change over time. This post covers the basics of the Stream API. As the draft becomes more stable and widely supported, this post will be expanded upon.

Detecting Support

Currently, Opera is the only browser to support the Stream API. Therefore, it is absolutely necessary to detect whether or not the API is supported before trying to use it. The following function detects stream support by checking for the existence of the navigator object’s getUserMedia() method.

function isStreamSupported() {
  if (navigator.getUserMedia)
    return true;
  else
    return false;
}

The getUserMedia() Method

The Stream API is accessed via the navigator.getUserMedia() method. However, before any multimedia streams can be accessed, the user must grant explicit permission to the browser. When getUserMedia() is called, Opera uses the following dialog box to receive the user’s consent.

Opera Requesting Access to the User's Camera

The syntax for getUserMedia() is shown below. The method takes two mandatory arguments, and an optional third argument. The first argument, “constraints”, is an object that specifies which media streams (ie video and/or audio) are requested by the browser. The second argument, “successCallback”, is a callback function which is executed if getUserMedia() is successful. The resulting media stream object is passed to “successCallback” as its only argument. The optional third argument, “errorCallback”, is a callback function that executes if getUserMedia() fails. For example, a failure occurs if the user does not agree to let the browser access the multimedia streams.

navigator.getUserMedia( constraints, successCallback[, errorCallback] )

Streaming to a <video> Element

The following example shows how getUserMedia() can be used to send a camera stream directly to an HTML <video> element. The example provides play, pause, and stop buttons for controlling the multimedia streams. Note that the “constraints” variable causes the browser to request both audio and video streams.  If you are using Opera, the example is also live online here.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>getUserMedia Example</title>
  <meta charset="UTF-8"/>
  <script>
    window.addEventListener("load", function() {
      var camera = document.getElementById("camera");
      var play = document.getElementById("play");
      var pause = document.getElementById("pause");
      var stop = document.getElementById("stop");
      var constraints = {audio:true, video:true};

      function success(stream) {
        camera.src = stream;
        camera.play();
        disableButtons(true, false, false);
      }

      function failure(error) {
        alert(JSON.stringify(error));
      }

      function disableButtons(disPlay, disPause, disStop) {
        play.disabled = disPlay;
        pause.disabled = disPause;
        stop.disabled = disStop;
      }

      disableButtons(true, true, true);

      if (navigator.getUserMedia)
        navigator.getUserMedia(constraints, success, failure);
      else
        alert("Your browser does not support getUserMedia()");

      play.addEventListener("click", function() {
        disableButtons(true, false, false);
        camera.play();
      }, false);

      pause.addEventListener("click", function() {
        disableButtons(false, true, false);
        camera.pause();
      }, false);

      stop.addEventListener("click", function() {
        disableButtons(true, true, true);
        camera.pause();
        camera.src = "";
      }, false);
    }, false);
  </script>
</head>
<body>
  <button id="play">Play</button>
  <button id="pause">Pause</button>
  <button id="stop">Stop</button>
  <br />
  <video id="camera"></video>
</body>
</html>