recent fixes

This commit is contained in:
steveseguin 2023-02-15 21:52:31 -05:00
parent f7c88fcce4
commit 55e2106e59
5 changed files with 254 additions and 81 deletions

View File

@ -56,7 +56,7 @@
<meta property="twitter:image" content="./media/vdoNinja_logo_full.png" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<link rel="stylesheet" href="./main.css?ver=255" />
<link rel="stylesheet" href="./main.css?ver=260" />
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.js"></script>
<style id="lightbox-animations" type="text/css"></style>
<!-- <link rel="manifest" href="manifest.json" /> -->
@ -83,7 +83,7 @@
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=45"></script>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=573"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=577"></script>
<input id="zoomSlider" type="range" style="display: none;" />
<span id="electronDragZone" style="pointer-events: none; z-index:-10; position:absolute;top:0;left:0;width:100%;height:2%;-webkit-app-region: drag;min-height:20px;"></span>
<div id="header">
@ -479,7 +479,7 @@
<i class="las la-robot"></i><span data-translate="select-avatar-image"> Default Avatar / Placeholder Image </span>
</div>
<div id="selectAvatarImage" style="margin-top:10px;">
<img src="./media/avatar.webp" loading="lazy" id="defaultAvatar1" style="max-width:130px;max-height:73.5px;display:inline-block;margin:10px;cursor:pointer;" onclick="changeAvatarImage(event, this);"/>
<img src="./media/avatar.webp" crossOrigin="Anonymous" loading="lazy" id="defaultAvatar1" style="max-width:130px;max-height:73.5px;display:inline-block;margin:10px;cursor:pointer;" onclick="changeAvatarImage(event, this);"/>
<label class="selected" id="noAvatarSelected" style="width:130px;display:inline-block;margin:0 1px; text-align: center; cursor:pointer;">
<i class="las la-minus-circle" style="font-size: 3em;"></i><br />No Image Selected
<button onclick="changeAvatarImage(event, this)" style="position: fixed; top: -100em; margin-left:10px; border:1px solid #555;"></button>
@ -1333,6 +1333,7 @@
<div id="overlayClockContainer" data-menu='context-menu-clock' data-initial="600" class="hidden"><span id="overlayClock"></span></div>
<div id="overlayClockContainer2" data-menu='context-menu-clock' data-initial="600" class="hidden"><span id="overlayClock2"></span></div>
<div id="overlayMsgs" onclick="this.innerHTML = '';" style="display:none"></div>
<div id="stickyMsgs" class="hidden"></div>
<div id="bigPlayButton" onclick="this.innerHTML = '';" style="display:none"></div>
<div id="controls_blank" class="hidden controlCenterBox">
<div class="controlsGrid">
@ -1751,12 +1752,12 @@
<i class="las la-robot"></i><span data-translate="select-avatar-image"> Default Avatar / Placeholder Image: </span>
</div>
<div id="selectAvatarImage3" style="margin-top:10px;">
<img src="./media/avatar.webp" loading="lazy" id="defaultAvatar2" style="max-width:130px;max-height:73.5px;display:inline-block;margin:10px;cursor:pointer;" onclick="changeAvatarImage(event, this);"/>
<label class="selected" id="noAvatarSelected3" style="width:130px;display:inline-block;margin:0 1px; text-align: center; cursor:pointer;">
<img src="./media/avatar.webp" crossOrigin="Anonymous" loading="lazy" id="defaultAvatar2" style="max-width:130px;max-height:73.5px;display:inline-block;margin:10px;cursor:pointer;" onclick="changeAvatarImage(event, this);"/>
<label class="selected avatarSelection" id="noAvatarSelected3">
<i class="las la-minus-circle" style="font-size: 3em;"></i><br />No Image Selected
<button onclick="changeAvatarImage(event, this)" style="position: fixed; top: -100em; margin-left:10px; border:1px solid #555;"></button>
</label>
<label style="width:130px;display:inline-block;margin:0 1px; text-align: center; vertical-align: top;cursor:pointer;">
<label class="avatarSelection">
<i class="las la-hdd" style="font-size: 3em;"></i><br />Select Local Image
<input type="file" onchange="changeAvatarImage(event, this)" accept="image/*" style="position: fixed; top: -100em; margin-left:10px; border:1px solid #555;">
</label>
@ -2025,9 +2026,12 @@
<span class='modalClose' onclick="toggleRoomSettings();">×</span>
<span></span>
<h3 data-translate="change-room-settings">Change room settings</h3><br />
<label title="Increase this at your peril. Changes the total inbound video bitrate per guest; mobile devices excluded." for="trbSettingInput" data-translate="change-room-video-quality">Change room video quality:</label>
<span style="margin-left: 6px;" id="trbSettingInputFeedback"></span>-kbps
<input id="trbSettingInput" type="range" min="0" max="4000" value="500" onchange="changeTRB(this);" oninput="getById('trbSettingInputFeedback').innerHTML = this.value;" style="width:100%;display:block;" />
<input id="trbSettingInput" type="range" min="0" max="4000" value="500" onchange="getById('trbSettingInputManual').value=this.value;changeTRB(this);" oninput="getById('trbSettingInputFeedback').innerHTML = this.value;" style="width:calc(100% - 60px);display:inline-block;" />
<input id="trbSettingInputManual" min="0" value="500" onchange="getById('trbSettingInput').value=this.value;changeTRB(this);" oninput="getById('trbSettingInputFeedback').innerHTML = this.value;" style="width:42px;display:inline-block;text-align: center;" />
<span style="margin: 20px 0 0 0;display:block" id='highlightDirectorSpan' title="Only the director's video will be visible to guests and within group scenes">
<input id="highlightDirector" style="width: 15px; height: 15px; margin:10px;" name="highlightDirector" data-action-type="solo-video" type="checkbox" onchange="requestInfocus(this);" />
<label for="highlightDirector" data-translate="highlight-director-only-video-guests-will-see">Highlight Director (only video guests will see)</label>
@ -2288,7 +2292,7 @@
var session = WebRTC.Media; // session is a required global variable if configuring manually. Run before loading main.js but after webrtc.js.
session.version = "23.1b";
session.version = "23.2b";
session.streamID = session.generateStreamID(); // randomly generates a streamID for this session. You can set your own programmatically if needed
session.defaultPassword = "someEncryptionKey123"; // Change this password if self-deploying for added security/privacy
@ -2401,11 +2405,11 @@
// session.hidehome = true; // If used, 'hide home' will make the landing page inaccessible, along with hiding a few go-home elements.
// session.record = false; // uncomment to block users from being able to record via vdo.ninja's built in recording function
</script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=648"></script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=657"></script>
<!--
// If you wish to change branding, blank offers a good clean start.
<script type="text/javascript" id="main-js" src="./main.js" data-translation="blank"></script>
-->
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=538"></script>
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=542"></script>
</body>
</html>

