fixed bug with pie / socket server

This commit is contained in:
Steve Seguin 2021-06-23 01:40:20 -04:00 committed by GitHub
parent 2bbda7fa19
commit f57df65c4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 54502 additions and 45 deletions

25
examples/changepass.html Normal file
View File

@ -0,0 +1,25 @@
<html><body><script>
var generateHash = function (str, length=false){
var buffer = new TextEncoder("utf-8").encode(str);
return crypto.subtle.digest("SHA-256", buffer).then(
function (hash) {
hash = new Uint8Array(hash);
if (length){
hash = hash.slice(0, parseInt(parseInt(length)/2));
}
hash = toHexString(hash);
return hash;
}
);
};
function toHexString(byteArray){
return Array.prototype.map.call(byteArray, function(byte){
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('');
}
var password = prompt("Please enter the password");
generateHash(password + location.hostname, 4).then(function(hash) { // million to one error.
alert("hash value: "+hash)
});
</script></body></html>

331
examples/dual.html Normal file
View File

@ -0,0 +1,331 @@
<html>
<head><title>Dual Input</title>
<style>
body{
padding:0;
margin:0;
}
iframe {
border:0;
margin:0;
padding:0;
display:block;
margin:0px;
min-height: 100px;
min-width: 100px;
max-height: 95%;
max-width: 99%%;
float: left;
position: fixed;
}
#viewlink {
width:400px;
}
input{
padding:5px;
margin:5px;
}
button{
padding:5px;
margin:5px;
position:relative;
}
.menu {
z-index: 10;
float:right;
right: 20px;
color: #fff;
}
.close {
background-color: #d33;
color: #fff;
}
.reload {
background-color: #0a0;
color: #fff;
}
.popup {
z-index: 9;
background-color: #f1f1f1;
border: 1px solid #d3d3d3;
text-align: center;
min-height: 100px;
min-width: 100px;
max-height: 95%;
max-width: 99%;
scale: 0.5;
}
.popup {
position: absolute;
/*resize: both; !*enable this to css resize*! */
overflow: auto;
}
.popup-header {
cursor: move;
background-color: #2196f3;
}
.popup .resizer-right {
width: 5px;
height: 100%;
background: transparent;
position: absolute;
right: 0;
bottom: 0;
cursor: e-resize;
}
.popup .resizer-bottom {
width: 100%;
height: 5px;
background: transparent;
position: absolute;
right: 0;
bottom: 0;
cursor: n-resize;
}
.popup .resizer-both {
width: 5px;
height: 5px;
background: transparent;
z-index: 10;
position: absolute;
right: 0;
bottom: 0;
cursor: nw-resize;
}
/*NOSELECT*/
.popup * {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
</style>
</head>
<body>
<input placeholder="Enter an OBS.Ninja Room Link" id="viewlink" />
<button onclick="loadIframe();">Load URL</button>You can drag and resize the generated windows; multiple can be created.
<div id="container"></div>
<script>
var currentZIndex = 100;
function initDragElement(popup){
var pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
var elmnt = null;
var header = getHeader(popup);
var iframe = getIFrame(popup);
popup.onmousedown = function() {
this.style.zIndex = "" + ++currentZIndex;
};
if (header) {
header.parentPopup = popup;
header.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
elmnt = this.parentPopup;
elmnt.style.zIndex = "" + ++currentZIndex;
e = e || window.event;
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
if (!elmnt) {
return;
}
e = e || window.event;
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = elmnt.offsetTop - pos2 + "px";
elmnt.style.left = elmnt.offsetLeft - pos1 + "px";
iframe.style.top = elmnt.offsetTop - pos2 + "px";
iframe.style.left = elmnt.offsetLeft - pos1 + "px";
}
function closeDragElement() {
/* stop moving when mouse button is released:*/
document.onmouseup = null;
document.onmousemove = null;
}
function getHeader(element) {
var headerItems = element.getElementsByClassName("popup-header");
if (headerItems.length === 1) {
return headerItems[0];
}
return null;
}
function getIFrame(element) {
var headerItems = element.getElementsByTagName("iframe");
if (headerItems.length === 1) {
return headerItems[0];
}
return null;
}
}
function initResizeElement(p) {
var iframe = getIFrame(p);
var element = null;
var startX, startY, startWidth, startHeight;
var right = document.createElement("div");
right.className = "resizer-right";
p.appendChild(right);
right.addEventListener("mousedown", initDrag, false);
right.parentPopup = p;
var bottom = document.createElement("div");
bottom.className = "resizer-bottom";
p.appendChild(bottom);
bottom.addEventListener("mousedown", initDrag, false);
bottom.parentPopup = p;
var both = document.createElement("div");
both.className = "resizer-both";
p.appendChild(both);
both.addEventListener("mousedown", initDrag, false);
both.parentPopup = p;
function initDrag(e) {
element = this.parentPopup;
startX = e.clientX;
startY = e.clientY;
startWidth = parseInt(
document.defaultView.getComputedStyle(element).width,
10
);
startHeight = parseInt(
document.defaultView.getComputedStyle(element).height,
10
);
document.documentElement.addEventListener("mousemove", doDrag, false);
document.documentElement.addEventListener("mouseup", stopDrag, false);
document.documentElement.addEventListener("click", stopDrag, false)
}
function doDrag(e) {
if (e.buttons==0){
stopDrag(e);
return false;
}
element.style.width = startWidth + e.clientX - startX + "px";
element.style.height = startHeight + e.clientY - startY + "px";
iframe.style.width = startWidth + e.clientX - startX + "px";
iframe.style.height = startHeight + e.clientY - startY + "px";
}
function stopDrag(e) {
document.documentElement.removeEventListener("mousemove", doDrag, false);
document.documentElement.removeEventListener("mouseup", stopDrag, false);
}
function getIFrame(element) {
var headerItems = element.getElementsByTagName("iframe");
if (headerItems.length === 1) {
return headerItems[0];
}
return null;
}
}
function loadIframe(){
var iframeContainer = document.createElement("div");
iframeContainer.className="popup";
iframeContainer.style.zIndex = "" + ++currentZIndex;
iframeContainer.style.width="325px";
iframeContainer.style.height="420px";
var button = document.createElement("button");
button.innerHTML = "Move";
button.className = "popup-header menu";
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Close";
button.className = "menu close";
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');iframe.parentNode.parentNode.removeChild(iframeContainer);}
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Reload";
button.className = "menu reload";
button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');}
iframeContainer.appendChild(button);
var iframe = document.createElement("iframe");
iframe.allow="autoplay";
iframe.src = document.getElementById("viewlink").value || "https://obs.ninja";
iframe.style.width="325px";
iframe.style.height="420px";
iframeContainer.appendChild(iframe);
document.getElementById("container").appendChild(iframeContainer);
initDragElement(iframeContainer);
initResizeElement(iframeContainer);
}
</script>
</body>
</html>

3
examples/mini.css Normal file
View File

@ -0,0 +1,3 @@
.tile {
max-width:200px !important;
}

172
examples/status.html Normal file
View File

@ -0,0 +1,172 @@
<html>
<head>
<meta charset="utf8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>OBSN Chat Overlay</title>
<style>
@font-face {
font-family: 'Cousine';
src: url('fonts/Cousine-Bold.ttf') format('truetype');
}
body {
margin:0;
padding:0 10px;
height:100%;
border: 0;
display: flex;
flex-direction: column-reverse;
position:absolute;
bottom:0;
overflow:hidden;
max-width:100%;
}
ul {
margin:0;
background-color: #0000;
color: white;
font-family: Cousine, monospace;
font-size: 3.2em;
line-height: 1.1em;
letter-spacing: 0.0em;
text-transform: uppercase;
padding: 0em;
text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1);
max-width:100%;
}
ul li {
background-color: black;
padding: 8px 8px 0px 8px;
margin:0;
word-wrap: break-word;
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
hyphens: auto;
max-width:100%;
}
a {
color:white;
font-size:1.2em;
text-transform: none;
word-wrap: break-word;
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
hyphens: auto;
}
</style>
<script>
(function (w) {
w.URLSearchParams =
w.URLSearchParams ||
function (searchString) {
var self = this;
self.searchString = searchString;
self.get = function (name) {
var results = new RegExp("[\?&]" + name + "=([^&#]*)").exec(
self.searchString
);
if (results == null) {
return null;
} else {
return decodeURI(results[1]) || 0;
}
};
};
})(window);
var urlParams = new URLSearchParams(window.location.search);
function loadIframe() {
var iframe = document.createElement("iframe");
var view= "";
if (urlParams.has("view")) {
view = "&view="+(urlParams.get("view") || "");
}
var room="";
if (urlParams.has("room")) {
room = "&room="+urlParams.get("room");
}
var password="";
if (urlParams.has("password")) {
password = "&password="+urlParams.get("password");
}
iframe.allow = "autoplay";
var srcString = "./?novideo&noaudio&label=chatOverlay&scene"+room+view+password;
iframe.src = srcString;
iframe.style.width="0";
iframe.style.height="0";
iframe.style.border="0";
document.body.appendChild(iframe);
//////////// LISTEN FOR EVENTS
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
/// If you have a routing system setup, you could have just one global listener for all iframes instead.
eventer(messageEvent, function (e) {
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
console.log(e);
if ("gotChat" in e.data){
logData(e.data.gotChat.label,e.data.gotChat.msg);
}
});
}
function printValues(obj) {
var out = "";
for (var key in obj) {
if (typeof obj[key] === "object") {
out += "<br />";
out += printValues(obj[key]);
} else {
if (key.startsWith("_")) {
} else {
out += "<b>" + key + "</b>: " + obj[key] + "<br />";
}
}
}
return out;
}
function logData(type, data) {
var log = document.body.getElementsByTagName("ul")[0];
var entry = document.createElement('li');
if (type){
type = "<i>"+type+"</i>";
}
entry.innerHTML = type + data;
//setTimeout(function(entry){ // hide message after 60 seconds
// entry.innerHTML="";
// entry.remove();
// },60000,entry);
log.appendChild(entry);
}
</script>
</head>
<body onload="loadIframe();">
<ul></ul>
</body>
</html>

133
examples/webhid.html Normal file
View File

@ -0,0 +1,133 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>WebHID Demo</title>
<style>
body {
text-align: center;
}
.button {
background-color: black;
border: none;
color: #00FF00;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
margin: 4px 2px;
cursor: pointer;
font-size: 24px;
}
#connected {
font-size: 24px;
max-height:700px;
overflow-y:scroll
}
#disconnectButton {
font-size: 24px;
}
</style>
</head>
<body>
<h1>STREAMDECK DEMO</h1>
<img src="./media/streamdeck.png" /><br />
<input class="button" type="button" id="connectButton" value="Connect" />
<input class="button" type="button" id="disconnectButton" style="display:none" value="Disconnect" />
<div id="connected" style>
</div>
<script>
const connectButton = document.getElementById("connectButton");
const disconnectButton = document.getElementById("disconnectButton");
const connect = document.getElementById("connect");
const deviceButtonPressed = document.getElementById("deviceButtonPressed");
var lastState = false;
//productId: 0x0060,
//class: models_1.StreamDeckOriginal,
//productId: 0x0063,
//class: models_1.StreamDeckMini,
//productId: 0x006c,
//class: models_1.StreamDeckXL,
//productId: 0x006d,
//class: models_1.StreamDeckOriginalV2,
document.addEventListener('DOMContentLoaded', async () => {
let devices = await navigator.hid.getDevices();
devices.forEach(device => {
console.log(`HID: ${device.productName}`);
});
});
function handleInputReport(e) {
console.log(e.device.productName + ": got input report " + e.reportId);
console.log(new Uint8Array(e.data.buffer));
var data = new Uint8Array(e.data.buffer);
if (lastState!==false){
for (var i=0;i<data.length;i++){
if (parseInt(data[i])!=data[i]){continue;}
if (lastState[i]!==data[i]){
if (data[i]){
document.getElementById("connected").innerHTML = "<br />Button "+(i+1)+" Pressed"+document.getElementById("connected").innerHTML;
} else {
document.getElementById("connected").innerHTML = "<br />Button "+(i+1)+" Released"+document.getElementById("connected").innerHTML;
}
} else {
if (data[i]){
document.getElementById("connected").innerHTML = "<br />Button "+(i+1)+" Pressed"+document.getElementById("connected").innerHTML;
}
}
}
}
lastState = data;
}
let device;
connectButton.onclick = async () => {
navigator.hid.requestDevice({
filters: [{ vendorId: 0x0fd9}] // elgato?
}).then((devices)=>{
console.log(devices);
device = devices[0];
console.log(`HID connected: ${device.productName}`);
document.getElementById("connected").innerHTML = "<br />Connected" +document.getElementById("connected").innerHTML;
document.getElementById("disconnectButton").style.display = "inline-block";
device.addEventListener("inputreport", handleInputReport);
//device.sendReport(outputReportId, outputReport).then(() => {
// console.log("Sent output report " + outputReportId);
//});
if (!device.opened){
device.open().then(()=>{
window.addEventListener("onbeforeunload", async () => {
await device.close();
});
}).catch(function(err){console.error(err);});
}
}).catch(function(err){console.error(err);});
};
disconnectButton.onclick = async () => {
await device.close();
//connected.style.display = "none";
//connectButton.style.display = "initial";
disconnectButton.style.display = "none";
};
</script>
</body>
</html>

