vdo.ninja/devices.html
2021-02-08 17:19:28 +01:00

185 lines
5.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
<link rel="stylesheet" href="./main.css?ver=11" />
<link rel="stylesheet" href="./devices.css?ver=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="utf8" />
</head>
<body>
<div id="header">
<a
id="logoname"
href="./"
style="text-decoration: none; color: white; margin: 2px"
>
<span data-translate="logo-header">
<font id="qos">O</font>BS.Ninja
</span>
</a>
</div>
<div id="devices">
<div class="notice">
Device IDs are bound to a combination of domain and browser. <br />If
you want to use electron-capture, open this URL on the electron-capture
app.
</div>
<div class="notice">
Check for browser and camera capabilities <a href="/supports">here</a>.
</div>
<div class="card">
<h1>🎤 Audio Inputs</h1>
<div id="audioInputs"></div>
</div>
<div class="card">
<h1>📹 Video Inputs</h1>
<div id="videoInputs"></div>
</div>
<div class="card">
<h1>🔉 Audio Outputs</h1>
<div id="audioOutputs"></div>
</div>
</div>
<div id="sharedDevices" style="display: none">
<span>Click to copy. Send this to your host:</span>
<span id="close" onclick="this.parentNode.style.display='none'">×</span>
<input id="devicesUrl" value="" />
</div>
<script>
const list = [];
const url = new URL(document.location.origin);
const audioInputDevices = [];
function isAudioInput(value) {
return value.kind === "audioinput";
}
function isAudioOutput(value) {
return value.kind === "audiooutput";
}
function isVideoInput(value) {
return value.kind === "videoinput";
}
function addDevice(element) {
const info = element.getElementsByClassName("device-id")[0];
const type = info.dataset.deviceType;
if (type === "audioinput") {
setAudioSearchParams(info);
}
if (type === "videoinput") {
setVideoSearchParams(info);
}
if (type === "audiooutput") {
return;
}
/*
Allows for multiple audio devices to be selected
Will be output as a comma separated string to &ad
*/
function setAudioSearchParams(info) {
// Device was already selected
if (info.parentNode.className === "device selected") {
// Remove device from list of selected devices
const index = audioInputDevices.indexOf(info.innerText);
if (index !== -1) {
audioInputDevices.splice(index, 1);
}
// Set the url param to the devices that are left
url.searchParams.set("ad", audioInputDevices.join(","));
element.className = "device";
// If no audio devices remained, just remove the param completely
if (audioInputDevices.length === 0) {
url.searchParams.delete("ad");
}
} else {
// Device is unselected
audioInputDevices.push(info.innerText);
url.searchParams.set("ad", audioInputDevices.join(","));
element.className = "device selected";
}
}
/*
Only allows for a single video device to be selected
*/
function setVideoSearchParams(info) {
// Device was already selected
if (info.parentNode.className === "device selected") {
info.parentNode.className = "device";
// Set the url param to the devices that are left
url.searchParams.set("vd", info.innerText);
element.className = "device";
// If no devices remained, just remove the param completely
if (audioInputDevices.length === 0) {
url.searchParams.delete("vd");
}
} else {
// Device is unselected
url.searchParams.set("vd", info.innerText);
element.className = "device selected";
}
}
// Update UI
showDeviceIdsPopup();
}
function showDeviceIdsPopup() {
document.getElementById("devicesUrl").value = decodeURIComponent(url);
document.getElementById("sharedDevices").style.display = "block";
}
function prettyPrint(json, element) {
let output = "<div class='prettyJson two-col'>";
let nestedObjs;
Object.entries(json)
.sort()
.forEach(([key, value]) => {
output += `
<div class='device' onclick='addDevice(this)'>
<span class='device-name'>${value.label}</span>
<span class='device-id' data-device-type='${value.kind}'>
${value.deviceId}
</span>
</div>`;
});
output += "</div>";
document.getElementById(element).innerHTML = output;
}
document.getElementById("devicesUrl").onclick = () => {
this.select();
document.execCommand("copy");
};
navigator.mediaDevices
.enumerateDevices()
.then((devices) => {
devices.forEach((device) => {
console.log(
`${device.kind}: ${device.label} id = ${device.deviceId}`
);
list.push(device);
});
prettyPrint(devices.filter(isAudioInput), "audioInputs");
prettyPrint(devices.filter(isAudioOutput), "audioOutputs");
prettyPrint(devices.filter(isVideoInput), "videoInputs");
})
.catch((err) => {
console.log(`${err.name}: ${err.message}`);
});
</script>
</body>
</html>