在 pageshow 上获取设备标签
Get device labels onpageshow
我正在编写一个网络应用程序,用户可以在其中使用他的相机(并选择要使用的相机)。问题是我希望用户可以在启用相机之前选择它。在当前代码中,当用户打开一个页面时,他会看到一个空的摄像头列表,当他启用摄像头流时,下拉列表中会填充摄像头名称。我希望在他打开该网页时填充下拉列表。
P.S。当我停止()相机时,它会禁用相机并只显示黑屏。为什么它是黑色而不是背景颜色?
CameraStreamView.cshtml
@using Api.Models
@{
ViewBag.Title = "Smart Vision";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="~/Content/Contact-Form-Clean.css">
</head>
<body onpageshow="Init()">
<div id="container">
<video id="video" style="display: block; margin: 0 auto; margin-top: 30px;" width="300" height="400" autoplay></video>
<button id="enableStream" style="display: block; margin: 0 auto; margin-top: 20px; height: 70px; width: 200px" onclick="start()">Enable camera</button>
<button id="disableStream" style="display: block; margin: 0 auto; margin-top: 20px; height: 70px; width: 200px" onclick="stop()">Disable camera</button>
<label for="videoSource">Video source: </label><select id="videoSource"></select>
</div>
<script src="~/Scripts/GetCameraFeed.js"></script>
</body>
</html>
GetCameraFeed.js
const videoSelect = document.querySelector('select#videoSource');
const selectors = [videoSelect];
function gotDevices(deviceInfos) {
// Handles being called several times to update labels. Preserve values.
const values = selectors.map(select => select.value);
selectors.forEach(select => {
while (select.firstChild) {
select.removeChild(select.firstChild);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label;
videoSelect.appendChild(option);
}
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
select.value = values[selectorIndex];
}
});
}
function Init() {
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
}
function gotStream(stream) {
window.stream = stream; // make stream available to console
video.srcObject = stream;
// Refresh button list in case labels have become available
return navigator.mediaDevices.enumerateDevices();
}
function handleError(error) {
console.log('navigator.getUserMedia error: ', error);
}
function start() {
const videoSource = videoSelect.value;
const constraints = {
video: { deviceId: videoSource ? { exact: videoSource } : undefined }
};
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).then(gotDevices).catch(handleError);
}
function stop() {
video.pause();
video.src = "";
stream.getTracks().forEach(track => track.stop());
console.log("Stopping stream");
}
你要的是explicitly disallowed, due to fingerprinting关注。有关用户设置的详细信息让网站可以在网络上唯一地识别他们,这是一个隐私问题。
一旦用户使用他们的相机和微信信任您的网站phone,此信息就被认为与分享有关。
工作组认为这是一个合理的权衡,原因如下:
- 大多数桌面用户只有一个摄像头或 none。
- 大多数 phone 用户有两个,但您可以使用 facingMode 约束来选择。
- 给定 1 和 2,对于大多数人来说,预先选择可以说是较差的用户体验。
我会考虑更改您的代码以在第一次请求默认摄像头,并让用户可以选择在事后更改它,如果他们需要的话。这是大多数 WebRTC 网站所做的。
请注意,这应该只是用户第一次访问您的网站时出现的问题。如果他们过去只授予过一次相机或微型 phone,您应该能够看到标签,至少在 Chrome.
中是这样
与 Chrome 不同,Firefox 不会隐式保留权限,因此您需要做更多的工作才能在重复访问时获取页面加载标签:
enumerateDevices
returns 每个设备一个 deviceId
,如果用户已授予(或将在此会话中授予)摄像头或微型[=41,则为您的网站保留=] 至少一次。您可以使用 cookie 或本地存储将 deviceId
与设备标签相关联。这也使人们在 Chrome.
中手动撤销权限后仍然存在
我正在编写一个网络应用程序,用户可以在其中使用他的相机(并选择要使用的相机)。问题是我希望用户可以在启用相机之前选择它。在当前代码中,当用户打开一个页面时,他会看到一个空的摄像头列表,当他启用摄像头流时,下拉列表中会填充摄像头名称。我希望在他打开该网页时填充下拉列表。
P.S。当我停止()相机时,它会禁用相机并只显示黑屏。为什么它是黑色而不是背景颜色?
CameraStreamView.cshtml
@using Api.Models
@{
ViewBag.Title = "Smart Vision";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="~/Content/Contact-Form-Clean.css">
</head>
<body onpageshow="Init()">
<div id="container">
<video id="video" style="display: block; margin: 0 auto; margin-top: 30px;" width="300" height="400" autoplay></video>
<button id="enableStream" style="display: block; margin: 0 auto; margin-top: 20px; height: 70px; width: 200px" onclick="start()">Enable camera</button>
<button id="disableStream" style="display: block; margin: 0 auto; margin-top: 20px; height: 70px; width: 200px" onclick="stop()">Disable camera</button>
<label for="videoSource">Video source: </label><select id="videoSource"></select>
</div>
<script src="~/Scripts/GetCameraFeed.js"></script>
</body>
</html>
GetCameraFeed.js
const videoSelect = document.querySelector('select#videoSource');
const selectors = [videoSelect];
function gotDevices(deviceInfos) {
// Handles being called several times to update labels. Preserve values.
const values = selectors.map(select => select.value);
selectors.forEach(select => {
while (select.firstChild) {
select.removeChild(select.firstChild);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label;
videoSelect.appendChild(option);
}
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
select.value = values[selectorIndex];
}
});
}
function Init() {
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
}
function gotStream(stream) {
window.stream = stream; // make stream available to console
video.srcObject = stream;
// Refresh button list in case labels have become available
return navigator.mediaDevices.enumerateDevices();
}
function handleError(error) {
console.log('navigator.getUserMedia error: ', error);
}
function start() {
const videoSource = videoSelect.value;
const constraints = {
video: { deviceId: videoSource ? { exact: videoSource } : undefined }
};
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).then(gotDevices).catch(handleError);
}
function stop() {
video.pause();
video.src = "";
stream.getTracks().forEach(track => track.stop());
console.log("Stopping stream");
}
你要的是explicitly disallowed, due to fingerprinting关注。有关用户设置的详细信息让网站可以在网络上唯一地识别他们,这是一个隐私问题。
一旦用户使用他们的相机和微信信任您的网站phone,此信息就被认为与分享有关。
工作组认为这是一个合理的权衡,原因如下:
- 大多数桌面用户只有一个摄像头或 none。
- 大多数 phone 用户有两个,但您可以使用 facingMode 约束来选择。
- 给定 1 和 2,对于大多数人来说,预先选择可以说是较差的用户体验。
我会考虑更改您的代码以在第一次请求默认摄像头,并让用户可以选择在事后更改它,如果他们需要的话。这是大多数 WebRTC 网站所做的。
请注意,这应该只是用户第一次访问您的网站时出现的问题。如果他们过去只授予过一次相机或微型 phone,您应该能够看到标签,至少在 Chrome.
中是这样与 Chrome 不同,Firefox 不会隐式保留权限,因此您需要做更多的工作才能在重复访问时获取页面加载标签:
enumerateDevices
returns 每个设备一个 deviceId
,如果用户已授予(或将在此会话中授予)摄像头或微型[=41,则为您的网站保留=] 至少一次。您可以使用 cookie 或本地存储将 deviceId
与设备标签相关联。这也使人们在 Chrome.