最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Make video stream Optional in getUserMedia - Stack Overflow

programmeradmin5浏览0评论

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?

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?

Share Improve this question edited Sep 1, 2021 at 18:42 jib 42.5k17 gold badges108 silver badges165 bronze badges asked Aug 14, 2014 at 12:50 SET001SET001 11.7k7 gold badges54 silver badges79 bronze badges 3
  • Check github./alongubkin/phonertc or refer to @Alon Gubkin. – barak manos Commented Aug 14, 2014 at 12:53
  • @barakmanos sc-cdn.scaleengine/i/a09d947bd5fe171b8c8fdc1b1f9f1a00.jpg – SET001 Commented Aug 14, 2014 at 13:48
  • Then use the other option that I mentioned... – barak manos Commented Aug 14, 2014 at 13:50
Add a ment  | 

3 Answers 3

Reset to default 12

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.

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

The accepted answer doesn't handle the case in which they have rejected camera permission but allowed mic permission (or vice versa). If you assume you have both, and proceed to ask for a camera and mic in your getUserMedia call, you'll get permission denied.

const devices = await navigator.mediaDevices.enumerateDevices()
const mics = devices.filter(device => device.kind == "audioinput")
const cams = devices.filter(device => device.kind == "videoinput")
const allowedMicPermission = mics.some(device => device.label != '')
const allowedWebcamPermission = cams.some(device => device.label != '')
const hasMic = mics.length > 0
const hasCam = cams.length > 0
// if no permission, assume we haven't asked them yet.
const constraints = !allowedMicPermission && !allowedWebcamPermission
   ? { audio: hasMic, video: hasCam}
   : { audio: allowedMicPermission && hasMic, video: allowedWebcamPermission && hasCam }
return navigator.mediaDevices.getUserMedia(constraints);

This is all to try to infer what permissions the user has given us. A much easier way is to ask the browser what permissions the user has given us, but that only works in Chrome right now, and doesn't seem likely to change.

发布评论

评论列表(0)

  1. 暂无评论