使用Web Camera拍摄个人资料图片并在画布中显示图片

Use Web Camera to capture profile pic and display the pic in canvas

本文关键字:布中 显示图 资料图片 Camera Web 使用      更新时间:2023-09-26

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

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

谷歌开发者建议使用navigator.getUserMedia,它也与我的应用程序兼容。

链接: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');
});

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

例如,这个fiddle适用于所有受支持的浏览器。

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

也支持现代约束语法。

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

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

我不确定Chrome是否允许从堆栈片段中获取UserMedia,所以这里有一个jsfiddle

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);
  }
canvas{border: 1px solid red}