如何为WebRTC(javascript)获取多个USB设备(摄像头)的唯一ID?
我正在Windows机器上开发,但目标平台是使用Chromium的Raspberry Pi(这是可选的,任何浏览器都可以)。我将多台摄像机(比如一打)连接到Pi,显然甚至必须使用USB集线器。在下面的代码中,每次插入摄像头或甚至在新的浏览器会话中,我都会看到不同的设备ID。我需要能够从特定的相机录制,录制视频或图像,打开/关闭相机等,但除非我能为每台相机获取某种唯一标识符,否则我无法做到这一点。如何为WebRTC(javascript)获取多个USB设备(摄像头)的唯一ID?
我也可以使用视频输入标识符来识别相机(例如/ dev/video0,/ dev/video1,.../dev/video n),但不知道如何在浏览器。
HTML:
<div id="container">
<h1>Test Page</h1>
<div id="List"></div>
<div class="select">
<p><label for="videoSource">Video source: </label><select id="videoSource"></select></p>
<p><label for="audioOutput">audioOutput source: </label><select id="audioOutput"></select></p>
<p><label for="audioInput">audioInput source: </label><select id="audioInput"></select></p>
</div>
<video muted autoplay></video>
</div>
的javascript:
<script>
var DeviceInfo = "";
var videoSelect = document.getElementById("videoSource");
var audioOutputSelect = document.getElementById("audioOutput");
var audioInputSelect = document.getElementById("audioInput");
navigator.mediaDevices.enumerateDevices()
.then(gotDevices)
.catch(errorCallback);
function gotDevices(deviceInfos) {
alert("deviceInfos.length: " + deviceInfos.length);
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
DeviceInfo += "<br>=================";
for (var key in deviceInfo) {
DeviceInfo += "<br>" + key + " => " + deviceInfo[key];
}
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);
}
}
document.getElementById("List").innerHTML = DeviceInfo;
}
function errorCallback(err) {
alert(err.name + ": " + err.message);
}
</script>
样本输出:
=================
toJSON => function toJSON() { [native code] }
deviceId => 68KeeWjqTyTiECj/vjwuwWSMNXraaUu/sz5CDSnbNg0=
kind => videoinput
label =>
groupId =>
=================
toJSON => function toJSON() { [native code] }
deviceId => wuJ0e0dyB7bUyO3L6MHV6CD8v+FQRRZ0V9oSS/IMebg=
kind => videoinput
label =>
groupId =>
=================
toJSON => function toJSON() { [native code] }
deviceId => BdtXeGDVhh2g68rfu4cOg9yZoS7WdgTNr8nXOThLfPU=
kind => videoinput
label =>
groupId =>
=================
toJSON => function toJSON() { [native code] }
deviceId => mAc/SogzkQKpq8O3Zto64+SlOwsg1kKdXJLxua5t328=
kind => audioinput
label =>
groupId =>
=================
toJSON => function toJSON() { [native code] }
deviceId => n1or62DRNYW0zC4yQVox75nQhBZb0BYR9C/VWB1GLkM=
kind => audioinput
label =>
groupId =>
=================
toJSON => function toJSON() { [native code] }
deviceId => 74K5qAhhroD8esqAYW+9P8jxs4yvdWnPQ1Ia8OYJZqc=
kind => audioinput
label =>
groupId =>
=================
toJSON => function toJSON() { [native code] }
deviceId => rHIqRAFL4ZcfTqJc214llo5XxeDLm+pTG/DoicpOryM=
kind => audioinput
label =>
groupId =>
还要注意标签是空白(在Windows /火狐),但在Raspbian /铬我做获取标签。不幸的是,它们并不是唯一的(例如,USB2.0 Camera(1871:0142))如果我能以某种方式使用这些标签......这个page表示标签“返回一个DOMString,它是描述此设备的标签(例如”External USB网络摄像机“)。只有在活动MediaStream使用或授予永久权限时才可用。”我不知道什么或如何做“持久性权限”。
任何帮助表示赞赏。我愿意使用不同的技术,即fswebcam以某种方式链接到浏览器(自定义URL)或PHP或其他任何方式。
浏览器维护同一个deviceid可能是安全问题,网站可以通过使用deviceid(如浏览器cookie)跟踪用户。
您可以从deviceInfo标签或MediaTrack标签获得设备供应商名称,如果它们全部来自同一供应商,则请戳here。或挖chromium devices并构建您的自定义版本。
deviceId
就是那个id。由于隐私原因,该页面的来源是独一无二的,但在第一次将相机或麦克风许可授予来自原始页面的页面之后,它将在cookie之类的浏览会话中持续存在。之后,它应该持续到用户清除他们的cookies。
换句话说,如果用户过去曾授予getUserMedia
访问您的页面的权限,无论是昨天还是一年前,那么您现在得到的id将与他们当时的内容相匹配,在来源网页中提供此后用户还没有清除他们的Cookie。
label
字段也是空白的,直到您完成此操作,再次出于隐私原因。
拔下插头和重新插入设备应该没有关系。 ID应该仍然可用。
Thanx @jib但是ID确实发生了变化,它们如何被重用? Pi可能会重新启动,然后我们必须重新编程以使用新的ID。 – Chiwda
@Chiwda我会隔离问题。 ID应该存储在类似cookie的存储中。它是否适用于常规桌面浏览器?如果是这样,那么你的覆盆子pi版本有一个错误。它有存储吗?最坏的情况下,使用其他人所建议的标签(他们还首先要求口香糖成功,就像我提到的那样)。 – jib
他们(ID)在Windows 10和Pi上的工作方式相同。是的,我知道他们需要一个成功的getUsermedia(),但是根据定义,每次调用它时都会重新创建它们。 – Chiwda