Devansh Sharma
Devansh Sharma

Reputation: 144

How does Camera Access work in HTML and JS?

I was looking for a way to implement a webcam into the browser and take a snapshot of the camera when the user clicks a button. There was a resource online that seemed to have use the code below but I cannot understand the following line. Can someone explain this?

navigator.getMedia = (navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia ||
        navigator.msGetUserMedia);

In case needed the entire code is below.

EDIT: Another related question in fact, what does navigator.getMedia represent and how does it work?

(function() {
  // Default Width set and height to be based on aspect ratio
  // Change to width/height of device (detect)
  var width = 320;
  var height = 0;

  //Status of stream
  var streaming = false;
  //Refers to <video> element
  var video = null;
  //Refers to <canvas> element
  var canvas = null;
  //Refers to <img> element
  var photo = null;
  //Refers to <button> element for trigger
  var startbutton = null;

  function startup() {
    video = document.getElementById('video');
    canvas = document.getElementById('canvas');
    photo = document.getElementById('photo');
    startbutton = document.getElementById('startbutton');

    navigator.getMedia = (navigator.getUserMedia ||
      navigator.webkitGetUserMedia ||
      navigator.mozGetUserMedia ||
      navigator.msGetUserMedia);

    navigator.getMedia({
        video: true,
        audio: false
      },
      function(stream) {
        if (navigator.mozGetUserMedia) {
          video.mozSrcObject = stream;
        } else {
          var vendorURL = window.URL || window.webkitURL;
          video.src = vendorURL.createObjectURL(stream);
        }
        video.play();
      },
      function(err) {
        console.log("An error occured! " + err);
      }
    );

    video.addEventListener('canplay', function(ev) {
      if (!streaming) {
        height = video.videoHeight / (video.videoWidth / width);

        // Firefox currently has a bug where the height can't be read from
        // the video, so we will make assumptions if this happens.

        if (isNaN(height)) {
          height = width / (4 / 3);
        }

        video.setAttribute('width', width);
        video.setAttribute('height', height);
        canvas.setAttribute('width', width);
        canvas.setAttribute('height', height);
        streaming = true;
      }
    }, false);

    startbutton.addEventListener('click', function(ev) {
      takepicture();
      ev.preventDefault();
    }, false);

    clearphoto();
  }

  // Fill the photo with an indication that none has been
  // captured.

  function clearphoto() {
    var context = canvas.getContext('2d');
    context.fillStyle = "#AAA";
    context.fillRect(0, 0, canvas.width, canvas.height);

    var data = canvas.toDataURL('image/png');
    photo.setAttribute('src', data);
  }

  // Capture a photo by fetching the current contents of the video
  // and drawing it into a canvas, then converting that to a PNG
  // format data URL. By drawing it on an offscreen canvas and then
  // drawing that to the screen, we can change its size and/or apply
  // other changes before drawing it.

  function takepicture() {
    var context = canvas.getContext('2d');
    if (width && height) {
      canvas.width = width;
      canvas.height = height;
      context.drawImage(video, 0, 0, width, height);

      var data = canvas.toDataURL('image/png');
      photo.setAttribute('src', data);
    } else {
      clearphoto();
    }
  }

  // Set up our event listener to run the startup process
  // once loading is complete.
  window.addEventListener('load', startup, false);
})();
<!doctype html>
<html>

<head>
  <script src="Camera.js"></script>
</head>

<body>
  <div>
    <div class="camera">
      <video id="video">Video stream not available.</video>
      <button id="startbutton">Take photo</button>
    </div>

    <canvas id="canvas"></canvas>

    <div class="output">
      <img id="photo" alt="The screen capture will appear in this box.">
    </div>

  </div>
</body>

</html>

Upvotes: 0

Views: 1608

Answers (2)

Barmar
Barmar

Reputation: 782315

The code you show is simply implementing backward compatibility for older browsers.

Before the navigator.getUserMedia() function was standardized, each of the major browsers had their own function, and it was conventional for them to name their extension functions with a browser prefix: webkit for WebKit-based browsers (Chrome and Safari), moz for Mozilla Firefox, and ms for Microsoft browsers.

The logical-OR operator || evaluates its operands from left to right, returning the first one that has a truthy value.

So what this code does is try to use navigator.getUserMedia() if it exists (which it would in a modern browser). If not, it then tries each of the older browser-specific functions as a fallback.

Upvotes: 2

Gustavo Topete
Gustavo Topete

Reputation: 1306

Well, the code itself is validating each case:

    navigator.getUserMedia ||
    navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia ||
    navigator.msGetUserMedia

it will return the first var which it's not null or undefined and then will be assigned to navigator.getMedia. I suppose that code was made to ensure it will work across multiple different browser and versions. If I'm wrong correct me please

Upvotes: 2

Related Questions