182
examples/zoom.html Normal file
View File

@ -0,0 +1,182 @@
<html>
<head><style>
span{margin:10px 0 0 0;display:block;}
body {
background-color:#cdf;
padding:0;
width;100%;height:100%
}
input{padding:5px;}
button {margin:10px 3px;}
#stream{
display:block;
}
</style></head>
<body id="main" style="margin:5%;"
<meta charset="utf-8"/>
<video id="video" autoplay="true" muted="true" playsinline style='height:420px;background-color:black;display:block;margin:0 0 10px 0;'></video>
<div id="devices">
<div class="select">
<label for="videoSource">Video source: </label><select id="videoSource"></select>
</div>
<div class="select">
<label for="audioSource">Audio source: </label><select id="audioSource"></select>
</div>
</div>
<button onclick="fullwindow()">FULL WINDOW</button>
<script>
window.onerror = function backupErr(errorMsg, url=false, lineNumber=false) {
console.error(errorMsg);
console.error(lineNumber);
console.error("Unhandeled Error occured"); //or any message
return false;
};
function fullwindow(){
videoElement.style.width="100%";
videoElement.style.padding= "0";
videoElement.style.margin="0";
videoElement.style.height="100%";
videoElement.style.zIndex="5";
videoElement.style.position = "absolute";
videoElement.style.top="0px";
videoElement.style.left="0px";
document.getElementById("main").style.overflow = "hidden";
videoElement.style.overflow = "hidden"
document.getElementById("main").style.backgroundColor="#000";
videoElement.style.cursor="none";
document.getElementById("main").style.cursor="none";
}
var videoElement = document.getElementById("video");
var gotDev = false;
async function gotDevices() {
if (gotDev){return;}
gotDev=true;
await navigator.mediaDevices.getUserMedia({audio:true, video:true}); // is needed to ask for permissinos.
navigator.mediaDevices.enumerateDevices().then((deviceInfos)=>{
for (let i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement("option");
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === "audioinput") {
option.text = deviceInfo.label || "microphone " + (audioSelect.length + 1);
audioSelect.appendChild(option);
if (option.text.startsWith("CABLE")){
option.selected =true;
}
} else if (deviceInfo.kind === "videoinput") {
option.text = deviceInfo.label || "camera " + (videoSelect.length + 1);
if (option.text.startsWith("NewTek")){
continue;
}
videoSelect.appendChild(option);
if (option.text.startsWith("OBS")){
option.selected =true;
}
}
}
getStream();
});
}
function getStream() {
if (window.stream) {
window.stream.getTracks().forEach(function (track) {
track.stop();
log("TRack stopping");
});
}
const constraints = {
audio: {
deviceId: { exact: audioSelect.value },
echoCancellation : false,
autoGainControl : false,
noiseSuppression : false
},
video: {
deviceId: { exact: videoSelect.value },
width: { min: 1280, ideal: 1920, max: 1920 },
height: { min: 720, ideal: 1080, max: 1080 }
}
};
return navigator.mediaDevices.getUserMedia(constraints)
.then(gotStream)
.catch(console.error);
}
function gotStream(stream) {
if (window.stream) {
window.stream = stream; // make stream available to console
videoElement.srcObject = stream;
var senders = session.pc.getSenders();
videoElement.srcObject.getVideoTracks().forEach((track)=>{
var added = false;
senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams?
if (sender.track) {
if (sender.track && sender.track.kind == "video") {
sender.replaceTrack(track); // replace may not be supported by all browsers. eek.
track.enabled = notCensored;
added = true;
}
}
});
if (added==false){
session.pc.addTrack(track);
log("ADDED NOT REPLACED?");
}
});
videoElement.srcObject.getAudioTracks().forEach((track)=>{
var added = false;
senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams?
if (sender.track) {
if (sender.track && sender.track.kind == "audio") {
sender.replaceTrack(track); // replace may not be supported by all browsers. eek.
track.enabled = notCensored;
added = true;
}
}
});
if (added==false){
session.pc.addTrack(track);
log("ADDED NOT REPLACED?");
}
});
} else {
window.stream = stream; // make stream available to console
videoElement.srcObject = stream;
}
}
var audioSelect = document.querySelector("select#audioSource");
var videoSelect = document.querySelector("select#videoSource");
audioSelect.onchange = getStream;
videoSelect.onchange = getStream;
gotDevices();
</script>
</body>
</html>

