6

Using the API navigator.mediaDevices.enumerateDevices() I got the ID of the devices available in the computer, but I don't know how to tell the navigator that I want to switch the camera or mic. In the forums there are many examples, but none is clear since webRTC changed many times the API and its reference. There is only one example in the web, proposed by webRTC but I can't really understand it or at least I cannot find in its code what I need.

I have not tried much because I am very new with webRTC...

if(!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) console.log('Enumerate Media Devices from getUserMedia is not supported');
navigator.mediaDevices.enumerateDevices()
    .then(function(devices) {
        devices.forEach(function(device) {
            if (device.kind == 'audioinput' || device.kind == 'audiooutput') $scope.devicesAudio.push(device);
            else if (device.kind == 'videoinput' || device.kind == 'videooutput') $scope.devicesVideo.push(device);
            else $scope.devices.push(device);
        });
    })
    .catch(function(err) {
        console.log(err.name + ':' + err.message);
    });




$scope.selectDevice = function(device) {

    if(device.kind == 'videooutput' || device.kind == 'videoinput') {
        console.log('video Device selected' + ' DEVICE_ID: ' + device.deviceId);
    }
    else if(device.kind == 'audioinput' || device.kind == 'videooutput') {
        console.log('Audio device selected' + ' DEVICE_ID: ' + device.deviceId);
    };
};

I hope that my application has the option to change the camera and the microphone...

1 Answers1

3

Use the deviceId constraint. I've updated MDN to mention it.

$scope.selectDevice = function(device) {
  let constraints, oldtrack;
  if (device.kind == 'videoinput') {
    constraints = {video: { deviceId: {exact: device.deviceId}}};
    oldtrack = (video.srcObject || []).getVideoTracks()[0];
  } else {
    constraints = {audio: { deviceId: {exact: device.deviceId}}};
    oldtrack = (video.srcObject || []).getAudioTracks()[0];
  }
  // Most phones only handle one camera open at a time, so stop old device first.
  if (oldtrack) {
    oldtrack.stop();
  }
  return navigator.mediaDevices.getUserMedia(constraints) 
    .then(stream => video.srcObject = stream);
    .catch(err => console.log(err.name + ':' + err.message));
}

Use the exact keyword to prevent fallback to a different device, since this is a selector.

You can ignore "audiooutput", as those are speakers, not mics. There's also no such thing as "videooutput". That's an invalid value. Those would be displays I suppose, but those are not enumerated by enumerateDevices().

The above is for illustration only, to show how the APIs work. Since we're dealing with hardware, making a robust selector is an exercise left to the reader.

For example: Most phones only handle one camera open at the same time. There may also be other conflicts like having a mic from a camera other than the camera in use, for example. Compare device.groupId properties to learn if a camera and a microphone are on the same hardware. If they match, it might work better to change camera and mic in tandem, for instance.

If you suspect hardware issues, try the WebRTC samples demo on your system.

jib
  • 40,579
  • 17
  • 100
  • 158
  • in its way it is not working, what I did was to pass the id of the device and the type (audio or video) from the HTML, so I could change the camera, but it generates conflict with the microphone – lucas emanuel himelfarb Feb 11 '19 at 19:30
  • @lucasemanuelhimelfarb Is this on a phone? Sounds like a hardware limitation, not an API problem. I've updated the example to handle phones. – jib Feb 11 '19 at 22:15
  • no, I am using the simplewebRTC library, specifically the conflict that I have is that, when I change the microphone, I delete the video... – lucas emanuel himelfarb Feb 12 '19 at 13:42
  • @lucasemanuelhimelfarb Well, I believe I've answered your question. I hope you figure out your specific problem. – jib Feb 12 '19 at 15:51
  • I left behind this case to move on with other things, today I have to return to the subject. One of the questions I have noted is the following: How to start the renegotiation? When changing the camera, the other person does not see the new flow generated ... Thanks in advance! – lucas emanuel himelfarb Mar 28 '19 at 12:13
  • okay! this is my new question https://stackoverflow.com/questions/55400158/how-to-restore-the-negotiation-after-changing-the-camera-and-microphone – lucas emanuel himelfarb Mar 28 '19 at 14:31