【问题标题】:Make video stream Optional in getUserMedia在 getUserMedia 中使视频流可选
【发布时间】:2014-08-14 12:50:38
【问题描述】:

在我的应用程序中,如果用户可以产生音频流,他就可以拨打电话。所以,我需要访问麦克风(音频流)。没有它,应用程序应该抛出一个错误。视频是可选的。所以,我打电话给navigator.getUserMedia 并把constraints 像这样:

{ audio: true, video: false }

当麦克风不存在时,它会引发错误,就像我需要的那样。但这样做的副作用是,如果用户也可以使用相机,视频不会出现在流中。

但是,如果我将audiovideo 都设置为true,当用户有麦克风但无法使用摄像头时(根据我的应用程序逻辑,这没问题),我会遇到错误

如何使视频流成为可选获取getUserMedia

【问题讨论】:

标签: javascript webrtc getusermedia


【解决方案1】:

现在存在另一种方式。您现在可以在致电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);

另一个答案也可以,但这可能更简洁一些。

请注意,这是使用enumerateDevices,它返回带有信息的设备列表。在致电getUserMedia 之前,出于隐私原因,返回的信息量有限,但它仍会显示用户是否拥有至少一个摄像头和/或至少一个麦克风,这就是我们所需要的。

【讨论】:

  • enumerateDevices 是否提示用户权限?
  • @Brackets 不,它没有。
  • 那么在调用getUserMedia之前说可以是不正确的
  • @Brackets 在getUserMedia 之前调用它仍然有效,但我已经更新了答案,以不暗示您获得完整的设备列表,以符合最新规范。谢谢
  • 酷,只是根据我的经验,它不起作用。只要确保它还没有改进,并且我的代码没有更新就可以了。
【解决方案2】:

我找到的一个解决方案是在启用视频和音频的情况下调用getUserMedia,如果调用失败(意味着他们没有摄像头或麦克风),那么你从失败回调中再次调用getUserMedia您仅提供对麦克风的请求访问权限。

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

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

当然,你可以随心所欲地处理成功和失败。

注意:如果没有摄像头,则不会出现请求初始摄像头馈送(将失败)的弹出窗口。因此,用户只会收到一个访问请求(这使得这个解决方案更受欢迎)。

【讨论】:

  • 完全像我在这种情况下能想象的唯一解决方案,但对我来说似乎有点粗糙......
  • 在约束中启用音频或视频的选项仅为布尔值。这很糟糕,但它是它的设计方式。好在他们不会得到两个弹出窗口(如果没有摄像头,视频请求永远不会发生)。
【解决方案3】:

接受的答案不处理他们拒绝相机权限但允许麦克风权限的情况(反之亦然)。如果您认为两者都有,并在您的 getUserMedia 通话中继续要求提供摄像头和麦克风,您将被拒绝。

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

这一切都是为了推断用户给了我们什么权限。一个更简单的方法是ask the browser what permissions the user has given us,但这目前仅适用于 Chrome,而且似乎不太可能改变。

【讨论】:

    猜你喜欢
    • 2018-10-13
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多