How can I get a list of video cameras attached in my computer using JavaScript?
Asked Answered
B

6

16

I want to display a list of video cameras attached to the user's computer, and when they select one, display streaming video from that camera in an HTML5 <video> tag.

How can I get a list of the video cameras attached to the user's computer?

Briareus answered 19/9, 2013 at 11:47 Comment(1)
Don't reinvent the wheel. Is already done with webRTC API. Look at @André Dion answer.Absurdity
H
7

Perhaps Navigator.getUserMedia() (uses WebRTC under the hood) is what you're looking for, though I don't see anything that will directly tell you what devices are available (the list of devices isn't exposed to your code—it's presented to the user when asking for permission to access available hardware).

Also note the browser support: Chrome 21+, Firefox 20+, Opera 12+, no support for IE and possibly Safari.

Hilde answered 19/9, 2013 at 11:58 Comment(12)
getUserMedia doesn't return the available attached devices, it only prompts a popup to the user asking what device he wants to use. If the user accepts, the second parameter on getUserMedia method (an acceptCallback) is called; otherwise, the third parameter (failedCallback) is called. dev.w3.org/2011/webrtc/editor/…Absurdity
@Thomás Not directly, no, but the successCallback does pass in a MediaStream object which exposes track information.Combustible
yes, only the track the user accepted to use. But I think @Panchotiya wants all the available devices.Absurdity
On a second though....I think I understand your position now. @Pachotiya is reinventing the wheel... He wants to display a list of available video devices which getUserMedia already does it for you in the popup...Absurdity
@Tomás I've added a similar statement to my answer for clarification. Thanks for your input.Combustible
If someone wants to try to use webRTC in IE follow this link: groups.google.com/d/msg/discuss-webrtc/tKoh1wrI8ig/MPTdCHpgcm4J (haven't tested it)Absurdity
@Tomás: @Pachotiya isn't re-inventing the wheel. He's designed an interface that he thinks would be good. Maybe it would be better in some ways, or for some tasks, than the interface allowed by Navigator.getUserMedia.Frustrated
@Paul D. Waite: Yes, you are right. But, anyway...the interface provided by getUserMedia is for an important security reason. WebDevelopers should never be able to start a local streaming without the user permission.Absurdity
@Tomás: sure, although letting web developers get a list of attached devices isn't the same as letting them start local streaming.Frustrated
I'm not sure why the OP accepted this as the correct answer as it's clearly not. the statement "the list of devices isn't exposed to your code" is false. Refer to the answer with more upvote from @Hereabout which should have been the accepted as the correct one. (using navigator.mediaDevices.enumerateDevices())Bordy
@Unicornist, you're commenting on an answer that was accepted 10 years ago. Was enumerateDevices even available in 2013? Even as of writing this comment it's not fully supported in Firefox...Combustible
@AndréDion sorry man didn't notice that and didn't mean to be harsh on you I just wondered "why" it is accepted I didn't even downvote or anything. About FF partial support: actually, it's supported well across browsers and FF support is from 2015, but they just recently also added an "output" device list which is useless yet since switching or selecting output devices is a very new API and is only supported by the latest unreleased FF (v116) as the time of this comment.Bordy
H
21

Only works in chrome and edge

<script>
     navigator.mediaDevices.enumerateDevices().then(function (devices) {
            for(var i = 0; i < devices.length; i ++){
                var device = devices[i];
                if (device.kind === 'videoinput') {
                    var option = document.createElement('option');
                    option.value = device.deviceId;
                    option.text = device.label || 'camera ' + (i + 1);
                    document.querySelector('select#videoSource').appendChild(option);
                }
            };
        });
</script>
 <select id="videoSource"></select>
Hereabout answered 22/2, 2017 at 18:49 Comment(2)
now this works everywhereBordy
There is no kind="videoinput" devices in my system :?. only "audioinput" and "audiooutput". Even my HD Pro Webcam C920 camera is showing as "audioinput". And the built-in camera is not detected. MacOS on Chrome.Rosalvarosalyn
H
7

Perhaps Navigator.getUserMedia() (uses WebRTC under the hood) is what you're looking for, though I don't see anything that will directly tell you what devices are available (the list of devices isn't exposed to your code—it's presented to the user when asking for permission to access available hardware).

Also note the browser support: Chrome 21+, Firefox 20+, Opera 12+, no support for IE and possibly Safari.

Hilde answered 19/9, 2013 at 11:58 Comment(12)
getUserMedia doesn't return the available attached devices, it only prompts a popup to the user asking what device he wants to use. If the user accepts, the second parameter on getUserMedia method (an acceptCallback) is called; otherwise, the third parameter (failedCallback) is called. dev.w3.org/2011/webrtc/editor/…Absurdity
@Thomás Not directly, no, but the successCallback does pass in a MediaStream object which exposes track information.Combustible
yes, only the track the user accepted to use. But I think @Panchotiya wants all the available devices.Absurdity
On a second though....I think I understand your position now. @Pachotiya is reinventing the wheel... He wants to display a list of available video devices which getUserMedia already does it for you in the popup...Absurdity
@Tomás I've added a similar statement to my answer for clarification. Thanks for your input.Combustible
If someone wants to try to use webRTC in IE follow this link: groups.google.com/d/msg/discuss-webrtc/tKoh1wrI8ig/MPTdCHpgcm4J (haven't tested it)Absurdity
@Tomás: @Pachotiya isn't re-inventing the wheel. He's designed an interface that he thinks would be good. Maybe it would be better in some ways, or for some tasks, than the interface allowed by Navigator.getUserMedia.Frustrated
@Paul D. Waite: Yes, you are right. But, anyway...the interface provided by getUserMedia is for an important security reason. WebDevelopers should never be able to start a local streaming without the user permission.Absurdity
@Tomás: sure, although letting web developers get a list of attached devices isn't the same as letting them start local streaming.Frustrated
I'm not sure why the OP accepted this as the correct answer as it's clearly not. the statement "the list of devices isn't exposed to your code" is false. Refer to the answer with more upvote from @Hereabout which should have been the accepted as the correct one. (using navigator.mediaDevices.enumerateDevices())Bordy
@Unicornist, you're commenting on an answer that was accepted 10 years ago. Was enumerateDevices even available in 2013? Even as of writing this comment it's not fully supported in Firefox...Combustible
@AndréDion sorry man didn't notice that and didn't mean to be harsh on you I just wondered "why" it is accepted I didn't even downvote or anything. About FF partial support: actually, it's supported well across browsers and FF support is from 2015, but they just recently also added an "output" device list which is useless yet since switching or selecting output devices is a very new API and is only supported by the latest unreleased FF (v116) as the time of this comment.Bordy
A
3

try out this...

<!DOCTYPE html>
  <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="author" content="Victor Stan">
      <meta name="description" content="Get multiple video streams on one page. Adapted from code by Muaz Khan">

      <title>Video Camera</title>

      <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" ></script>

      <style type="text/css" media="screen">
        video {
          border:1px solid gray;
        }
      </style>
  </head>
  <body>
    <script>
      if (!MediaStreamTrack) document.body.innerHTML = '<h1>Incompatible Browser Detected. Try <strong style="color:red;">Chrome Canary</strong> instead.</h1>';

      var videoSources = [];

      MediaStreamTrack.getSources(function(media_sources) {
        console.log(media_sources);
        alert('media_sources : '+media_sources);
        media_sources.forEach(function(media_source){
          if (media_source.kind === 'video') {
            videoSources.push(media_source);
          }
        });

        getMediaSource(videoSources);
      });

      var get_and_show_media = function(id) {
        var constraints = {};
        constraints.video = {
          optional: [{ sourceId: id}]
        };

        navigator.webkitGetUserMedia(constraints, function(stream) {
          console.log('webkitGetUserMedia');
          console.log(constraints);
          console.log(stream);

          var mediaElement = document.createElement('video');
          mediaElement.src = window.URL.createObjectURL(stream);
          document.body.appendChild(mediaElement);
          mediaElement.controls = true;
          mediaElement.play();

        }, function (e) 
        {
          alert('Hii');  
          document.body.appendChild(document.createElement('hr'));
          var strong = document.createElement('strong');
          strong.innerHTML = JSON.stringify(e);
          alert('strong.innerHTML : '+strong.innerHTML);
          document.body.appendChild(strong);
        });
      };

      var getMediaSource = function(media) {
        console.log(media);
        media.forEach(function(media_source) {
          if (!media_source) return;

          if (media_source.kind === 'video') 
          {
            // add buttons for each media item
            var button = $('<input/>', {id: media_source.id, value:media_source.id, type:'submit'});
            $("body").append(button);
            // show video on click
            $(document).on("click", "#"+media_source.id, function(e){
              console.log(e);
              console.log(media_source.id);
              get_and_show_media(media_source.id);
            });
          }
        });
      }
    </script>
  </body>
</html>
Aimo answered 20/9, 2013 at 6:45 Comment(1)
I get list but i want to stream in one video tagBriareus
A
1

JavaScript cannot access your cameras to return a list. You will need to use a Flash SWF to get the camera information and pass it back to your page's JavaScript.

EDIT: to those who downvoted. These methods will not give him a dropdown list of available cameras. If it does, please post a link or code. At the current date, the only way to get a list of cameras (which is what his questions was) is to use Flash (or possibly silverlight, but Flash has much broader install coverage). I've edited my question to be a little more specific in terms of getting the list versus accessing a camera.

Airlike answered 19/9, 2013 at 11:50 Comment(2)
webRTC API is available on firefox and chrome last versions. WebRTC is a standard in construction that promotes the use of the camera using only html5 and javascript. Maybe using webrtc he can access the available cameras.Absurdity
@Tomás That is not a solution to get the list of cameras via javascript. It will allow access to a camera on a limited set of browsers, but it doesn't answer his question.Airlike
E
0
await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
let devices = await navigator.mediaDevices.enumerateDevices();
devices = devices.filter((device) => device.kind == "videoinput");

devices variable is the array of webcam/video input devices.

Elainaelaine answered 15/11, 2023 at 7:35 Comment(0)
S
0

Getting a list of camera devices

const devices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = devices.filter(device => device.kind === 'videoinput');

Example: Setting a video device for playback

// get list of devices
const devices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = devices.filter(device => device.kind === 'videoinput');

// for this example, I'll choose the first one
const videoDevice = videoDevices[0];

// request user permission on media stream
// note: normally, you can call this multiple times w/o needing to
//       request permission again
mediaStreamRef = await navigator.mediaDevices.getUserMedia({
  audio: true,
  video: {
    deviceId: videoDevice?.deviceId
  }
});

// get video node
const videoRef = document.querySelector('video');

// reset everything on the video
videoRef.src = null;
videoRef.srcObject = mediaStreamRef;
videoRef.play();

Notes:

Stash answered 23/1, 2024 at 21:18 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.