从您的 Web 应用中选择摄像头、麦克风和扬声器

借助新型浏览器,您可以选择输入和输出设备,包括摄像头、麦克风和扬声器。

例如:

  • 在手机上,选择前置或后置摄像头。
  • 在笔记本电脑上,选择内部扬声器或通过蓝牙连接的扬声器。
  • 如需进行视频聊天,请选择内置或外接麦克风或摄像头。

所有这些功能均由 navigator.mediaDevices 返回的 MediaDevices 对象公开。

MediaDevices 有两种方法,这两种方法都已在桌面版和 Android 版 Chrome 47 中实现:enumerateDevices()getUserMedia()

选择音频输出设备。

enumerateDevices()

返回一个 Promise,用于访问可用设备的 MediaDeviceInfo 对象数组。

该方法与 MediaStreamTrack.getSources() 类似,但与该方法(仅在 Chrome 中实现)不同,它符合标准,并包含音频输出设备。您可以通过以下演示来试用此功能。

以下是某个演示中经过略微简化的代码:

navigator.mediaDevices.enumerateDevices()
    .then(gotDevices)
    .catch(errorCallback);
...
function gotDevices(deviceInfos) {

    ...

    for (var i = 0; i !== deviceInfos.length; ++i) {
    var deviceInfo = deviceInfos[i];
    var option = document.createElement('option');
    option.value = deviceInfo.deviceId;
    if (deviceInfo.kind === 'audioinput') {
        option.text = deviceInfo.label ||
        'Microphone ' + (audioInputSelect.length + 1);
        audioInputSelect.appendChild(option);
    } else if (deviceInfo.kind === 'audiooutput') {
        option.text = deviceInfo.label || 'Speaker ' +
        (audioOutputSelect.length + 1);
        audioOutputSelect.appendChild(option);
    } else if (deviceInfo.kind === 'videoinput') {
        option.text = deviceInfo.label || 'Camera ' +
        (videoSelect.length + 1);
        videoSelect.appendChild(option);
    }

    ...

}

使用 enumerateDevices() 检索可用设备的 ID 后,您可以使用 setSinkId()(在 Audio Output Devices API 中定义)更改视频或音频元素的音频输出目的地:

element.setSinkId(sinkId)
    .then(function() {
    console.log('Audio output device attached: ' + sinkId);
    })
    .catch(function(error) {
    // ...
    });

此方法用于设置元素的音频输出设备。调用 setSinkId() 后,您可以使用 sinkId 属性获取元素的当前输出音频设备的 ID。

getUserMedia()

这会替换 navigator.getUserMedia(),但返回的不是回调,而是用于访问 MediaStream 的 Promise。我们建议开发者使用 MediaDevices.getUserMedia(),但没有计划移除 navigator.getUserMedia()它仍然是规范的一部分

WebRTC 示例网站提供了相关演示。

以下是演示中的代码段:

navigator.mediaDevices.getUserMedia(constraints)
    .then(function(stream) {
    var videoTracks = stream.getVideoTracks();
    console.log('Got stream with constraints:', constraints);
    console.log('Using video device: ' + videoTracks[0].label);
    stream.onended = function() {
        console.log('Stream ended');
    };
    window.stream = stream; // make variable available to console
    video.srcObject = stream;
    })
    .catch(function(error) {
    // ...
    }

免除标志

在 Chrome 中,enumerateDevices() 方法是“无标志”的,但对于 MediaDevices.getUserMedia(),您仍然需要在 chrome://flags 中启用实验性 Web 平台功能,或使用以下命令行标志:

--enable-blink-features=GetUserMedia

对于 setSinkId(),同样:启用实验性 Web 平台功能或使用标志:

--enable-blink-features=AudioOutputDevices

如需详细了解浏览器支持,请参阅下文。

未来展望

建议的 ondevicechange 事件处理脚本会按预期执行操作:当可用设备集发生变化时,系统会触发 devicechange 事件,并且您可以在处理脚本中调用 enumerateDevices() 来获取新的设备列表。目前还没有任何浏览器实现此功能。

屏幕截图草稿是 Media Capture API 的扩展,它提出了一种 MediaDevices.getDisplayMedia() 方法,可让用户显示屏的区域用作媒体流的来源。此外,还有一个针对 getSupportedConstraints()MediaDevices 扩展提案,其中提供了有关可用于 getUserMedia() 调用的约束条件的信息:浏览器支持的音频和视频功能。

演示

了解详情