Search code examples
webcamgetusermedia

How do i detect multiple web-cameras connected to a system and choose a specific camera at a time?


I am trying to use two cameras on web application . My requirement is to detect these cameras from the browser and choose one camera at time to capture the image and display it in the web-page. It may be like we are displaying two buttons , by clicking on one button camera1 will be detected and capture the image , when the user press the other button second camera will be used to capture the image.

I need to achieve this using HTML5 and JavaScript. I already have some reference and tried navigator.webkitGetUserMedia() and MediaStreamTrack.getSources() but i am getting a script error using MediaStreamTrack.getSources(). Error : " Failed to execute 'getSources' on 'MediaStreamTrack': Functionality not implemented yet " .

Currently the browser is able to display the cameras and user need to select the camera on page load, can we do it programmatically?

Here is the link for the code : http://jsfiddle.net/xL8wzzx2/

<!DOCTYPE html>
<body>
<video id="video" autoplay></video>
<button id="snap">Capture</button>
<button id="new">New</button>
<canvas id="canvas" width="640" height="480"></canvas>
<button id="upload">Upload</button>
</body>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1 /jquery.min.js"></script>
<script>

// Put event listeners into place
window.addEventListener("DOMContentLoaded", function() {
// Grab elements, create settings, etc.

var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
video = document.getElementById("video"),
videoObj = { "video": true },
errBack = function(error) {
   console.log("Video capture error: ", error.code); 
};


/* < Error: TypeError: MediaStreamTrack.getSources is not a function >*/

MediaStreamTrack.getSources(function(sources){
  var cams = _.filter(sources, function(e){ //only return video elements 
  return e.kind === 'video';
  });
  var camIds = _.map(cams, function (e) { // return only ids
    return e.id;
 });
});

// </Error  >If the above block is removed, then it is working properly.




// Put video listeners into place
if(navigator.getUserMedia) { // Standard
navigator.getUserMedia(videoObj, function(stream) {
video.src = stream;
video.play();
}, errBack);
} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(videoObj, function(stream){
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
} else if(navigator.mozGetUserMedia) { // WebKit-prefixed
navigator.mozGetUserMedia(videoObj, function(stream){
video.src = window.URL.createObjectURL(stream);
video.play();
}, errBack);
}
// Trigger photo take
document.getElementById("snap").addEventListener("click", function() {
context.drawImage(video, 0, 0, 640, 480);
// Littel effects
$('#video').fadeOut('slow');
$('#canvas').fadeIn('slow');
$('#snap').hide();
$('#new').show();
// Allso show upload button
//$('#upload').show();
});
// Capture New Photo
document.getElementById("new").addEventListener("click", function() {
$('#video').fadeIn('slow');
$('#canvas').fadeOut('slow');
$('#snap').show();
$('#new').hide();
});
// Upload image to sever 
document.getElementById("upload").addEventListener("click", function(){
var dataUrl = canvas.toDataURL();
$.ajax({
type: "POST",
url: "camsave.php",
data: { 
imgBase64: dataUrl
}
}).done(function(msg) {
console.log('saved');
// Do Any thing you want
});
});
}, false);


// Upload image to sever 
document.getElementById("upload").addEventListener("click", function(){
var dataUrl = canvas.toDataURL();
$.ajax({
type: "POST",
url: "camsave.php",
data: { 
imgBase64: dataUrl
}
}).done(function(msg) {
console.log('saved');
// Do Any thing you want
});
});


</script>

Thank you.


Solution

  • You can detect multiple cameras in chrome(as if now). It's done with the help of a js function called getSources() You can use following code for that:

    function gotSources(sourceInfos) {
      var cam_count = 1;
      for (var i = 0; i != sourceInfos.length; ++i) {
        var sourceInfo = sourceInfos[i];
        if (sourceInfo.kind == 'video') {
          opt_text = "camera" + cam_count;
          cam_count++;
          $("#sel_src").append(new Option(opt_text, sourceInfo.id));
        }
      }
    }
    
    function set_cam() {
        var camera_id = document.getElementById("sel_src").value;
        $.post("assign_cam.php", {
            cam_id: camera_id,
            cam_number: cam_no
          },
          function(data, status) {
            alert(data);
          }
        );
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <div id="sel_src_list" style="color:white">
      <br>Capture Image :
      <select id="sel_src" name="sel_src1"></select>&nbsp;&nbsp;&nbsp;
      <input type="button" id="cam1" name="cam1" onclick="set_cam()" value="Assign">
    </div>
    <div style="color:white" id="src_list"></div>
    <script>
      navigator.getUserMedia = navigator.getUserMedia ||
        navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
    
      if (typeof MediaStreamTrack === 'undefined') {
        alert('This browser does not support MediaStreamTrack.\n\nTry Chrome Canary.');
      } else {
        MediaStreamTrack.getSources(gotSources);
      }
    </script>

    To see it's working you should connect multiple camera to your PC and the chrome browser should be installed(latest version). You have to store those camera ids in a page and use it in another page for buttons which should be used to capture the image. For that you can use following query :

      function show_cam2(cam_src_id) {
        $('#video').fadeOut('slow');
        $('#canvas').fadeOut('slow');
        $('#video2').fadeIn('slow');
        $('#canvas').fadeIn('slow');
        // Grab elements, create settings, etc.
        var canvas = document.getElementById("canvas2"),
          context = canvas.getContext("2d"),
          video = document.getElementById("video2"),
          videoObj = {
            "video": true
          },
          errBack = function(error) {
            console.log("Video capture error: ", error.code);
          };
    
    
    
        var constraints = {
          video: {
            optional: [{
              sourceId: cam_src_id
            }]
          }
        };
    
    
    
    
        // Put video listeners into place
        if (navigator.getUserMedia) { // Standard
          navigator.getUserMedia(constraints, function(stream) {
            video.src = stream;
            video.play();
          }, errBack);
        } else if (navigator.webkitGetUserMedia) { // WebKit-prefixed
          navigator.webkitGetUserMedia(constraints, function(stream) {
            video.src = window.webkitURL.createObjectURL(stream);
            video.play();
          }, errBack);
        } else if (navigator.mozGetUserMedia) { // WebKit-prefixed
          navigator.mozGetUserMedia(constraints, function(stream) {
            video.src = window.URL.createObjectURL(stream);
            video.play();
          }, errBack);
        }
        // Trigger photo take
        document.getElementById("snap2").addEventListener("click", function() {
          context.drawImage(video, 0, 0, 640, 480);
          // Littel effects
          $('#video2').fadeOut('slow');
          $('#canvas2').fadeIn('slow');
          $('#snap2').hide();
          $('#new2').show();
        });
        // Capture New Photo
        document.getElementById("new2").addEventListener("click", function() {
          $('#video2').fadeIn('slow');
          $('#canvas2').fadeOut('slow');
          $('#snap2').show();
          $('#new2').hide();
        });
        // Upload image to sever 
        document.getElementById("upload2").addEventListener("click", function() {
          var dataUrl = canvas.toDataURL();
          $.ajax({
            type: "POST",
            url: "camsave.php",
            data: {
              imgBase64: dataUrl
            }
          }).done(function(msg) {
            console.log('saved');
            // Do Any thing you want
          });
        });
      }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <table border=1>
      <tr>
        <td>
          <video id="video" width="320" height="240" autoplay></video>
        </td>
        <td>
          <button id="snap">Capture</button>
        </td>
        <td>
          <button id="new">New</button>
        </td>
        <td>
          <canvas id="canvas" width="320" height="240"></canvas>
        </td>
        <td>
          <button id="upload">Upload</button>
        </td>
        <td>
          <input type="button" onclick=show_cam( '< device #1>') value="capture_image">
        </td>
      </tr>
      <tr>
        <td>
          <video id="video2" width="320" height="240" autoplay></video>
        </td>
        <td>
          <button id="snap2">Capture2</button>
        </td>
        <td>
          <button id="new2">New2</button>
        </td>
        <td>
          <canvas id="canvas2" width="320" height="240"></canvas>
        </td>
        <td>
          <button id="upload2">Upload2</button>
        </td>
        <td>
          <input type="button" onclick=show_cam2( '< device #1>') value="capture_image_2">
        </td>
    
      </tr>
    </table>
    <script>
      // Put event listeners into place
      //window.addEventListener("DOMContentLoaded", function() {
      function show_cam(cam_src_id) {
          $('#video2').fadeOut('slow');
          $('#canvas2').fadeOut('slow');
          $('#video').fadeIn('slow');
          $('#canvas').fadeIn('slow');
          // Grab elements, create settings, etc.
          var canvas = document.getElementById("canvas"),
            context = canvas.getContext("2d"),
            video = document.getElementById("video"),
            videoObj = {
              "video": true
            },
            errBack = function(error) {
              console.log("Video capture error: ", error.code);
            };
    
    
          var constraints = {
            video: {
              optional: [{
                sourceId: cam_src_id
              }]
            }
          };
          // navigator.getUserMedia(constraints, successCallback, errorCallback);
    
    
    
          // Put video listeners into place
          if (navigator.getUserMedia) { // Standard
            navigator.getUserMedia(constraints, function(stream) {
              video.src = stream;
              video.play();
            }, errBack);
          } else if (navigator.webkitGetUserMedia) { // WebKit-prefixed
            navigator.webkitGetUserMedia(constraints, function(stream) {
              video.src = window.webkitURL.createObjectURL(stream);
              video.play();
            }, errBack);
          } else if (navigator.mozGetUserMedia) { // WebKit-prefixed
            navigator.mozGetUserMedia(constraints, function(stream) {
              video.src = window.URL.createObjectURL(stream);
              video.play();
            }, errBack);
          }
          // Trigger photo take
          document.getElementById("snap").addEventListener("click", function() {
            context.drawImage(video, 0, 0, 640, 480);
            // Littel effects
            $('#video').fadeOut('slow');
            $('#canvas').fadeIn('slow');
            $('#snap').hide();
            $('#new').show();
            // Allso show upload button
            //$('#upload').show();
          });
          // Capture New Photo
          document.getElementById("new").addEventListener("click", function() {
            $('#video').fadeIn('slow');
            $('#canvas').fadeOut('slow');
            $('#snap').show();
            $('#new').hide();
          });
          // Upload image to sever 
          document.getElementById("upload").addEventListener("click", function() {
            var dataUrl = canvas.toDataURL();
            $.ajax({
              type: "POST",
              url: "camsave.php",
              data: {
                imgBase64: dataUrl
              }
            }).done(function(msg) {
              console.log('saved');
              // Do Any thing you want
            });
          });
        }
        //}, false);
    </script>