20

I want to make a program on the web which will capture an image via the user's webcam.

I am using the getUserMedia Web API. Here is my code, but it does not work. How can I change it to capture the webcam image?

<div id="container">
    <video autoplay="true" id="videoElement">

    </video>
</div>
<script>

</script>

There is the JS:

var video = document.querySelector("#videoElement");

navigator.getUserMedia, elem = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;

console.log(navigator.getUserMedia);

if (navigator.getUserMedia) {
    navigator.getUserMedia({video: true}, handleVideo, videoError);
}

function handleVideo(stream) {
    video.src = window.URL.createObjectURL(stream);
}

function videoError(e) {
    // do something
}
stef
  • 14,172
  • 2
  • 48
  • 70
PumpkinSeed
  • 2,945
  • 9
  • 36
  • 62
  • When you say "it does not work", could you specify what error you are seeing and what the expected behaviour should be? Adding a functioning example would also be helpful. – stef Nov 28 '15 at 19:31
  • I haven't error, when I saw the tutorial it ask permission to my webcam, but in my application nothing happened. – PumpkinSeed Nov 28 '15 at 19:39
  • @PumpkinSeed It's most likely because you have no webcam attached or some other program is already using it. – Jesper Jun 04 '19 at 14:37

3 Answers3

24

You can use this working sample

 <!DOCTYPE html>
<html>
  <head>
  </head>
  <body onload="init();">
    <h1>Take a snapshot of the current video stream</h1>
   Click on the Start WebCam button.
     <p>
    <button onclick="startWebcam();">Start WebCam</button>
    <button onclick="stopWebcam();">Stop WebCam</button> 
       <button onclick="snapshot();">Take Snapshot</button> 
    </p>
    <video onclick="snapshot(this);" width=400 height=400 id="video" controls autoplay></video>
  <p>

        Screenshots : <p>
      <canvas  id="myCanvas" width="400" height="350"></canvas>  
  </body>
  <script>
      //--------------------
      // GET USER MEDIA CODE
      //--------------------
          navigator.getUserMedia = ( navigator.getUserMedia ||
                             navigator.webkitGetUserMedia ||
                             navigator.mozGetUserMedia ||
                             navigator.msGetUserMedia);

      var video;
      var webcamStream;
            
      function startWebcam() {
        if (navigator.getUserMedia) {
           navigator.getUserMedia (

              // constraints
              {
                 video: true,
                 audio: false
              },

              // successCallback
              function(localMediaStream) {
                  video = document.querySelector('video');
                 video.srcObject=localMediaStream;
                 webcamStream = localMediaStream;
              },

              // errorCallback
              function(err) {
                 console.log("The following error occured: " + err);
              }
           );
        } else {
           console.log("getUserMedia not supported");
        }  
      }
            
      function stopWebcam() {
          webcamStream.stop();
      }
      //---------------------
      // TAKE A SNAPSHOT CODE
      //---------------------
      var canvas, ctx;

      function init() {
        // Get the canvas and obtain a context for
        // drawing in it
        canvas = document.getElementById("myCanvas");
        ctx = canvas.getContext('2d');
      }

      function snapshot() {
         // Draws current image from the video element into the canvas
        ctx.drawImage(video, 0,0, canvas.width, canvas.height);
      }

  </script>
</html>
suhailvs
  • 20,182
  • 14
  • 100
  • 98
ScaisEdge
  • 131,976
  • 10
  • 91
  • 107
  • I suggest you of post a new question with the related code e a well documented error you have .. – ScaisEdge May 22 '17 at 05:30
  • 1
    The error I receive is `Uncaught TypeError: webcamStream.stop is not a function at stopWebcam (snapshot:78) at HTMLButtonElement.onclick (snapshot:21)` – nu everest May 22 '17 at 14:33
  • check for you code ... because in my is clear that the webcamStream.stop() is a function .. and as suggested before y post a new question with your code ..and not the message error only – ScaisEdge May 22 '17 at 14:39
  • Getting this error Not allowed to load local resource: blob:null/ae3137ac-05ad-43ee-be8e-40c85984c987 –  Oct 20 '17 at 05:17
  • This still works fine in Firefox 61. To upload the content via form data create a hidden input `base64` and use `document.getElementById('base64').value=canvas.toDataURL('image/png'); ` – see https://www.kevinhoyt.com/2015/06/18/webcam-to-php-upload/ – maybe add this to your Answer – rubo77 Aug 25 '18 at 07:50
  • 1
    Just tried this example in Chrome and it does not work. The line below will not work as it says that a function with that signature can't be found: video.src = window.URL.createObjectURL(localMediaStream); I replaced it with: video.srcObject = localMediaStream; to make it work. Though the stop-button does not work as Chrome says that there is no stop-function on the webcamstream. – Jesper Jun 04 '19 at 14:30
  • [`LocalMediaStream` was dropped](https://developer.mozilla.org/en-US/docs/Web/API/LocalMediaStream) in favor of [`MediaStream`](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream) (which in return has a completely different interface and e.g. no `.stop()` method); same goes for `Navigator.getUserMedia` - I suggest to have a look at this snipped instead https://stackoverflow.com/a/57915667/2182191 – foobored Jul 15 '21 at 09:04
  • hi @ScaisEdge iam using your code to take screen shot and i am able to take screen shot can you please tell me how i can get that picture file so that i can upload to my server – Hamza Qureshi Apr 15 '22 at 07:28
  • @HamzaQureshi you should take the canvas content as an image eg: `var img = canvas.toDataURL("image/png"); ` once you have the img then you shoull take a look for update the image to the server – ScaisEdge Apr 15 '22 at 07:51
19

There have been updates to the getUserMedia api that now expose takePhoto and grabFrame. The grabFramemethod is less exciting because it does what we have been doing all along and just returning the next video frame from the stream but takePhoto interupts the stream to use the cameras "highest available photographic camera resolution" to capture a compressed image blob. More details here: google devs

var stream, imageCapture; 

function getMediaStream()
{ 
    window.navigator.mediaDevices.getUserMedia({video: true})
    .then(function(mediaStream)
    { 
        stream = mediaStream; 
        let mediaStreamTrack = mediaStream.getVideoTracks()[0];
        imageCapture = new ImageCapture(mediaStreamTrack);
        console.log(imageCapture);
    })
    .catch(error);
}

function error(error)
{ 
    console.error('error:', error); 
}

function takePhoto(img)
{ 
    const img = img || document.querySelector('img');

    imageCapture.takePhoto()
    .then(blob => {
        let url = window.URL.createObjectURL(blob);
        img.src = url;

        window.URL.revokeObjectURL(url); 
    })
    .catch(error);
}; 

/* just call */ 
getMediaStream(); 

/* and when you want to capture an image */ 
takePhoto();
tech-e
  • 434
  • 5
  • 15
-1

getUserMedia is not supported by IE11, take a look on this link: https://caniuse.com/#search=getuserMedia

So if you are still wanted to use the core property of getUserMedia then you need to use polyfill. Take a look on this polyfilllink: https://github.com/addyosmani/getUserMedia.js

Santosh
  • 1
  • 3