使用网络摄像头捕获个人资料图片并在画布中显示图片

时间:2015-11-06 04:36:24

标签: javascript firefox canvas camera webcam-capture

我有一个插件,我使用笔记本电脑或手机上的网络摄像头捕捉图像,然后将其放在画布中。所有这些在Chrome中运行良好,但在使用Firefox时,它根本不起作用。我怀疑它是navigator.getUserMedia,它在firefox中引起了问题,因为它已被弃用。

link:https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMedia

Google开发人员建议使用navigator.getUserMedia,它也与我的应用程序兼容。

link:https://developers.google.com/web/updates/2015/10/media-devices

因此,请建议在下面的代码中进行哪些更改,以便在firefox中使用。

先谢谢。

<script type="text/javascript">
var ctx = null;
var canvas = document.getElementById("tmpImage");
var localMediaStream = null;
var video = document.querySelector('video');

function snapshot() {
    if (localMediaStream) {
        ctx.drawImage(video, 0, 0);
        var img = document.getElementById('CaptureImage');
        // "image/webp" works in Chrome 18. In other browsers, this will fall back to image/png.
        img.src = canvas.toDataURL('image/webp');
    }
}

function hasGetUserMedia() {
    // Note: Opera builds are unprefixed.
    return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia || navigator.msGetUserMedia);
}

function onFailSoHard(e) {
    if (e.code == 1) {
        alert('User denied access to their camera');
    } else {
        alert('getUserMedia() not supported in your browser.');
    }
}

function start() {

    if (hasGetUserMedia()) {
        if (navigator.webkitGetUserMedia)
            navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
        //var getUserMedia = navigator.webkitGetUserMedia || navigator.getUserMedia;


        //var gumOptions = { video: true, toString: function () { return 'video'; } };    
        if (navigator.getUserMedia) {

            navigator.getUserMedia({
                video: true,
                audio: false
            }, function (stream) {
                if (navigator.webkitGetUserMedia) {
                    video.src = window.webkitURL.createObjectURL(stream);
                } else {
                    video.src = stream; // Opera
                }
                localMediaStream = stream;
            }, onFailSoHard);
        } else {
            video.src = 'somevideo.webm'; // fallback.
        }
    }
}

function stop() {
    video.pause();
    video = document.getElementById('sourcevid');
    video.src = "";
    localMediaStream.stop();
}

function ResizeCanvas() {
    canvas.height = video.videoHeight;
    canvas.width = video.videoWidth;
}

$(document).ready(function () {
    ctx = canvas.getContext('2d');
});

2 个答案:

答案 0 :(得分:2)

使用官方adapter.js polyfill。问题解决了。

E.g。 this fiddle适用于所有受支持的浏览器。

navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => video.srcObject = stream)
  .catch(e => console.error(e));

也支持modern constraints syntax

答案 1 :(得分:0)

是的,getUserMedia API正在发展。 新语法为navigator.mediaDevices.getUserMedia。 Edge和Firefox已经实现了这种新语法,它将返回一个Promise,迫使我们重写代码......
Chrome关于它的确很晚,甚至还使用了一些从未标准化的视频约束语法。 这个过程现在变得有点复杂,但有一些libraries可以处理这些情况。

我还编写了自己的实现,可以处理大多数支持GUM的浏览器:

我不确定Chrome是否允许来自堆栈代码段的getUserMedia,所以is a jsfiddle

&#13;
&#13;
var video,canvas,ctx;
var settings = {
  video_constraints: {
    width: {
      min: 1200,
      max: 1920
    },
    height: {
      min: 720,
      max: 1080
    },
    require: ["width", "height"],
    facingMode: "user",
  },
  audio: false,
}

function getStream(video) {
  video.streaming = false;
  if (navigator.webkitGetUserMedia)
    setWebkitConstraints();
  navigator.getUserMedia = navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
  if (!navigator.getUserMedia && !navigator.mediaDevices) {
    alert('GUM is not supported by this browser');
    return false;
  }
  var opts = {
    video: settings.video_constraints,
    audio: settings.audio
  };
  var then = function(stream) {
    if (navigator.mozGetUserMedia)
      video.mozSrcObject = stream;
    else {
      var URL = window.URL || window.webkitURL;
      video.src = URL.createObjectURL(stream);
    }
    video.play();
    loopStart(video);
  };
  var error = function(err) {
    console.log("An error occured! ", err)
    if (err.name.indexOf('Permission') == 0) return;
  };

  if (navigator.mediaDevices) {
    navigator.mediaDevices.getUserMedia(opts).then(then, error).catch(error);
  } else {
    navigator.getUserMedia(opts, then, error);
  }
};
// handle webkit old and deprecated constraint syntax
var setWebkitConstraints = function() {
  var wkConstraints = {
    mandatory: {}
  };
  var c = settings.video_constraints;
  for (var i in c) {
    switch (i) {
      case 'width':
        for (j in c[i]) {
          switch (j) {
            case 'max':
              wkConstraints.mandatory.maxWidth = c[i][j];
              break;
            case 'min':
              wkConstraints.mandatory.minWidth = c[i][j];
              break;
            case 'exact':
              wkConstraints.mandatory.minWidth = wkConstraints.mandatory.maxWidth = c[i][j];
              break;
          }
        };
        break;

      case 'height':
        for (var j in c[i]) {
          switch (j) {
            case 'max':
              wkConstraints.mandatory.maxHeight = c[i][j];
              break;
            case 'min':
              wkConstraints.mandatory.minHeight = c[i][j];
              break;
            case 'exact':
              wkConstraints.mandatory.minHeight = wkConstraints.mandatory.maxHeight = c[i][j];
              break;
          }
        };
        break;
      default:
        break;
    }
  }
  settings.video_constraints = wkConstraints;
};
var loopStart= function(video){
		
		if (!video.streaming) {
			if(video.videoHeight === 0){
				window.setTimeout(function() {
					video.pause();
					video.play();
					loopStart(video);
					}, 100);
				}
			else {
				video.streaming = true;
				video.dispatchEvent(new Event('streaming'));
				}
			}else{return;}
		};

(function init(){
  video = document.createElement('video');
  canvas = document.createElement('canvas');
  document.body.appendChild(canvas);
  ctx = canvas.getContext('2d');
  video.addEventListener('streaming', copy2canvas, false);
  getStream(video);
  })()
function copy2canvas(){
	console.log('succesfully streaming');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    draw();
    }
function draw(){
    ctx.drawImage(video, 0,0);
    requestAnimationFrame(draw);
  }
&#13;
canvas{border: 1px solid red}
&#13;
&#13;
&#13;