Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make video stream Optional in getUserMedia

In my application a user can make calls if he can produce an audio stream. So, I need to require access to the microphone (audio stream). Without it the application should throw an error. Video is optional. So, I call navigator.getUserMedia and put constraints like this:

{ audio: true, video: false }

And it throws an error when a microphone is not present, just like I need. But a side effect from this is that if the user also has access to a camera, video is not present in stream.

But if I set both audio and video to true I would have an error in cases when users have a microphone but do not have access to a camera (which is ok according to my application logic)

How I can make a video stream optional get getUserMedia?

like image 704
SET Avatar asked Dec 12 '22 04:12

SET


2 Answers

There now exists another way. You can now check directly whether the user has a camera and/or a microphone before calling getUserMedia:

navigator.mediaDevices.enumerateDevices()
  .then(devices => {
    const cams = devices.filter(device => device.kind == "videoinput");
    const mics = devices.filter(device => device.kind == "audioinput");

    const constraints = { video: cams.length > 0, audio: mics.length > 0 };
    return navigator.mediaDevices.getUserMedia(constraints);
  })
  .then(stream => video.srcObject = stream)
  .catch(failed);

The other answer works as well, but this may be a bit cleaner.

Note that this is using enumerateDevices, which returns a list of devices with information. The amount of information returned is limited for privacy reasons ahead of calling getUserMedia, but it will still reveal whether the user has at least one camera and/or at least one microphone, which is all we need here.

like image 76
jib Avatar answered Dec 23 '22 17:12

jib


A solution I have found is to call getUserMedia with video and audio enabled, if the call fails(meaning that they either don't have a camera or a mic) then you call getUserMedia again from the failure callback that you provide requesting access to the microphone only.

var failedLocalAudioAndVideoStreamCallBack = function (error) {
      getUserMedia({ audio: true, video: false }, 
      gotLocalAudioStreamCallBack, failedLocalAudioStreamCallBack )});
    }

    getUserMedia({ audio: true, video: true },
    gotLocalAudioAndVideoStreamCallBack, failedLocalAudioAndVideoStreamCallBack); 

Of course, you can handle successes and failures however you like.

NOTE: if there is no camera, the pop-up requesting the initial camera feed(that will fail) never occurs. So, the user will only get one request for access(which makes this solution a tad bit more palatable).

like image 44
Benjamin Trent Avatar answered Dec 23 '22 16:12

Benjamin Trent