174
lib.js
View File

@ -618,6 +618,7 @@ function createVideoElement(){
v.volume = session.volume; // setting default volume
log("setting volume to manual");
}
return v;
}
@ -1799,27 +1800,57 @@ function applySceneState(){ // guest side; tally light, etc.
getById("obsState").classList.remove("ondeck");
getById("obsState").classList.add("recording"); // TODO: this needs to check all peers to make sure it's valid
getById("obsState").innerHTML = "ON AIR";
if (session.tallyStyle){
getById("main").classList.remove("ondeck");
getById("main").classList.add("recording");
}
} else if (ondeck && !visibility){
getById("obsState").classList.remove("recording");
getById("obsState").classList.add("ondeck"); // TODO: this needs to check all peers to make sure it's valid
getById("obsState").innerHTML = "STAND BY";
if (session.tallyStyle){
getById("main").classList.remove("recording");
getById("main").classList.add("ondeck");
}
} else if (visibility){
getById("obsState").classList.remove("recording");
getById("obsState").classList.remove("ondeck");
getById("obsState").innerHTML = "ACTIVE";
if (session.tallyStyle){
getById("main").classList.remove("recording");
getById("main").classList.remove("ondeck");
}
} else {
getById("obsState").classList.remove("recording");
getById("obsState").classList.remove("ondeck");
getById("obsState").innerHTML = "INACTIVE";
getById("obsState").classList.add("hidden"); // I don't think most people care to see inactive.
if (session.tallyStyle){
getById("main").classList.remove("recording");
getById("main").classList.remove("ondeck");
}
}
if (visibility){ // BASIC TALLY LIGHT (on deck disabled)
getById("obsState").classList.add("onair"); // LIVE
if (session.tallyStyle){
getById("main").classList.add("onair");
}
} else {
getById("obsState").classList.remove("onair");
if (session.tallyStyle){
getById("main").classList.remove("onair");
}
}
if (session.automute){
if (!visibility){
session.micIsolatedAutoMute = [];
@ -3137,6 +3168,7 @@ function createRichVideoElement(UUID){ // this function is used to check and gen
}, { once: true });
setupIncomingVideoTracking(session.rpcs[UUID].videoElement, UUID);
pokeIframeAPI("video-element-created", "videosource_"+UUID, UUID);
}
@ -5475,7 +5507,7 @@ function loadQR(callback=false, value=false){
}
script.src = "./thirdparty/qrcode.min.js"; // dynamically load this only if its needed. Keeps loading time down.
document.head.appendChild(script);
} else {
} else if (callback){
callback(value);
}
}
@ -6062,10 +6094,12 @@ function setAvatarImage(tracks){
session.canvas.height = 2 * parseInt(height / 2);
session.canvas.width = 2 * parseInt(width / 2);
session.canvasCtx.drawImage(session.avatar, 0, 0, session.canvas.width, session.canvas.height);
session.avatar.timer = setInterval(function(){
log("drawing");
session.canvasCtx.drawImage(session.avatar, 0, 0, session.canvas.width, session.canvas.height);
},500);
},2000);
applyMirror(true);
@ -7534,10 +7568,10 @@ async function getFaces(){
//////
var digitalZoomMain=false;
function digitalZoom() {
function digitalZoom(reinit=false) {
if (session.effect !== "7"){return;}
if (digitalZoomMain){
digitalZoomMain();
digitalZoomMain(reinit);
return;
} else if (digitalZoomMain===null){
return;
@ -7626,7 +7660,14 @@ function digitalZoom() {
timers.activelyProcessingDraw = false;
}
function fde2(){
function fde2(reinit=false){
if (reinit){
if (session.canvasSource && session.canvasSource.srcObject && session.canvasSource.srcObject.getVideoTracks().length){
session.canvasSource.width = session.canvasSource.srcObject.getVideoTracks()[0].getSettings().width || 1280;
session.canvasSource.height = session.canvasSource.srcObject.getVideoTracks()[0].getSettings().height || 720;
}
xa = null;
}
if (!timers.activelyProcessingDraw){
draw();
}
@ -12497,12 +12538,9 @@ function publishWebcam(btn = false) {
window.onresize = updateMixer;
window.onorientationchange = function(){setTimeout(async function(){
if (session.forceAspectRatio){
// if (window.matchMedia("(orientation: portrait)").matches){
// await updateCameraConstraints("aspectRatio", 1.0/session.forceAspectRatio);
// } else {
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
// }
}
if (session.effect && (session.effect === "7")){digitalZoom(true);}
updateForceRotate();
updateMixer();
}, 200);};
@ -13874,6 +13912,14 @@ function audioMeter(mediaStreamSource, audioContext) {
}
}
if (session.pushLoudness==true){
var loudnessObj = {};
loudnessObj[session.streamID] = parseInt(total);
if (isIFrame){
parent.postMessage({"loudness": loudnessObj, "action":"loudness", "value":total}, session.iframetarget);
}
}
if (session.noisegate){
if (total<=ng2){
if (currentlyActive==ng3){
@ -14852,12 +14898,9 @@ async function createRoomCallback(passAdd, passAdd2) {
window.onresize = updateMixer;
window.onorientationchange = function(){setTimeout(async function(){
if (session.forceAspectRatio){
// if (window.matchMedia("(orientation: portrait)").matches){
// await updateCameraConstraints("aspectRatio", 1.0/session.forceAspectRatio);
// } else {
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
// }
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
}
if (session.effect && (session.effect === "7")){digitalZoom(true);}
updateForceRotate();
updateMixer();
}, 200);};
@ -18745,7 +18788,7 @@ if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // this ena
///
const stream = await window.navigator.mediaDevices.getUserMedia(new_constraints);
resolve(stream);
} else if (session.screenshare!==true){
} else if (session.screenshare && (session.screenshare!==true)){
var sscid=null;
const sources = await ipcRenderer.sendSync('getSources',{types: ['window']});
for (var i=0; i<sources.length;i++){
@ -19399,6 +19442,7 @@ function toggleRoomSettings(){
document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end
document.getElementById("modalBackdrop").addEventListener("click", toggleRoomSettings);
document.getElementById('trbSettingInput').value = session.totalRoomBitrate;
document.getElementById('trbSettingInputManual').value = session.totalRoomBitrate;
document.getElementById('trbSettingInputFeedback').innerHTML = session.totalRoomBitrate;
}
}
@ -19610,7 +19654,7 @@ function checkBasicStreamsExist(){
} else if (document.getElementById("previewWebcam")) {
session.videoElement = document.getElementById("previewWebcam");
} else {
session.videoElement = createVideoElement();
session.videoElement = createVideoElement();
}
session.videoElement.addEventListener("playing", (e)=>{
@ -21586,10 +21630,26 @@ session.publishStream = function(v){ // stream is used to generated an SDP
}; // publishStream
function stickyMessage(message){
var textOverlay = getById("stickyMsgs");
if (textOverlay) {
var spanOverlay = document.createElement("span");
spanOverlay.innerHTML = message;
var closeBtn = document.createElement("button");
closeBtn.className = "overlayCloseBtn";
closeBtn.innerText = "X";
closeBtn.onclick = function(){this.parentNode.remove();};
textOverlay.appendChild(spanOverlay);
spanOverlay.appendChild(closeBtn);
textOverlay.classList.remove("hidden");
}
}
session.postPublish = async function(){
log("Post publish");
if (session.welcomeMessage){
getChatMessage(session.welcomeMessage, false, true, true);
stickyMessage(session.welcomeMessage);
// getChatMessage(session.welcomeMessage, false, true, true);
}
if (session.welcomeImage){
@ -21771,12 +21831,9 @@ async function publishScreen2(constraints, audioList=[], audio=true, overrideFra
window.onresize = updateMixer;
window.onorientationchange = function(){setTimeout(async function(){
if (session.forceAspectRatio){
//if (window.matchMedia("(orientation: portrait)").matches){
// await updateCameraConstraints("aspectRatio", 1.0/session.forceAspectRatio);
//} else {
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
//}
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
}
if (session.effect && (session.effect === "7")){digitalZoom(true);}
updateForceRotate();
updateMixer();
}, 200);};
@ -21955,12 +22012,9 @@ async function publishScreen2(constraints, audioList=[], audio=true, overrideFra
window.onresize = updateMixer;
window.onorientationchange = function(){setTimeout(async function(){
if (session.forceAspectRatio){
//if (window.matchMedia("(orientation: portrait)").matches){
// await updateCameraConstraints("aspectRatio", 1.0/session.forceAspectRatio);
//} else {
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
//}
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
}
if (session.effect && (session.effect === "7")){digitalZoom(true);}
updateForceRotate();
updateMixer();
}, 200);};
@ -27052,6 +27106,14 @@ function previewWebcam() {
} else {
constraint.video = true;
}
window.onorientationchange = function(){setTimeout(async function(){
if (session.forceAspectRatio){
await updateCameraConstraints("aspectRatio", session.forceAspectRatio);
}
if (session.effect && (session.effect === "7")){digitalZoom(true);}
updateForceRotate();
}, 200);};
if ((constraint.video === false) && (constraint.audio === false)){
if (session.autostart) {
@ -27590,6 +27652,7 @@ function generateQRPageCallback(hash) {
getById("qrcode").title = "";
if (getById("qrcode").getElementsByTagName('img').length) {
getById("qrcode").getElementsByTagName('img')[0].style.cursor = "none";
getById("qrcode").getElementsByTagName('img')[0].style.margin = "0 auto";
}
}, 100); // i really hate the title overlay that the qrcode function makes
@ -30821,7 +30884,7 @@ function fftWaveform( source, UUID, trackid){ // append the delay Node to the t
loudness = Math.sqrt(Mean)*10;
session.rpcs[uuid].stats.Audio_Loudness = parseInt(loudness);
if (session.pushLoudness==true){
if (session.pushLoudness==true){
var loudnessObj = {};
loudnessObj[session.rpcs[uuid].streamID] = session.rpcs[uuid].stats.Audio_Loudness;
@ -30973,9 +31036,9 @@ function effectsDynamicallyUpdate(event, ele){
return;
}
if (session.effect === "7"){
if (session.effect === "7"){ // digitalZoom
getById("selectEffectAmount").style.display = "block";
getById("selectEffectAmount3").style.display = "block";
getById("selectEffectAmount3").style.display = "block";
session.effectValue = 1.0;
getById("selectEffectAmountInput").min = 1;
getById("selectEffectAmountInput").max = 1.99;
@ -31728,17 +31791,26 @@ async function processWHIP(data){
if (data.streamID){
msg.streamID = data.streamID;
} else {
msg.streamID = session.generateRandomString(15); // fake
msg.streamID = session.generateRandomString(15); // fake
}
log("setupIncoming");
await session.setupIncoming(msg); // could end up setting up the peer the wrong way.
var callback = null;
var promise = new Promise((resolve, reject) => {
callback = resolve;
});
session.rpcs[msg.UUID].whipCallback = callback;
var callback2 = null;
var promise2 = new Promise((resolve, reject) => {
callback2 = resolve;
});
session.rpcs[msg.UUID].whipCallback2 = callback2;
log("CONNECT PEEER");
session.connectPeer(msg);
log("CONNECT PEEER DONE");
if (!session.manual || !session.director){
window.onresize = updateMixer;
@ -31747,7 +31819,41 @@ async function processWHIP(data){
};
}
return await promise; // return SDP answer for the remote WHIP request
log("ICE BUNDLE PROMISE");
setTimeout(function(UUID){
log("ICE BUNDLE PROMISE TIMEOUT");
if (session.rpcs[UUID].whipCallback2){
session.rpcs[UUID].whipCallback2([...session.rpcs[UUID].iceBundle]);
clearTimeout(session.rpcs[UUID].iceTimer);
session.rpcs[UUID].iceTimer = null;
session.rpcs[UUID].iceBundle = []
session.rpcs[UUID].whipCallback2 = null;
}
},3000,msg.UUID);
var iceBundle = await promise2; // waiting for ICE GATHER COMPLETE
session.rpcs[msg.UUID].whipCallback2 = null;
log("ICE BUNDLE");
log(iceBundle);
var insertIce = "";
iceBundle.forEach(ice=>{
if (ice.candidate){
insertIce += "a="+ice.candidate+"\r\n";
}
});
var sdpAnswer = await promise;
session.rpcs[msg.UUID].whipCallback = null;
sdpAnswer = sdpAnswer.replace("a=ice-ufrag", insertIce+"a=ice-ufrag");
log("completed");
log(sdpAnswer);
return sdpAnswer; // return SDP answer for the remote WHIP request
}
var queuedSendingAPIMsgs = [];

115
main.css
View File

@ -1,5 +1,6 @@
:root {
--background-color: #141926;
--dark-background-color: #02050c;
--container-color: #373737;
--button-color: #2A2A2A;
--blue-accent: #4a4c63;
@ -15,7 +16,6 @@
--video-border: 0px;
--video-border-color: #0000;
--video-rounded: 0px;
--color-mode: light;
--button-radius: 2px;
--myvideo-max-width: min(800px,100vw);
--myvideo-width:unset;
@ -26,6 +26,13 @@
--background-main-image: unset;
--show-codirectors: inline-block;
--full-screen-button: inherit;
--color-mode: light;
--video-background-image-size: auto 30%;
}
@media (prefers-color-scheme: dark) {
:root {
--color-mode: dark;
}
}
* {
@ -421,6 +428,42 @@ button.white:active {
#overlayClock2:empty{
display:none;
}
#stickyMsgs{
margin:0 auto;
background-color: #0000;
color: white;
font-family: Cousine, monospace;
font-size: 6vh;
line-height: 8vh;
letter-spacing: 0.0em;
text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1);
width:100%;
z-index: 7;
vertical-align: top;
text-align: center;
position: fixed;
overflow-wrap: anywhere;
padding:2% 3%;
}.
.avatarSelection{
vertical-align: top;
margin: 10px 0;
width:130px;
display:inline-block;
margin:0 1px;
text-align: center;
cursor:pointer;
}
.overlayCloseBtn{
padding: 0;
margin: 10px;
width: 16px;
height: 16px;
position: relative;
bottom: 10px;
background-color: #DDDD;
}
#overlayMsgs{
margin:0 auto;
background-color: #0000;
@ -1336,6 +1379,9 @@ body {
transition: opacity .1s linear;
scrollbar-color:#666 #201c29;
}
body.darktheme{
background-color: var(--dark-background-color);
}
::-webkit-scrollbar {
width: 15px;
@ -2293,16 +2339,38 @@ img {
border-radius: 4px;
text-align: center;
}
#obsState.larger {
padding:2px 10px;
font-size: 30px;
}
@media only screen and (max-height: 400px){
#obsState {
transform: scale(0.9);
}
}
@media only screen and (max-height: 300px){
#obsState {
transform: scale(0.8);
}
}
@media only screen and (max-width: 620px){
#obsState {
top:20px;
transform: scale(0.63);
transform: scale(0.8);
}
}
@media only screen and (max-height: 200px){
#obsState {
transform: scale(0.7);
}
}
@media only screen and (max-width: 400px){
#obsState {
top:30px;
transform: scale(0.56);
transform: scale(0.7);
display:none!important;
opacity:0;
}
@ -2313,34 +2381,17 @@ img {
opacity:0;
}
}
@media only screen and (max-height: 400px){
#obsState {
transform: scale(0.5);
}
}
@media only screen and (max-height: 300px){
#obsState {
transform: scale(0.4);
}
}
@media only screen and (max-height: 200px){
#obsState {
transform: scale(0.3);
}
}
.onair {
border:green solid 2px !important;
box-shadow: inset 0 0 max(10vw, 10vh) green;
}
.ondeck {
border: yellow solid 2px !important;
display: block !important;
box-shadow: inset 0 0 max(10vw, 10vh) yellow;
}
.recording{
border: red solid 2px !important;
box-shadow: inset 0 0 max(10vw, 10vh) red
}
.raisedHand{
@ -2467,7 +2518,7 @@ video {
-ms-user-select: none; /* IE10+ */
-webkit-tap-highlight-color:transparent;
outline-style:none;
background-size: auto 50px;
background-size: var(--video-background-image-size);
background-repeat: no-repeat;
background-position: center;
background-image: var(--video-background-image);
@ -4106,6 +4157,9 @@ input:checked + .slider:before {
z-index: 0;
opacity: 0.8;
}
#modalBackdrop.darktheme{
background-color: var(--dark-background-color);
}
.modalBackdrop {
background: var(--background-color);
@ -4118,6 +4172,10 @@ input:checked + .slider:before {
opacity: 0.8;
}
.modalBackdrop.darktheme{
background-color: var(--dark-background-color);
}
.opaqueBackdrop{
background: var(--background-color);
position: fixed;
@ -4128,6 +4186,9 @@ input:checked + .slider:before {
z-index: 0;
opacity: 1.0;
}
.opaqueBackdrop.darktheme{
background-color: var(--dark-background-color);
}
.alertModalMessage>select{
font-size: 100%;
@ -4428,12 +4489,6 @@ input:checked + .slider:before {
content: "\f023"; }
.la-lock-open:before {
content: "\f3c1"; }
@media (prefers-color-scheme: dark) {
:root {
--color-mode: dark;
--background-color: #02050c;
}
}
body.darktheme {
color: white;

20
main.js
View File

@ -254,6 +254,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
try {
avatarImg = 'url("'+avatarImg+'")';
document.documentElement.style.setProperty('--video-background-image', avatarImg);
document.documentElement.style.setProperty('--video-background-image-size', "contain");
} catch(e){}
}
}
@ -513,6 +514,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.statsInterval = parseInt(urlParams.get("statsinterval")) || 3000; // milliseconds. interval of requesting stats of remote guests
}
if (urlParams.has('rotate') ) {
session.rotate = urlParams.get('rotate') || 90;
session.rotate = parseInt(session.rotate);
@ -1167,7 +1169,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
} else if (avatar){
avatar = decodeURIComponent(avatar);
session.avatar = document.getElementById("defaultAvatar2");
session.avatar = getById("defaultAvatar2");
session.avatar.ready = false;
session.avatar.onload = () => {
session.avatar.ready = true;
@ -1176,12 +1178,12 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
getById("defaultAvatar1").classList.add("selected");
getById("defaultAvatar2").classList.add("selected");
};
document.getElementById("defaultAvatar1").src = avatar;
document.getElementById("defaultAvatar2").src = avatar;
getById("defaultAvatar1").src = avatar;
getById("defaultAvatar2").src = avatar;
}
document.getElementById("avatarDiv3").classList.remove("hidden");
document.getElementById("avatarDiv").classList.remove("hidden");
getById("avatarDiv3").classList.remove("hidden");
getById("avatarDiv").classList.remove("hidden");
}
if (urlParams.has('prompt') || urlParams.has('validate') || urlParams.has('approve')){
@ -1972,11 +1974,15 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (session.obsControls){
getById("obscontrolbutton").classList.remove("hidden");
getById("controlButtons").style.display = "block";
}
if (urlParams.has('tallyoff') || urlParams.has('notally') || urlParams.has('disabletally') || urlParams.has('to')) {
log("Tally Light off");
getById("obsState").style.setProperty("display", "none", "important");
} else if (urlParams.has('tally')) {
session.tallyStyle = 1;
getById("obsState").classList.add("larger");
}
if (urlParams.has('automute') || urlParams.has('am')){
@ -2145,7 +2151,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (session.darkmode){
document.body.classList.add("darktheme");
document.querySelector(':root').style.setProperty('--background-color',"#02050c" );
//document.querySelector(':root').style.setProperty('--background-color',"#02050c" );
} else {
document.body.classList.remove("darktheme");
//document.querySelector(':root').style.setProperty('--background-color',"#141926" ); // already set as default.
@ -3662,6 +3668,8 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
if (urlParams.has('effects') || urlParams.has('effect')) {
session.effect = urlParams.get('effects') || urlParams.get('effect') || null;
} else if (urlParams.has('zoom')){
session.effect = "7";
}
if (window.FaceDetector !== undefined){

File diff suppressed because one or more lines are too long