代码之家  ›  专栏  ›  技术社区  ›  Devansh Sharma

摄像头访问在HTML和JS中是如何工作的?

  •  0
  • Devansh Sharma  · 技术社区  · 8 年前

    我正在寻找一种在浏览器中实现网络摄像头的方法,当用户单击按钮时,可以对摄像头进行快照。有一个在线资源似乎使用了下面的代码,但我无法理解下面的代码。有人能解释一下吗?

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

    如果需要,完整代码如下。

    编辑:另一个相关问题事实上 navigator.getMedia 代表以及它是如何工作的?

    (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>
    2 回复  |  直到 8 年前
        1
  •  2
  •   Barmar    8 年前

    您显示的代码只是实现了对旧浏览器的向后兼容性。

    navigator.getUserMedia() 功能是标准化的,每个主要浏览器都有自己的功能,传统的做法是使用浏览器前缀命名扩展功能: webkit 对于基于WebKit的浏览器(Chrome和Safari), moz 对于Mozilla Firefox,以及 ms 对于Microsoft浏览器。

    逻辑OR运算符 || 从左到右计算其操作数,返回第一个具有truthy值的操作数。

    所以这段代码所做的就是尝试使用 导航器。getUserMedia() 如果它存在(在现代浏览器中也会存在)。如果没有,则会尝试使用每个旧的浏览器特定功能作为后备功能。

        2
  •  2
  •   Gustavo Topete    8 年前

    代码本身正在验证每个案例:

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

    它将返回第一个非null或未定义的var,然后将其分配给navigator。getMedia。我认为,编写这些代码是为了确保它能够跨多个不同的浏览器和版本工作。如果我错了,请纠正我