View File

@ -68,7 +68,7 @@
<link itemprop="url" href="./media/obsNinja_logo_full.png" />
</span>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=33"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=207"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=208"></script>
<input id="zoomSlider" type="range" style="display: none;" />
<div id="header">
@ -495,6 +495,8 @@
</option>
</select>
</span>
<br />
<span data-translate="application-audio-capture">For application-specific audio capture, <a href='https://docs.vdo.ninja/audio' style='color: #007AC8;'>see here</a></span>
</div>
<div class="outer close">
<div class="inner">
@ -1338,7 +1340,7 @@
<button data-action-type="recorder-local" title="Start Recording this remote stream to this local drive. *experimental*'" onclick="recordLocalVideoToggle();">
<i class="las la-circle"></i>
<span data-translate="record-local"> Record</span>
</button>
</button>
<span>
<button style="width:34px;" data-action-type="order-down" title="Shift this Video Down in Order" onclick="changeOrderDirector(-1);">

134
lib.js
View File

@ -397,7 +397,11 @@ function warnUser(message, timeout=false){
}
zindex = 31 + document.querySelectorAll('.alertModal').length;
message = message.replace(/\n/g,"<br />");
try{
message = message.replace(/\n/g,"<br />");
} catch(e){
errorlog(message);
}
modalTemplate =
`<div class="alertModal" id="alertModal" style="z-index:${zindex + 2}">
<div class="alertModalInner">
@ -2437,6 +2441,14 @@ function updateUserList(){
},200);
}
function resetCanvas(){
session.streamSrc.getVideoTracks().forEach((track) => {
session.canvasSource.width = track.getSettings().width || 1280;
session.canvasSource.height = track.getSettings().height || 720;
});
}
var LaunchTFWorkerCallback = false;
function TFLiteWorker(){
if (session.tfliteModule==false){
@ -2471,6 +2483,8 @@ function TFLiteWorker(){
function process(){
if (session.tfliteModule.activelyProcessing){return;}
session.tfliteModule.activelyProcessing=true;
try{
segmentationMaskCtx.drawImage(
session.canvasSource,
@ -3441,7 +3455,7 @@ function directorSendMessage(ele) {
inputField.style.margin = "5px 10px 5px 10px";
inputField.style.padding = "5px";
target.appendChild(inputField);
var sendButton = document.createElement("button");
sendButton.innerHTML = "<i class='las la-reply'></i> send message ";
@ -3501,6 +3515,7 @@ function directorSendMessage(ele) {
target.appendChild(closeButton);
target.appendChild(sendButton);
target.appendChild(overlayMsg);
target.appendChild(inputField);
ele.parentNode.appendChild(target);
inputField.focus();
inputField.select();
@ -4661,7 +4676,7 @@ session.publishIFrame = function(iframeURL){
container.id = "container";
var iframe = document.createElement("iframe");
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;transparency;";
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;";
iframe.src = session.iframeSrc;
iframe.id = "iframe_source"
session.iframeEle = iframe;
@ -7706,17 +7721,17 @@ function resetupAudioOut() {
function obfuscateURL(input) {
if (input.startsWith("https://obs.ninja/")) {
input = input.replace('https://obs.ninja/', '');
input = input.replace('https://obs.ninja/', 'obs.ninja/');
} else if (input.startsWith("http://obs.ninja/")) {
input = input.replace('http://obs.ninja/', '');
input = input.replace('http://obs.ninja/', 'obs.ninja/');
} else if (input.startsWith("obs.ninja/")) {
input = input.replace('obs.ninja/', '');
input = input.replace('obs.ninja/', 'obs.ninja/');
} else if (input.startsWith("https://vdo.ninja/")) {
input = input.replace('https://vdo.ninja/', '');
input = input.replace('https://vdo.ninja/', 'vdo.ninja/');
} else if (input.startsWith("http://vdo.ninja/")) {
input = input.replace('http://vdo.ninja/', '');
input = input.replace('http://vdo.ninja/', 'vdo.ninja/');
} else if (input.startsWith("vdo.ninja/")) {
input = input.replace('vdo.ninja/', '');
input = input.replace('vdo.ninja/', 'vdo.ninja/');
}
input = input.replace('&view=', '&v=');
@ -7902,25 +7917,66 @@ if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // this ena
window.navigator.mediaDevices.getDisplayMedia = () => {
return new Promise(async (resolve, reject) => {
try {
if (session.autostart){
var sscid = 0
if (typeof session.screenshare === "number"){
sscid = session.screenshare-1;
if (sscid<0){sscid=0;}
if (parseInt(session.screenshare)+"" === session.screenshare){
var sscid = parseInt(session.screenshare)-1;
if (sscid<0){sscid=0;}
const sources = await desktopCapturer.getSources({ types: ['screen'] });
const stream = await window.navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sources[sscid].id,
maxFrameRate: 60
}
}
});
resolve(stream);
} else if (session.screenshare!==true){
var sscid=null;
const sources = await desktopCapturer.getSources({ types: ['window'] });
for (var i=0; i<sources.length;i++){
if (sources[i].name.startsWith(session.screenshare)){ // check if anythign starts with
sscid=i;
break;
}
}
if (sscid===null){
sscid = 0; // grab first window if nothing.
for (var i=0; i<sources.length;i++){
if (sources[i].name.includes(session.screenshare)){ // check if something includes the string; fallback
sscid=i;
break;
}
}
}
const stream = await window.navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sources[sscid].id,
maxFrameRate: 60
}
}
});
resolve(stream);
} else {
var sscid = 0;
const sources = await desktopCapturer.getSources({ types: ['screen'] });
const stream = await window.navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sources[sscid].id,
maxFrameRate: 60
}
}
});
resolve(stream);
}
const sources = await desktopCapturer.getSources({ types: ['screen'] });
const stream = await window.navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sources[sscid].id,
maxFrameRate: 60
}
}
});
resolve(stream)
} else {
const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] });
const selectionElem = document.createElement('div');
@ -7984,7 +8040,7 @@ if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // this ena
}
ElectronDesktopCapture = true;
} catch(e){
warnlog("couldn't load electron's screen capture; you might need to decrease security permissions a bit.");
warnlog("Couldn't load electron's screen capture. Elevate the app's permission to allow it (right-click?)");
}
}
@ -10387,7 +10443,7 @@ function dragElement(elmnt) {
function previewIframe(iframesrc) { // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: <body onload=>loadIframe();"> , but don't call it before the page loads.
var iframe = document.createElement("iframe");
iframe.allow = "autoplay;camera;microphone;fullscreen;transparency;picture-in-picture;";
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;";
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.style.border = "10px dashed rgb(64 65 62)";
@ -10437,7 +10493,7 @@ function previewIframe(iframesrc) { // this is pretty important if you want to a
function loadIframe(iframesrc) { // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: <body onload=>loadIframe();"> , but don't call it before the page loads.
var iframe = document.createElement("iframe");
iframe.allow = "autoplay;camera;microphone;fullscreen;transparency;picture-in-picture;";
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;";
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.style.border = "10px dashed rgb(64 65 62)";
@ -12268,8 +12324,7 @@ function createIframePopup() {
}
var iframe = document.createElement("iframe");
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;transparency;";
iframe.allowtransparency = "true";
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;";
var extras = "";
if (session.password){
@ -13391,11 +13446,18 @@ function getChatMessage(msg, label = false, director = false, overlay = false) {
function updateClosedCaptions(msg, label, UUID) {
msg.counter = parseInt(msg.counter);
var transcript = sanitizeChat(msg.transcript); // keep it clean.
var temp = document.createElement('div');
temp.innerText = msg.transcript;
temp.innerText = temp.innerHTML;
var transcript = temp.textContent || temp.innerText || "";
if (transcript == "") {
return;
}
transcript = transcript.toUpperCase();
transcript = transcript.charAt(0).toUpperCase() + transcript.slice(1);
//transcript = transcript.substr(-1, 5000); // keep it from being too long
if (label) {
label = sanitizeLabel(label);
@ -14653,6 +14715,7 @@ function attemptTFLiteJsFileLoad(){
if (session.tfliteModule!==false){
return true;
}
warnUser("Loading effects model...");
TFLITELOADING=true;
session.tfliteModule={};
@ -14685,7 +14748,8 @@ async function changeTFLiteImage(ev, ele){
async function loadTFLiteModel(){
try{
try {
if (session.tfliteModule && (session.tfliteModule.img)){
var img = session.tfliteModule.img;
session.tfliteModule = await createTFLiteSIMDModule();
@ -14702,6 +14766,7 @@ async function loadTFLiteModel(){
}
} catch(e){
warnlog("TF-LITE FAILED TO LOAD");
closeModal();
return;
}
const modelResponse = await fetch("./thirdparty/tflite/segm_full_v679.tflite");
@ -14711,6 +14776,7 @@ async function loadTFLiteModel(){
session.tfliteModule._loadModel(session.tfliteModule.model.byteLength);
session.tfliteModule.activelyProcessing = false;
TFLITELOADING = false;
closeModal();
if ((session.effects>=3) && (session.effects<=5)){
if (document.getElementById("videosource")){
activatedPreview=false;

View File

@ -368,9 +368,6 @@ hr {
padding: 0;
overflow: hidden;
margin: var(--video-margin);
transition-property: all;
transition-duration: 1s;
transition-timing-function: ease-in;
}
#gridlayout {

12
main.js
View File

@ -286,7 +286,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
} else if (urlParams.has('screenshare') || urlParams.has('ss')) {
session.screenshare = true;
if (urlParams.get('screenshare') || urlParams.get('ss')){
session.screenshare = parseInt(urlParams.get('screenshare'));
session.screenshare = urlParams.get('screenshare') || urlParams.get('ss');
}
} else if (urlParams.has('fileshare') || urlParams.has('fs')) {
getById("container-5").classList.remove('advanced');
@ -2362,16 +2362,18 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
document.head.appendChild(script4);
}
script4.onload = function() {
closeModal();
async function loadModel(){
model = await faceLandmarksDetection.load(faceLandmarksDetection.SupportedPackages.mediapipeFacemesh);
}
loadModel();
}
script.src = "https://unpkg.com/@tensorflow/tfjs-core@2.4.0/dist/tf-core.js";
script2.src = "https://unpkg.com/@tensorflow/tfjs-converter@2.4.0/dist/tf-converter.js";
script3.src = "https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.4.0/dist/tf-backend-webgl.js";
script4.src = "https://unpkg.com/@tensorflow-models/face-landmarks-detection@0.0.1/dist/face-landmarks-detection.js";
script.src = "./thirdparty/tfjs/tf-core.js";
script2.src = "./thirdparty/tfjs/tf-converter.js";
script3.src = "./thirdparty/tfjs/tf-backend-webgl.js";
script4.src = "./thirdparty/tfjs/face-landmarks-detection.js";
warnUser("Loading effects model...");
script.type = 'text/javascript';script2.type = 'text/javascript';script3.type = 'text/javascript';script4.type = 'text/javascript';
document.head.appendChild(script);

5
thirdparty/ffmpeg.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

16300
thirdparty/tfjs/tf-backend-webgl.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

8058
thirdparty/tfjs/tf-converter.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
thirdparty/tfjs/tf-converter.js.map vendored Normal file

File diff suppressed because one or more lines are too long

27681
thirdparty/tfjs/tf-core.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
thirdparty/tfjs/tf-core.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long