javascript 无法在第一页加载时在 Google Chrome 中使用 HTML5 和 getUserMedia() 从网络摄像头拍摄照片

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14868621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 22:47:36  来源:igfitidea点击:

Unable to take photo from webcam using HTML5 and getUserMedia() in Google Chrome on first page load

javascripthtmlhtml5-canvashtml5-videowebcam

提问by Naveen

Taking reference from this article on HTML5RocksI am trying to build a utility to take photo from webcam.

参考这篇关于 HTML5Rocks 的文章,我正在尝试构建一个实用程序来从网络摄像头拍摄照片。

Below is my HTML code snippet:

下面是我的 HTML 代码片段:

<button type="button" name="btnCapture" id="btnCapture">Start my camera</button><br />
<video autoplay="true" id="video" style="height:240px;width:320px"></video><canvas id="canvas" style="display: none; height:240px;width:320px"></canvas><br />
<img id="capturedImage" src="/blank.gif" style="height:240px;width:320px"><input type="hidden" id="hdnImageBase64" name="hdnImageBase64"><br />

On click of button btnCaptureI start my webcam and clicking it again It captures the photo from webcam and puts it into the image capturedImage.

单击按钮,btnCapture我启动网络摄像头并再次单击它从网络摄像头捕获照片并将其放入图像中capturedImage

Below is my JavaScript code:

下面是我的 JavaScript 代码:

var video = document.getElementById("video");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var localMediaStream = null;
var capturedImage = document.getElementById("capturedImage");
var buttonTextCapturePicture = "Say Cheese!";

function onFailSoHard(e) {
    if (e.code == 1) {
        alert("Something went wrong! Either your webcam is not connected or you denied access to it.");
    } else {
        alert("getUserMedia() not supported in your browser. Try using latest version of Google Chrome or Opera.");
    }
}

function snapshot() {
    if (localMediaStream) {
        try {
            ctx.drawImage(video, 0, 0);
            capturedImage.src = canvas.toDataURL("image/png");
            document.getElementById("hdnImageBase64").value = canvas.toDataURL("image/png");
        } catch (e) {
            alert("Something went wrong while capturing you. Try refreshing the page. " + e);
        }
    }
}

video.addEventListener("click", snapshot, false);

function sizeCanvas() {
    setTimeout( function() {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        capturedImage.height = video.videoHeight;
        capturedImage.width = video.videoWidth;
    }, 50);
}

var button = document.getElementById("btnCapture");
button.addEventListener("click", function(e) {
    if (localMediaStream) {
        snapshot();
        return;
    }
    if (navigator.getUserMedia) {
        navigator.getUserMedia("video", function(stream) {
            video.src = stream;
            localMediaStream = stream;
            sizeCanvas();
            button.textContent = buttonTextCapturePicture;
        }, onFailSoHard);
    } else if (navigator.webkitGetUserMedia) {
        navigator.webkitGetUserMedia({"video" : true}, function(stream) {
            video.src = window.webkitURL.createObjectURL(stream);
            localMediaStream = stream;
            sizeCanvas();
            button.textContent = buttonTextCapturePicture;
        }, onFailSoHard);
    } else {
        onFailSoHard({
            target : video
        });
    }
}, false);

When the button btnCaptureis clickd first time it calls the function sizeCanvas()to set the canvas and image width & height to video's width & height (i.e. 320 & 240). When the button is clicked second time it take Base64 encoded snapshot from webcam using canvas.toDataURLand puts it into image capturedImage.

btnCapture第一次点击按钮时,它调用函数sizeCanvas()将画布和图像的宽度和高度设置为视频的宽度和高度(即 320 和 240)。第二次单击该按钮时,它会使用来自网络摄像头的 Base64 编码快照canvas.toDataURL并将其放入图像中capturedImage

It works in Opera. But in Google Chrome it always fails the first time when page is loaded. But when the same page is refreshed it works. Trying to debug I found that the code canvas.toDataURLreturns image Base64 as data:,for the first time due to which it is unable to draw image whih results in error of Resource interpreted as Image but transferred with MIME type text/plain: "data:,".in console. Also if I do not call the function sizeCanvasthen it works first time but then the picture is not of the dimension I require and gets cropped.

它适用于歌剧。但是在谷歌浏览器中它总是在第一次加载页面时失败。但是当刷新同一页面时,它就可以工作了。尝试调试时,我发现代码第一次canvas.toDataURL返回图像 Base64,data:,因为它无法绘制图像,导致Resource interpreted as Image but transferred with MIME type text/plain: "data:,".控制台出错。此外,如果我不调用该函数,sizeCanvas那么它第一次工作,但图片不是我需要的尺寸并被裁剪。

Any ideas how I can make it work in Chrome the first time with sizeCanvas?

有什么想法可以让我第一次在 Chrome 中使用它sizeCanvas吗?

Google Chrome: 24.0.1312.57 Opera: 12.11

谷歌浏览器:24.0.1312.57 歌剧:12.11

回答by Black Sheep

LIVE DEMO

现场演示

Works well in Chrome and FF.

在 Chrome 和 FF 中运行良好。

(function() {

  var streaming = false,
      video        = document.querySelector('#video'),
      canvas       = document.querySelector('#canvas'),
      photo        = document.querySelector('#photo'),
      startbutton  = document.querySelector('#startbutton'),
      width = 320,
      height = 0;

  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);
    }
  );

This code I found here: LINK DEVELOPER MOZILLA

我在这里找到的代码:LINK DEVELOPER MOZILLA

UPDATE: I updated my Live Demo to JSFiddle because getUserMedia()is no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See The Chromium Projectsfor more details.

更新:我将我的 Live Demo 更新为 JSFiddle,因为getUserMedia()它不再适用于不安全的来源。要使用此功能,您应该考虑将应用程序切换到安全来源,例如 HTTPS。有关更多详细信息,请参阅Chromium 项目