遍历音视频设备
正如第 4 章中所述,进行一对一通信之前,需要对设备进行检测,看看主机上都支持哪些设备。在浏览器上遍历音视频设备特别简单,调用 enumerateDevices()
接口即可,其原型参见代码 5.1。
navigater.mediaDevices.enumerateDevices();
interface MediaDeviceInfo {
readonly attribute DOMString deviceId;
readonly attribute MediaDeviceKind kind;
readonly attribute DOMString label;
readonly attribute DOMString groupId;
}
enum MediaDeviceKind {
"audioinput",
"audiooutput",
"videoinput"
}
下面详细介绍一下 MediaDeviceInfo
结构。从上面的代码中可以看到,MediaDeviceInfo
包括 4 个属性,分别是 deviceId
、kind
、label
和 groupId
。
deviceId
表示每个设备的唯一编号,通过该编号可以从 WebRTC
的音视频设备管理中找到该设备。
kind
表示设备的种类。音视频设备包括三种类型:音频输入设备、音频输出设备以及视频输入设备。音频的输入设备和输出设备是两种不同类型的设备。而对于视频设备来说,它只有输入设备,视频的输出则是由显示器完成的。由于显示器是默认设备,所以不需要通过音视频设备管理器进行管理。
label
是设备的名字。该名字是便于人们记忆的名字,不像 deviceId
那样是一串毫无规律的字符串。
groudId
表示组 Id。如果两个设备是在同一个硬件上,则它们属于同一组,因此它们的 groupId
是一致的,例如音频的输入与输出设备就是集成到一起的。
现在 enumerateDevices()
接口的作用及其参数含义你已经清楚了,下面我们来了解一下如何调用 enumerateDevices()
接口。在浏览器上使用 JavaScript
调用 enumerate Devices()
时,与我们通常使用 C/C++
等语言调用接口的方式有些不同,JavaScript
采用 Promise
方式调用 enumerateDevices()
接口。关于 Promise
的内容在这里就不做进一步讲解了,如果你对其不熟悉,可以自行在网上查找相关内容。下面看一下使用 enumerate Devices()
接口的具体例子,如代码 5.3 所示。
// 如果遍历设备失败,则回调该函数
function handleError(error) {
console.log('err:', error);
}
// 如果得到音视频设备,则回调该函数
function gotDevices(deviceInfos) {
// 遍历所有设备信息
for (let i = 0; i !== deviceInfos.length; ++i) {
// 取每个设备信息
const deviceInfo = deviceInfos[i];
// ...
}
// ...
}
// 遍历所有音视频设备
navigator.mediaDevices.enumerateDevices()
.then(gotDevices)
.catch(handleError);
当将上面的代码片段生成 js
文件放到浏览器下执行时,浏览器首先从第 19 行处的代码开始执行,即调用 enumerateDevices()
接口获得主机上的所有音视频设备。如果 enumerate Devices()
函数执行成功,则会回调 gotDevices()
方法,该方法的输入参数 deviceInfos
中存放的就是通过 enumerateDevices()
获得的所有音视频设备的信息。此时,可以通过一个 for
循环来遍历每一项设备信息。如果 enumerateDevices()
函数执行失败,则回调 handleError()
函数,此时可以通过该函数将错误信息打印出来。
这里需要注意的是,基于安全方面的原因,浏览器有可能不允许调用 enumerateDevices()
函数,此时需要手工将浏览器的安全访问设置为允许。另外,测试时最好使用 Chrome
浏览器,因为它对 WebRTC
的支持最全。