Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using WebRTC how to choose mic and camera?

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...

like image 700
lucas emanuel himelfarb Avatar asked Feb 11 '19 12:02

lucas emanuel himelfarb


1 Answers

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.

like image 159
jib Avatar answered Oct 12 '22 19:10

jib