开发直播类的网页应用时,往往需要在开播前检测摄像头和麦克风是否正常,本文介绍一下浏览器如何获取到可用的摄像头和麦克风设备列表。
媒体接口
- mediaDevices.getUserMedia()
- mediaDevices.enumerateDevices()
需要用到上面两个媒体接口,getUserMedia()用于获取用户授权,enumerateDevices()用于获取可用设备列表。
代码实现
async function openUserMedia(e) {
// 1. 获取到设备授权
await navigator.mediaDevices.getUserMedia({video: true, audio: true});
// 2. 获取设备列表
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
devices.forEach(function(device) {
console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
});
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});
}
openUserMedia()
如果有一个或多个 MediaStream 处于活动状态或者获得了持久授权,将会输出类似下面的内容:
audioinput: 默认 - MacBook Air麦克风 (Built-in) id = default
audioinput: MacBook Air麦克风 (Built-in) id = 343f8207e0b9ebc3f9a98cde134d2818e64b2141b3bd087c58974c727bdca8c0
videoinput: FaceTime HD Camera id = 5ce24d4798ba56b830bc8adc4bcc7171dbe0fcca481f739606190492b21a1e21
videoinput: OBS Virtual Camera (m-de:vice) id = 495bd88129048451bf9b0c5c9342f298c55fdaedf91b3cfe0470a4cbc36e4d26
audiooutput: 默认 - MacBook Air扬声器 (Built-in) id = default
audiooutput: MSI PAG271P (HDMI) id = c20fbe0e2317c5f754d7e334acfeee6b39e7cd64fd37a3ed536142a7ec64f296
audiooutput: MacBook Air扬声器 (Built-in) id = cea14bbd0ab3b96fd22d84941c63aac1c6de60646744efa2d5bd20fa566b7600
可以看到有音频输入、音频输出、视频输入设备。
我们一般需要用户选择的就是音频输入、视频输入设备,可以写两个过滤方法,把获取到的设备展示在页面上。
分别获取摄像头、麦克风
function getCameras() {
return new Promise((resolve, reject) => {
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
resolve(devices.filter(d => d.kind === 'videoinput'))
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});
})
}
function getMicrophones() {
return new Promise((resolve, reject) => {
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
resolve(devices.filter(d => d.kind === 'audioinput'))
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});
})
}
// 3. 设备列表插入到页面
let cameraSelect = document.getElementById('camera-select');
let microphoneSelect = document.getElementById('microphone-select');
const updateDevice = async () => {
cameras = await getCameras();
cameras?.forEach(camera => {
const option = document.createElement('option');
option.value = camera.deviceId;
option.text = camera.label;
cameraSelect.appendChild(option);
});
microphones = await getMicrophones();
microphones?.forEach(microphone => {
const option = document.createElement('option');
option.value = microphone.deviceId;
option.text = microphone.label;
microphoneSelect.appendChild(option);
});
}
updateDevice();
需要在页面上准备两个下拉框:
<div class='select-wrapper'>
<div class='input-group mb-3'>
<label class='input-group-text' for='camera-select'>Camera</label>
<select class='form-select' id='camera-select'>
</select>
</div>
<div class='input-group mb-3'>
<label class='input-group-text' for='microphone-select'>Microphone</label>
<select class='form-select' id='microphone-select'>
</select>
</div>
</div>
这样就把系统可用的设备展示出来,方便用户选择。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。