4

I am successfully using webcam.js with an angular app to allow users to capture a picture of themselves. However I'm having a problem where some users are uploading blank - all white or all black photos. I suspect that some cameras start up more slowly than others which is allowing users to take pictures of themselves that are blank before the camera is really working.

I would like to be able to detect when the camera is actually on and streaming so I could wait until then to make the Take Photo button available. Normally after you go through the security step of allowing the camera, the video element is blank for half a second while the camera is turning on or the source is being loaded or whatever is happening. On my computer if I move fast I can just barely click the take picture button before the video steam is loaded and it will take a picture that shows as all black. I'm guessing on some computers that the half a second could be longer, possibly enough so that people are trying to take pictures before they see themselves on the screen.

We're also trying to solve this with some better UX, but it would be great if there was a way to prevent people from taking pictures before the camera is ready. I haven't been able to find anything so far about detecting when the camera is on, but have thought about the possibility of detecting the dominant color of a picture that's been taken and if it's all black or white tell the user to take it again, using something like this: Get average color of image via Javascript. Obviously not ideal to have the user go through that loop though if we could wait to show the take picture button.

Thank you in advance!

Community
  • 1
  • 1
Tracy B.
  • 63
  • 1
  • 7
  • Can't you detect the dominant color before putting up the take a picture button? – jib Mar 19 '16 at 02:30
  • I don't think I'd want do it with the method mentioned above (http://stackoverflow.com/questions/2541481/get-average-color-of-image-via-javascript) because I'd have to programmatically capture an image, create a canvas element, and check the color on an interval to determine when the picture was no longer a single color - that seems really heavy on the browser. Though I suppose that might be a solution if there is no other option to check if the camera is on. – Tracy B. Mar 21 '16 at 20:19
  • If you use a small width and height and not too frequent an interval then it shouldn't be a big deal. You only need create the canvas once. – jib Mar 21 '16 at 20:41

1 Answers1

5

Using video.onplaying worked for me (https fiddle for Chrome):

var snap = () => navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => {
    video.srcObject = stream;
    return new Promise(resolve => video.onplaying = resolve);
  })
  .then(() => canvas.getContext('2d').drawImage(video, 0, 0, 160, 120))
  .catch(log);

var log = msg => div.innerHTML += "<br>" + msg;
<button onclick="snap()">Snap!</button><div id="div"></div>
<video id="video" width="160" height="120" autoplay></video>
<canvas id="canvas" width="160" height="120"></canvas>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
jib
  • 40,579
  • 17
  • 100
  • 158
  • This is perfect, I think onplaying was actually what I was looking for, but I've implemented the more robust version of waiting for onplaying to show the button, and once the user takes a picture check to make sure that it isn't predominantly black or white. Thanks! – Tracy B. Mar 23 '16 at 17:32