现代浏览器让您可以选择输入和输出设备,包括摄像头、麦克风和扬声器。
例如:
- 在手机上,选择前置或后置摄像头。
- 在笔记本电脑上,选择内部扬声器或通过蓝牙连接的扬声器。
- 进行视频聊天时,可以选择内部或外部麦克风或摄像头。
所有此功能都通过 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) {
// ...
}
弃旗
enumerateDevices()
方法是在 Chrome 中“无标志”的,而对于 MediaDevices.getUserMedia()
,您仍需在 chrome://flags 中启用实验性网络平台功能或使用以下命令行标志:
--enable-blink-features=GetUserMedia
同样,对于 setSinkId()
:启用实验性 Web 平台功能或使用标志:
--enable-blink-features=AudioOutputDevices
下文详细介绍了浏览器支持。
未来展望
我们提议的 ondevicechange
事件处理脚本就行了:当可用设备集发生变化时会触发 devicechange
事件,并且您可以在处理程序中调用 enumerateDevices()
来获取新的设备列表。尚未在任何浏览器中实现此功能。
Screen Capture 草稿是对 Media Capture API 的扩展,它提出了一个 MediaDevices.getDisplayMedia()
方法,该方法可让用户的屏幕区域被用作媒体流的来源。此外,还有针对 getSupportedConstraints()
的 MediaDevices
扩展提案,其中提供了有关可用于 getUserMedia()
调用的限制条件的信息:浏览器支持的音频和视频功能。
样本歌曲
- getUserMedia()
- enumerateDevices():
- MediaDevices 填充码
了解详情
- Mozilla 开发者网络:媒体设备
- 实现状态
- 媒体捕获和流编辑器的草稿:MediaDevices
- Audio Output Devices API