Merge pull request #930 from steveseguin/v20.x-dev-patches

V20.4 merge
This commit is contained in:
Steve Seguin 2022-01-24 09:15:14 -05:00 committed by GitHub
commit 871b4c3808
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 2312 additions and 1119 deletions

View File

@ -233,6 +233,11 @@
button.onclick = function(){iframe.contentWindow.postMessage({"getStreamIDs":true}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "get media device list";
button.onclick = function(){iframe.contentWindow.postMessage({"getDeviceList":true}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Start AutoMixer";
button.onclick = function(){iframe.contentWindow.postMessage({"automixer":true}, '*');};
@ -347,6 +352,17 @@
iframeContainer.appendChild(outputWindow);
}
if ("deviceList" in e.data){
var outputWindow = document.createElement("div");
outputWindow.innerHTML = "child-page-action: deviceList<br />";
for (var i = 0;i<e.data.deviceList.length;i++){
outputWindow.innerHTML += e.data.deviceList[i].label + "<br />";
}
outputWindow.style.border="1px dotted black";
iframeContainer.appendChild(outputWindow);
}
if ("loudness" in e.data){
console.log(e.data);
if (document.getElementById("loudness")){

View File

@ -54,7 +54,7 @@
transition: opacity .1s linear;
}
</style>
<link rel="stylesheet" href="./main.css?ver=146" />
<link rel="stylesheet" href="./main.css?ver=151" />
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.min.js"></script>
<style id="lightbox-animations" type="text/css"></style>
</head>
@ -66,8 +66,8 @@
<span itemprop="thumbnail" itemscope itemtype="http://schema.org/ImageObject">
<link itemprop="url" href="./media/vdoNinja_logo_full.png" />
</span>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=35"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=339"></script>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=36"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=345"></script>
<input id="zoomSlider" type="range" style="display: none;" />
<div id="header">
@ -115,7 +115,12 @@
<div id="controlButtons" >
<div id="obsState" class="advanced" >ACTIVE</div>
<div id="subControlButtons">
<div id="queuebutton" title="Load the next guest in queue" alt="Load the next guest in queue" onmousedown="event.preventDefault(); event.stopPropagation();" onclick="session.nextQueue()" tabindex="16" role="button" aria-pressed="false" onkeyup="enterPressedClick(event,this);" class="advanced float" style="cursor: pointer;" >
<div id="blindAllGuests" title="Blind all guests in room (toggle)" alt="Blind all guests in room (toggle)" onmousedown="event.preventDefault(); event.stopPropagation();" onclick="blindAllGuests(this, event)" tabindex="16" role="button" aria-pressed="false" onkeyup="enterPressedClick(event,this);" class="advanced float" style="cursor: pointer;" >
<i class="toggleSize las la-eye my-float"></i>
</div>
<div id="queuebutton" title="Load the next guest in queue" alt="Load the next guest in queue" onmousedown="event.preventDefault(); event.stopPropagation();" onclick="nextQueue()" tabindex="16" role="button" aria-pressed="false" onkeyup="enterPressedClick(event,this);" class="advanced float" style="cursor: pointer;" >
<i id="queuetoggle" class="toggleSize las la-stream my-float"></i>
<div id="queueNotification"></div>
</div>
@ -237,7 +242,7 @@
<span data-translate="room-name">Room Name</span>:
</b>
</div>
<input type="text" autocorrect="off" autocapitalize="none" id="videoname1" placeholder="Enter a Room Name here" onkeydown="checkStrengthRoom(event, 'securityLevelRoom');" onchange="checkStrengthRoom(event, 'securityLevelRoom');" onkeyup="enterPressed(event, createRoom);" maxlength="30" style="font-size: 110%; padding: 5px;" />
<input type="text" autocorrect="off" autocapitalize="none" id="videoname1" placeholder="Enter a room name here" onkeydown="checkStrengthRoom(event, 'securityLevelRoom');" onchange="checkStrengthRoom(event, 'securityLevelRoom');" onkeyup="enterPressed(event, createRoom);" maxlength="30" style="max-width: 431px;width: 100%;font-size: 110%; padding: 5px;" />
<div id="securityLevelRoom" style="display:none;margin-top:3px;position:relative;top:3px;font-size:0.8em;"></div>
</th>
@ -255,7 +260,7 @@
<span data-translate="password-input-field">Password</span>:
</b>
</div>
<input type="text" autocorrect="off" autocapitalize="none" id="passwordRoom" placeholder="Optional room password here" onkeydown="checkStrengthRoom(event, 'securityLevelRoom');" onchange="checkStrengthRoom(event, 'securityLevelRoom');" onkeyup="enterPressed(event, createRoom);" maxlength="30" style="font-size: 110%; padding: 5px;" />
<input type="text" autocorrect="off" autocapitalize="none" id="passwordRoom" placeholder="Optional room password here" onkeydown="checkStrengthRoom(event, 'securityLevelRoom');" onchange="checkStrengthRoom(event, 'securityLevelRoom');" onkeyup="enterPressed(event, createRoom);" maxlength="50" style="max-width: 431px;width: 100%;font-size: 110%; padding: 5px;" />
</th>
</tr><tr >
@ -264,7 +269,7 @@
<input id="broadcastFlag" type="checkbox" title="For large group rooms, this option can reduce the load on remote guests substantially" />
</th><th style="text-align:left;; padding-top: 20px;">
<b>
<span data-translate="guests-only-see-director" style="cursor: help;" title="For large group rooms, this option can reduce the load on remote guests substantially" >Guests can only see the Director's Video</span>
<span data-translate="guests-only-see-director" style="cursor: help;" title="For large group rooms, this option can reduce the load on remote guests substantially" >The guests can see the director, but not other guests' videos</span>
</b>
</th>
</tr><tr>
@ -273,7 +278,7 @@
<input id="showdirectorFlag" type="checkbox" title="The director will be visible in scenes as if a performer themselves." />
</th><th style="text-align:left;; padding-bottom: 20px;">
<b>
<span data-translate="scenes-can-see-director" style="cursor: help;" title="If checked, the director can be added to scenes as if a guest. Otherwise, the director will never appear in a scene." >Director will be performing; appearing in scenes</span>
<span data-translate="scenes-can-see-director" style="cursor: help;" title="If checked, the director can be added to scenes as if a guest. Otherwise, the director will never appear in a scene." >The director will be performing as well, appearing in group scenes</span>
</b>
</th>
</tr><tr>
@ -295,11 +300,11 @@
</tr>
</table>
<div style="margin: 0 auto; width: 400px; max-width:100%;">
<div style="margin: 0 auto; width: 470px; max-width:100%;">
<button onclick="createRoom()" class="gobutton" style="width:100%;" alt="Enter the room as the group's director" title="You'll enter as the room's director">
<span data-translate="enter-the-rooms-control">Enter the Room's Control Center</span>
<span data-translate="enter-the-rooms-control">Enter the room's Control Center in the director's role</span>
</button>
<br /><br />
<br />
<button class="white roomnotes" style="display: block;" onclick="toggle(document.getElementById('roomnotes'),this);">
<span data-translate="show-tips">Show me some tips..</span>
</button>
@ -317,10 +322,10 @@
<br />
<br />
</ul>
<br />
<br /><br />
<i>Looking to just chat and not direct?</i>
<button onclick="jumptoroom2()" class="gobutton" style="width:100%;" alt="Enter the room as the group's director" title="You'll enter as the room's director">
<span data-translate="join-the-room-basic">Join room as participant</span>
<span data-translate="join-the-room-basic">Join the room as a Participant, rather than a director</span>
</button>
</div>
</div>
@ -339,7 +344,7 @@
<div class="container-inner">
<br />
<p>
<video id="previewWebcam" class="previewWebcam" oncanplay="updateStats();" controlsList="nodownload" muted autoplay playsinline ></video>
<video id="previewWebcam" class="previewWebcam task" title="Right-click this video for additional options" data-menu="context-menu-video" oncanplay="updateStats();" controlsList="nodownload" muted autoplay playsinline ></video>
</p>
<div id="infof"></div>
<button onclick="this.disabled=true;setTimeout(function(){requestBasicPermissions();},20);" id="getPermissions" style="display:none;" data-ready="false" >
@ -417,7 +422,10 @@
<i class="las la-headphones"></i><span data-translate="select-output-source"> Audio Output Destination:
</span><button onclick="playtone()" class="white" style="margin:0 0 0 15px;padding: 2px 10px 0px 10px;" type="button">Test</button></div>
<select id="outputSource" ></select>
<div id="headphoneTip1" class="cameraTip advanced">
<i class="las la-info-circle"></i>
<p><span id="headphoneTipContext1"></span></p>
</div>
</span>
<div id="effectsDiv">
<div style="text-align: left;display: inline-block;">
@ -773,10 +781,10 @@
Some devices that use hardware encoding can experience video glitching; switching to VP8 or VP9 as a <a target='_blank' title='Jump to the documentation' href='https://docs.vdo.ninja/viewers-settings/codec'>codec</a> may help.
</li>
<li>
Video glitching and random audio-loss can occur when using the OBS browser source. The <a href='https://github.com/steveseguin/electroncapture/blob/master/README.md' target="_blank">Electron Capture app</a> avoids these issues.
Windows users, upgrading to OBS 27.2 or newer will fix video glitching issues caused by network packet loss. <a href='https://github.com/obsproject/obs-studio/releases' target="_blank">Grab the newest OBS version here</a>.
</li>
<li>
Samsung smartphones (A-series) may fail to publish video with some mobile browsers; try using Firefox or the native <a href='https://docs.vdo.ninja/getting-started/native-mobile-app-versions#android-download-link'>VDO.Ninja Android app</a> in these cases.
Samsung smartphones (A-series) may fail to publish video with some mobile browsers; try using Firefox Mobile or the native <a href='https://docs.vdo.ninja/getting-started/native-mobile-app-versions#android-download-link'>Android app</a> in these cases.
</li>
<br />
<h4>
@ -1064,11 +1072,11 @@
</label>
<span data-translate="guest-joins-with-no-camera">Guest joins with no camera</span>
<Br />
<label class="switch" title="Make the invite URL encoded, so parameters are harder to tinker with by guests">
<label class="switch" title="Make the invite URL encoded, so parameters are harder to tinker with by guests. This also debrands the interface and gives it a new domain name.">
<input type="checkbox" data-param="" id="obfuscate_director_1" onchange="updateLink(1,this);">
<span class="slider"></span>
</label>
<span data-translate="obfuscate-link">Obfuscate link and parameters</span>
<span data-translate="obfuscate-link">Obfuscate with Invite.cam</span>
</div>
</div>
@ -1182,11 +1190,11 @@
</div>
<div></div>
<div id='guestFeeds' style="display:none"><div id='deleteme'>
<div class='vidcon directorMargins' style='min-height: 300px;text-align: center;'><h2>Guest 1</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<div class='vidcon directorMargins' style='min-height: 300px;text-align: center;'><h2>Guest 2</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<div class='vidcon directorMargins' style='min-height: 300px;text-align: center;'><h2>Guest 3</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<div class='vidcon directorMargins' style='min-height: 300px;text-align: center;'><h2>Guest 4</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<h4 style='color:#CCC;margin:20px 20px 0 20px;' data-translate='more-than-four-can-join' >These four guest slots are just for demonstration. More than four guests can actually join a room.</h4>
<div class='vidcon directorMargins' id='fakeguest1' style='min-height: 300px;text-align: center;'><h2>Guest 1</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<div class='vidcon directorMargins' id='fakeguest2' style='min-height: 300px;text-align: center;'><h2>Guest 2</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<div class='vidcon directorMargins' id='fakeguest3' style='min-height: 300px;text-align: center;'><h2>Guest 3</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<div class='vidcon directorMargins' id='fakeguest4' style='min-height: 300px;text-align: center;'><h2>Guest 4</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
<h4 style='color:#CCC;margin:20px 20px 0 20px;' id='fakeguestinfo' data-translate='more-than-four-can-join' >These four guest slots are just for demonstration. More than four guests can actually join a room.</h4>
</div></div>
</div>
<div id="hiddenElements"></div>
@ -1219,6 +1227,15 @@
<span data-translate="add-to-scene">add to scene 1</span>
</button>
<button data-action-type="solo-video" style="text-shadow: 0px 0px yellow;" data-value="0" title="Solo this video everywhere" onclick="requestInfocus(this);">
<i class="las la-user"></i>
<span data-translate="solo-video">Highlight guest</span>
</button>
<font class="tooltip" style="height: 0; border: 0;">
<input data-action-type="volume" type="range" min="0" max="200" value="100" title="Remotely change the volume of this guest" oninput="remoteVolumeUI(this)" ondblclick="this.value=100;remoteVolume(this);remoteVolumeUI(this);" onchange="remoteVolume(this);" style="grid-column: 2; margin:5px; width: 93%; position: relative;top: 0.6em; background-color:#fff0;"/><span class="tooltiptext" style='float: right; overflow: auto; left: 40px; width: 3em; top: -13px; margin: 0; position:relative;font-family:"Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus,Code2000, Code2001, Code2002, Musica, serif, LastResort;' >100</span>
</font>
<button data-action-type="mute-guest" title="Mute this guest everywhere" onclick="remoteMute(this, event);">
<i class="las la-microphone-slash" style="color:#900"></i>
<span data-translate="mute-guest" >mute guest</span>
@ -1239,25 +1256,25 @@
</button>
<span class="hidden" data-cluster="1" data-action-type="sceneCluster1">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="3" data-action-type="add-scene-3" title="Add to Scene 3" onclick="directEnable(this, event, 3);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="3" title="Add to Scene 3" onclick="directEnable(this, event, 3);">
<span >S3</span>
</button>
<button style="width:35.2px;" data-action-type="addToScene" data-scene="4" data-action-type="add-scene-4" title="Add to Scene 4" onclick="directEnable(this, event, 4);">
<button style="width:35.2px;" data-action-type="addToScene" data-scene="4" title="Add to Scene 4" onclick="directEnable(this, event, 4);">
<span >S4</span>
</button>
<button style="width: 35.2px" data-action-type="addToScene" data-scene="5" data-action-type="add-scene-5" title="Add to Scene 5" onclick="directEnable(this, event, 5);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="5" title="Add to Scene 5" onclick="directEnable(this, event, 5);">
<span >S5</span>
</button>
</span>
<span class="hidden" data-cluster="1" data-action-type="sceneCluster2">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="6" data-action-type="add-scene-6" title="Add to Scene 6" onclick="directEnable(this, event, 6);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="6" title="Add to Scene 6" onclick="directEnable(this, event, 6);">
<span >S6</span>
</button>
<button style="width: 35.2px" data-action-type="addToScene" data-scene="7" data-action-type="add-scene-7" title="Add to Scene 7" onclick="directEnable(this, event, 7);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="7" title="Add to Scene 7" onclick="directEnable(this, event, 7);">
<span >S7</span>
</button>
<button style="width: 35.2px" data-action-type="addToScene" data-scene="8" data-action-type="add-scene-8" title="Add to Scene 8" onclick="directEnable(this, event, 8);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="8" title="Add to Scene 8" onclick="directEnable(this, event, 8);">
<span >S8</span>
</button>
</span>
@ -1276,10 +1293,7 @@
<span class="hideDropMenu" style="grid-column: 2;" ></span>
<button class="hidden" data-cluster="2" data-action-type="solo-video" style="text-shadow: 0px 0px yellow;" data-value="0" title="Solo this video everywhere" onclick="requestInfocus(this);">
<i class="las la-user"></i>
<span data-translate="solo-video">Highlight guest</span>
</button>
<button class="hidden" data-cluster="2" data-action-type="hide-guest" title="Hide this guest everywhere" onclick="remoteMuteVideo(this, event);">
<i class="las la-video-slash"></i>
@ -1294,9 +1308,6 @@
<i class="las la-eye-slash"></i> <span data-translate="toggle-remote-display">Blind Guest</span>
</button>
<font class="tooltip hidden" data-cluster="2" style="height: 0; border: 0;">
<input data-action-type="volume" type="range" min="0" max="200" value="100" title="Remotely change the volume of this guest" oninput="remoteVolumeUI(this)" ondblclick="this.value=100;remoteVolume(this);remoteVolumeUI(this);" onchange="remoteVolume(this);" style="grid-column: 2; margin:5px; width: 93%; position: relative;top: 0.6em; background-color:#fff0;"/><span class="tooltiptext" style='float: right; overflow: auto; left: 40px; width: 2.5em; top: -13px; margin: 0; position:relative;font-family:"Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus,Code2000, Code2001, Code2002, Musica, serif, LastResort;' >100</span>
</font>
<span class="hidden" data-cluster="2" data-action-type="change-quality">
<button style="width: 35.2px" data-action-type="change-quality1" title="Disable Video Preview" onclick="toggleQualityDirector(0, this.dataset.UUID, this);">
@ -1347,13 +1358,13 @@
<span data-translate="request-upload"> Request File</span>
</button>
<button class="hidden mainonly" data-cluster="2" data-action-type="create-timer" data-value="0" title="Set a countdown timer that this guest sees" onclick="directTimer(this, event);">
<button class="hidden mainonly" data-cluster="2" data-action-type="create-timer" data-value="0" title="Set a countdown timer that this guest sees. CTRL (cmd) + click to pause." onclick="directTimer(this, event);">
<i class="las la-clock"></i>
<span data-translate="create-timer">Create Timer</span>
</button>
<span id="channelGroup1" class="hidden" data-cluster="2">
<span class="hidden" data-cluster="2">
<button style="width:35.2px;" data-action-type="add-channel" title="Set to Audio Channel 1" onclick="changeChannelOffset(this.dataset.UUID, 0);">
<span >C1</span>
@ -1366,7 +1377,7 @@
</button>
</span>
<span id="channelGroup2" class="hidden" data-cluster="2">
<span class="hidden" data-cluster="2">
<button style="width:35.2px;" data-action-type="add-channel" title="Set to Audio Channel 4" onclick="changeChannelOffset(this.dataset.UUID,3);">
<span >C4</span>
@ -1379,7 +1390,7 @@
</button>
</span>
<span id="mixGroup1" class="hidden" data-cluster="2">
<span class="hidden" data-cluster="2">
<button style="width:35.2px;" data-action-type="toggle-group" data-value="1" title="Add/remove from group 1" onclick="changeGroup(this);">
<span >G1</span>
@ -1392,7 +1403,7 @@
</button>
</span>
<span id="mixGroup2" class="hidden" data-cluster="2">
<span class="hidden" data-cluster="2">
<button style="width:35.2px;" data-action-type="toggle-group" data-value="4" title="Add/remove from group 4" onclick="changeGroup(this);">
<span >G4</span>
@ -1429,29 +1440,55 @@
</button>
<span>
<button style="width: 35.2px" data-scene="2" data-action-type="addToScene" data-action-type="add-scene-2" title="Add to Scene 2" onclick="directEnable(this, event, 2, true);">
<button style="width: 35.2px" data-scene="2" data-action-type="addToScene" title="Add to Scene 2" onclick="directEnable(this, event, 2, true);">
<span >S2</span>
</button>
<button style="width:35.2px;" data-scene="3" data-action-type="addToScene" data-action-type="add-scene-3" title="Add to Scene 3" onclick="directEnable(this, event, 3, true);">
<button style="width:35.2px;" data-scene="3" data-action-type="addToScene" title="Add to Scene 3" onclick="directEnable(this, event, 3, true);">
<span >S3</span>
</button>
<button style="width: 35.2px" data-scene="4" data-action-type="addToScene" data-action-type="add-scene-4" title="Add to Scene 4" onclick="directEnable(this, event, 4, true);">
<button style="width: 35.2px" data-scene="4" data-action-type="addToScene" title="Add to Scene 4" onclick="directEnable(this, event, 4, true);">
<span >S4</span>
</button>
</span>
<span >
<button style="width: 35.2px" data-scene="5" data-action-type="addToScene" data-action-type="add-scene-5" title="Add to Scene 5" onclick="directEnable(this, event, 5, true);">
<button style="width: 35.2px" data-scene="5" data-action-type="addToScene" title="Add to Scene 5" onclick="directEnable(this, event, 5, true);">
<span >S5</span>
</button>
<button style="width: 35.2px" data-scene="6" data-action-type="addToScene" data-action-type="add-scene-6" title="Add to Scene 6" onclick="directEnable(this, event, 6, true);">
<button style="width: 35.2px" data-scene="6" data-action-type="addToScene" title="Add to Scene 6" onclick="directEnable(this, event, 6, true);">
<span >S6</span>
</button>
<button style="width: 35.2px" data-scene="7" data-action-type="addToScene" data-action-type="add-scene-7" title="Add to Scene 7" onclick="directEnable(this, event, 7, true);">
<button style="width: 35.2px" data-scene="7" data-action-type="addToScene" title="Add to Scene 7" onclick="directEnable(this, event, 7, true);">
<span >S7</span>
</button>
</span>
<span>
<button style="width:35.2px;" data-action-type="toggle-group" data-value="1" title="Add/remove from group 1" onclick="changeGroupDirector(this);">
<span >G1</span>
</button>
<button style="width: 35.2px" data-action-type="toggle-group" data-value="2" title="Add/remove from group 2" onclick="changeGroupDirector(this);">
<span >G2</span>
</button>
<button style="width: 35.2px" data-action-type="toggle-group" data-value="3" title="Add/remove from group 3" onclick="changeGroupDirector(this);">
<span >G3</span>
</button>
</span>
<span>
<button style="width:35.2px;" data-action-type="toggle-group" data-value="4" title="Add/remove from group 4" onclick="changeGroupDirector(this);">
<span >G4</span>
</button>
<button style="width: 35.2px" data-action-type="toggle-group" data-value="5" title="Add/remove from group 5" onclick="changeGroupDirector(this);">
<span >G5</span>
</button>
<button style="width: 35.2px" data-action-type="toggle-group" data-value="6" title="Add/remove from group 6" onclick="changeGroupDirector(this);">
<span >G6</span>
</button>
</span>
<button data-action-type="force-keyframe" data-value="0" title="Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues." onclick="session.sendKeyFrameScenes();">
<span data-translate="force-keyframe">Rainbow Puke Fix</span>
</button>
@ -1632,12 +1669,6 @@
<span data-translate="picture-in-picture">Picture-in-picture</span>
</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Cast">
<i class="las la-external-link"></i>
<span data-translate="chrome-cast">Cast..</span>
</a>
</li>
</ul>
</nav>
@ -1756,7 +1787,8 @@
<i class="las la-fire-alt"></i>
</div>
<div id="batteryMeterTemplate" class="battery advanced" data-plugged="1">
<div class="battery-level" style="height:100%;">🔌</div>
<div class="battery-level" style="height:100%;"></div>
<div class="battery-charging">+</div>
</div>
<div id="voiceMeterTemplate" class="video-meter advanced">
</div>
@ -1840,7 +1872,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 = "20.1";
session.version = "20.4";
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
@ -1905,11 +1937,11 @@
// session.introOnClean = true; // this will load the page with the webcam selection screen if &push or &room is in the URL; no need to use &webcam.
</script>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=247"></script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=256"></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=288"></script>
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=290"></script>
</body>
</html>

2388
lib.js

File diff suppressed because it is too large Load Diff

169
main.css
View File

@ -111,7 +111,21 @@ th {
background: yellow;
transition: all 50ms linear;
}
.meter3 {
display: inline-block;
width: 0px;
height: 10px;
background: red;
transition: all 25ms linear;
}
.meter4 {
display: inline-block;
width: 2px;
height: 10px;
background: black;
position:relative;
float:left;
}
#mynetwork {
width: 600px;
height: 400px;
@ -187,7 +201,9 @@ button.grey {
.red2 {
background-color: #840000 !important;
}
.blue {
background-color: #000084 !important;
}
.orange {
background-color: #673100 !important;
@ -344,6 +360,7 @@ button.white:active {
}
body.darktheme .credits {
color: #707a93;
}
@ -539,6 +556,8 @@ hr {
animation: pulse 2s infinite;
}
.battery {
border: 3px solid #4192c5;
width: 11px;
@ -551,10 +570,20 @@ hr {
font-size: 1.5em;
z-index: 2;
cursor: help;
display:block;
display:none;
}
.battery[data-plugged="1"]{
font-size:0px;
.battery-charging{
margin: 0;
left: -1px;
padding: 0;
position: absolute;
font-size: 0.54em;
display: none;
}
.battery[data-plugged="1"] > .battery-charging {
display:block;
}
.battery.warn {
border: 3px solid #EFAF13;
@ -566,8 +595,15 @@ hr {
background: #30b455;
position: absolute;
bottom: 0px;
left: 0;
right: 0;
left: 0;
font-size: 0.7em;
margin: 0;
padding: 0;
}
.hasMedia > .battery {
display:block;
}
.signal-meter{
@ -578,10 +614,13 @@ hr {
top: 1px;
background-color: #FFF2;
font-size: 1.5em;
display:block;
display:none;
z-index: 2;
cursor: help;
}
.hasMedia > .signal-meter {
display:block;
}
.signal-meter[data-cpu="0"]>.la-signal {
display:block;
}
@ -760,6 +799,10 @@ button.glyphicon-button.active.focus {
.roomnotes{
display:none!important;
}
#head5 {
margin-right: 1px;
}
}
@media only screen and (max-width: 400px){
#subControlButtons {
@ -900,9 +943,6 @@ button.btnArmTransferRoom.selected{
#head4{
display:none;
}
#head5{
display:none;
}
#head2{
display:none;
}
@ -1034,7 +1074,27 @@ input[type='radio'] { cursor:pointer; }
margin: 44vh auto;
cursor: help;
}
#retryimage{
display: block;
margin: 25vh auto;
max-width: 50%;
max-height: 50%;
animation: fadeIn 2s;
}
#retrymessage{
display: block;
margin: 80vh auto;
animation: fadeIn 2s;
color: white;
position: absolute;
left: 0;
top: 0;
float: left;
width: 100%;
height: 100%;
text-align: center;
font-size: 2em;
}
@keyframes spin-animation {
0% {
@ -1072,6 +1132,22 @@ body {
margin: 0;
opacity: 1;
transition: opacity .1s linear;
scrollbar-color:#666 #201c29;
}
::-webkit-scrollbar {
width: 15px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 13px rgb(0 0 0 / 90%);
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
border-radius: 4px;
-webkit-box-shadow: inset 0 0 16px rgb(150 150 150 / 100%);
border: solid 3px transparent;
}
.previewWebcam {
@ -1280,6 +1356,31 @@ input[type=range]:focus::-ms-fill-upper {
}
}
@media only screen and (max-width: 1220px) {
#fakeguest4{
display: none!important;
}
#fakeguestinfo{
display: none!important;
}
}
@media only screen and (max-width: 933px) {
#fakeguest3{
display: none!important;
}
}
@media only screen and (max-width: 641px) {
#fakeguest2{
display: none!important;
}
}
@media only screen and (max-width: 292px) {
#fakeguest1{
display: none!important;
}
}
@media screen and (max-width: 768px) {
#popOutChat{
display: none;
@ -2684,14 +2785,24 @@ a.task {
.shift {
display: inline-block;
position: relative;
margin: 7px 0 0 4px;
margin: 0 0 0 4px;
padding: 0;
width: 27px;
width: 33px;
font-size: 0.8em;
top: -7px;
top: -4.9px;
}
.shift>i {
cursor:pointer;
width: 10px;
margin: 0 auto;
left: -1.1px;
position: relative;
}
.shift.locked>i{
display:none;
}
.shift.locked>span{
margin-left: 7px;
}
#toggleroomnotes {
grid-column: 4;
@ -2744,19 +2855,19 @@ i.las.la-circle {
}
.streamID {
text-align: right;
margin: 5px 5px 5px 0px;
margin: 5px 5px 2px 0px;
font-size: 0.7em;
text-overflow: ellipsis;
overflow: hidden;
position: relative;
width: 230px;
width: 227px;
display: inline-block;
}
.streamID i {
margin-left: 5px;
font-size: 1.3em;
position: relative;
top: 2px;
top: 1px;
}
.soloLink {
background: none;
@ -2776,7 +2887,7 @@ div#guestFeeds {
background: var(--container-color);
padding: 5px 0 15px 20px;
display: inline-block;
margin: 0px var(--regular-margin);
margin: 0px var(--regular-margin) 80px var(--regular-margin);
}
div#guestFeeds:empty {
@ -2954,6 +3065,7 @@ span#guestTips {
right: 10px;
}
.video-meter2 {
display:block;
padding:0;
width: 4px;
height:0%;
@ -2968,6 +3080,18 @@ span#guestTips {
transition: height 0.1s ease, background-color 0.1s ease;
}
.hasMedia > .video-meter2 {
display:block;
}
.hasMedia > .video-meter-2 {
display:block;
}
.hasMedia > .video-meter {
display:block;
}
#voiceMeterTemplate{
display:none;
}
@ -3204,7 +3328,7 @@ input:checked + .slider:before {
.promptModalMessage {
position: relative;
display: block;
width: 98%;
width: 93%;
margin: 0 5%;
}
@ -3379,6 +3503,7 @@ input:checked + .slider:before {
.alertModal {
width: 90%;
}
}
.iframeDetails {
@ -3643,7 +3768,10 @@ input:checked + .slider:before {
content: "\f0a0"; }
.la-signal:before {
content: "\f012"; }
.la-unlock:before {
content: "\f023"; }
.la-lock-open:before {
content: "\f3c1"; }
@media (prefers-color-scheme: dark) {
:root {
--color-mode: dark;
@ -3653,6 +3781,7 @@ input:checked + .slider:before {
body.darktheme {
color: white;
scrollbar-color: #000 #333;
}
body.darktheme form>label{
color: white;

212
main.js
View File

@ -100,13 +100,17 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (!isIFrame){
if (getStorage("redirect") == "yes") {
if (getChromeVersion()===65){
// pass, since probably manycam and that's bugged
} else if (getStorage("redirect") == "yes") {
setStorage("redirect", "", 0);
session.sticky = true;
} else if (getStorage("settings") != "") {
if (!(session.cleanOutput)){
if (!(session.cleanOutput)){
window.focus();
session.sticky = confirm(miscTranslations["load-previous-session"]);
session.sticky = confirm(getStorage("settings"));
if (!session.sticky) {
setStorage("settings", "", 0);
log("deleting cookie as user said no");
@ -362,7 +366,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (urlParams.has('showdirector') || urlParams.has('sd')) {
session.showDirector = urlParams.get('showdirector') || urlParams.get('sd') || true;
session.showDirector = parseInt(urlParams.get('showdirector')) || parseInt(urlParams.get('sd')) || true; // if 2, video only allowed. True or 1 will be video + audio allowed.
}
if (urlParams.has('rotate') ) {
@ -403,6 +407,11 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.midiHotkeys = parseInt(session.midiHotkeys);
}
if (urlParams.has('midioffset')){
session.midiOffset = urlParams.get('midioffset') || 0;
session.midiOffset = parseInt(session.midiOffset);
}
if (urlParams.has('midiremote') || urlParams.has('remotemidi')){
if (session.director!==false){
session.midiRemote = parseInt(urlParams.get('midiremote')) || parseInt(urlParams.get ('remotemidi')) || 4;
@ -513,6 +522,11 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.muted = true;
}
if (urlParams.has('hideguest') || urlParams.has('hidden')) {
session.directorVideoMuted = true;
}
if (urlParams.has('safemode')) {
session.safemode = true;
}
@ -538,7 +552,13 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.directorDisplayMuted=true; // false == true in this case.
}
if (urlParams.has('blindall')) {
session.directorBlindButton=true; // false == true in this case.
}
if (session.directorBlindButton){
getById("blindAllGuests").classList.remove("advanced");
}
if (urlParams.has('dpi') || urlParams.has('dpr')) {
session.devicePixelRatio = urlParams.get('dpi') || urlParams.get('dpr') || 2.0;
} //else if (window.devicePixelRatio && window.devicePixelRatio!==1){
@ -717,6 +737,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
if (urlParams.has('preloadbitrate')) {
session.preloadbitrate = parseInt(urlParams.get('preloadbitrate')) || 0; // 1000
}
if (urlParams.has('rampuptime')) {
session.rampUpTime = parseInt(urlParams.get('rampuptime')) || 10000;
}
if (urlParams.has('scenetype') || urlParams.has('type')) {
session.sceneType = parseInt(urlParams.get('scenetype')) || parseInt(urlParams.get('type')) || false;
@ -816,20 +840,28 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
generateHash(session.password + session.salt, 6).then(function(hash) { // million to one error.
log("hash is " + hash);
if (hash.substring(0, 4) !== hash_input) { // hash crc checks are just first 4 characters.
session.taintedSession = true;
if (!(session.cleanOutput)) {
getById("request_info_prompt").innerHTML = miscTranslations["password-incorrect"];
getById("request_info_prompt").style.display = "block";
getById("mainmenu").style.display = "none";
getById("head1").style.display = "none";
session.cleanOutput = true;
generateHash(session.password + "obs.ninja", 6).then(function(hash2) { // million to one error.
log("hash2 is " + hash2);
if (hash2.substring(0, 4) !== hash_input) { // hash crc checks are just first 4 characters.
session.taintedSession = true;
if (!(session.cleanOutput)) {
getById("request_info_prompt").innerHTML = miscTranslations["password-incorrect"];
getById("request_info_prompt").style.display = "block";
getById("mainmenu").style.display = "none";
getById("head1").style.display = "none";
session.cleanOutput = true;
} else {
getById("request_info_prompt").innerHTML = "";
getById("request_info_prompt").style.display = "block";
getById("mainmenu").style.display = "none";
getById("head1").style.display = "none";
}
} else {
getById("request_info_prompt").innerHTML = "";
getById("request_info_prompt").style.display = "block";
getById("mainmenu").style.display = "none";
getById("head1").style.display = "none";
}
} else {
session.taintedSession = false;
session.hash = hash;
}
}).catch(errorlog);
} else {
session.taintedSession = false;
session.hash = hash;
@ -1368,10 +1400,29 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers?
session.audioMeterGuest = false;
session.audioEffects = false;
session.obsfix = 15; // can be manually set via URL. ; VP8=15, VP9=30. (previous was 20.)
if (window.obsstudio.pluginVersion){
if (macOS){ // if mac, no fix
//session.obsfix = false;
} else if (window.obsstudio.pluginVersion=="2.17.4"){ // if obs v27.2 beta, no fix
//session.obsfix = false;
} else {
var ver = window.obsstudio.pluginVersion.split(".");
if (ver.length >= 2){
if (parseInt(ver[0])<=2){
if (parseInt(ver[0])==2){
if (parseInt(ver[1])<=16){
session.obsfix = 15;
}
} else {
session.obsfix = 15;
}
}
}
}
}
try {
log("OBS VERSION:" + window.obsstudio.pluginVersion);
log("macOS: " + navigator.userAgent.indexOf('Mac OS X') != -1);
log("macOS: " + macOS);
log(window.obsstudio);
if (typeof document.visibilityState !== "undefined"){
@ -1398,7 +1449,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
var cefVersion = getChromeVersion();
if (ver1.length == 3) { // Should be 3, but disabled3
if ((ver1.length == 3) && (parseInt(ver1[0]) == 2) && (cefVersion < 76) && (navigator.userAgent.indexOf('Mac OS X') != -1)) {
if ((ver1.length == 3) && (parseInt(ver1[0]) == 2) && (cefVersion < 76) && (macOS)) {
updateURL("streamlabs");
getById("main").innerHTML = "<div style='background-color:black;color:white;' data-translate='obs-macos-not-supported'><h1>Update OBS Studio to v26.1.2 or newer; older versions and StreamLabs OBS are not supported on macOS.\
<br /><i><small><small>download here: <a href='https://github.com/obsproject/obs-studio/releases'>https://github.com/obsproject/obs-studio/releases</a></small></small></i>\
@ -1412,9 +1463,9 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
}
//if (navigator.userAgent.indexOf('Mac OS X') != -1) {
// session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) // oct 2021, OBS now supports vp8 and actually breaks with h264 android devices.
//}
if (navigator.userAgent.indexOf('Mac OS X') != -1) {
session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) // oct 2021, OBS now supports vp8 and actually breaks with h264 android devices.
}
if (session.disableOBS===false){
window.addEventListener("obsSourceVisibleChanged", obsSourceVisibleChanged);
@ -1431,7 +1482,6 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
}
if (urlParams.has('chroma')) {
log("Chroma ENABLED");
getById("main").style.backgroundColor = "#" + (urlParams.get('chroma') || "0F0");
@ -1493,9 +1543,9 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
} catch(e){errorlog(e);}
if (urlParams.has("videodevice") || urlParams.has("vdevice") || urlParams.has('vd') || urlParams.has('device') || urlParams.has('d')) {
if (urlParams.has("videodevice") || urlParams.has("vdevice") || urlParams.has('vd') || urlParams.has('device') || urlParams.has('d') || urlParams.has('vdo')) {
session.videoDevice = urlParams.get("videodevice") || urlParams.get("vdevice") || urlParams.get("vd") || urlParams.get("device") || urlParams.get("d");
session.videoDevice = urlParams.get("videodevice") || urlParams.get("vdevice") || urlParams.get("vd") || urlParams.get("device") || urlParams.get("d") || urlParams.get("vdo");
if (session.videoDevice === null) {
session.videoDevice = "1";
@ -1528,7 +1578,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
// whatever the user entered I guess, santitized.
session.videoDevice = session.videoDevice.replace(/[\W]+/g, "_").toLowerCase();
}
getById("videoMenu").style.display = "none";
if (!urlParams.has('vdo')){
getById("videoMenu").style.display = "none";
}
log("session.videoDevice:" + session.videoDevice);
}
@ -1706,6 +1759,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.order = parseInt(urlParams.get('order')) || 1;
}
if (urlParams.has('orderby')) {
session.orderby = urlParams.get('orderby') || "id";
}
if (urlParams.has('slot')) {
session.slot = parseInt(urlParams.get('slot')) || 0;
}
@ -1741,6 +1798,14 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.sensorData = parseInt(session.sensorData);
}
if (urlParams.has('ptime')) {
session.ptime = parseInt(urlParams.get('ptime')) || 20;
if (session.ptime<10){
session.ptime = 10;
}
}
if (urlParams.has('minptime')) {
session.minptime = parseInt(urlParams.get('minptime')) || 10;
if (session.minptime < 10) {
@ -1761,16 +1826,6 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
}
if (urlParams.has('ptime')) {
session.ptime = parseInt(urlParams.get('ptime')) || 20;
if (session.minptime < 10) {
session.ptime = 10;
}
if (session.minptime > 300) {
session.ptime = 300;
}
}
if (urlParams.has('codec')) {
log("CODEC CHANGED");
@ -1909,6 +1964,18 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.meshcastBitrate = parseInt(session.meshcastBitrate);
}
if (urlParams.has('mcscreensharebitrate') || urlParams.has('mcssbitrate')){
session.meshcastScreenShareBitrate = urlParams.get('mcscreensharebitrate') || urlParams.get('mcssbitrate') || 2500;
session.meshcastScreenShareBitrate = parseInt(session.meshcastScreenShareBitrate);
}
if (urlParams.has('mcscreensharecodec') || urlParams.has('mcsscodec')){
session.meshcastScreenShareCodec = urlParams.get('mcscreensharecodec') || urlParams.get('mcsscodec') || false;
}
if (session.meshcastScreenShareCodec){
session.meshcastScreenShareCodec = session.meshcastScreenShareCodec.toLowerCase();
}
if (urlParams.has('mcab') || urlParams.has('mcaudiobitrate') || urlParams.has('meshcastab')){
session.meshcastAudioBitrate = urlParams.get('mcab') || urlParams.get('mcaudiobitrate') || urlParams.get('meshcastab') || 32;
session.meshcastAudioBitrate = parseInt(session.meshcastAudioBitrate);
@ -2529,21 +2596,25 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.queue = true;
}
if (urlParams.has('permaid') || urlParams.has('push')) {
session.permaid = urlParams.get('push') || urlParams.get('permaid');
if (urlParams.has('push') || urlParams.has('id') || urlParams.has('permaid') ) {
session.permaid = urlParams.get('push') || urlParams.get('id') || urlParams.get('permaid');
if (session.permaid) {
session.streamID = sanitizeStreamID(session.permaid);
} else {
session.permaid = null;
}
if (urlParams.has('permaid')) {
updateURL("permaid=" + session.streamID, true, false); // I'm not deleting the permaID first tho...
if (urlParams.has('push')){
updateURL("push="+session.streamID, true, false);
} else if (urlParams.has('id')){
updateURL("id="+session.streamID, true, false); // not 'officially' supporting this yet; we'll see.
} else if (urlParams.has('permaid')){
updateURL("permaid="+session.streamID, true, false);
} else {
updateURL("push=" + session.streamID, true, false); // I'm not deleting the permaID first tho...
updateURL("push="+session.streamID, true, false);
}
if (urlParams.has('director') || urlParams.has('dir')) { // if I do a short form of this, it will cause duplications in the code elsewhere.
//var director_room_input = urlParams.get('director');
//director_room_input = sanitizeRoomName(director_room_input);
@ -2574,9 +2645,9 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
getById("mainmenu").classList.add("mainmenuclass");
getById("header").style.alignSelf = "center";
if ((iOS) || (iPad)) {
getById("header").style.display = "none"; // just trying to free up space.
}
//if ((iOS) || (iPad)) {
//getById("header").style.display = "none"; // just trying to free up space.
//}
if (session.webcamonly == true) { // mobile or manual flag 'webcam' pflag set
getById("head1").innerHTML = '<font style="color:#CCC;" data-translate="please-accept-permissions">- Please accept any camera permissions</font>';
@ -2721,6 +2792,12 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.screenShareBitrate = parseInt(session.screenShareBitrate) || 2500;
}
if (urlParams.has('screensharelabel') || urlParams.has('sslabel')) {
session.screenShareLabel = urlParams.get('screensharelabel') || urlParams.get('sslabel');
session.screenShareLabel = decodeURIComponent(session.screenShareLabel);
session.screenShareLabel = session.screenShareLabel.replace(/_/g, " ")
}
if (session.roomid!==false){
if (!(session.cleanOutput)) {
if (session.roomid === "test") {
@ -2954,23 +3031,38 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
getById("mainmenu").innerHTML = '';
getById("mainmenu").classList.remove("row");
var timeout = 5000;
if (urlParams.has('waittimeout')){
timeout = parseInt(urlParams.get('waittimeout')) || 0;
}
setTimeout(function() {
try {
if ((session.view) && (!(session.cleanOutput))) {
if ((session.view)) {
if (document.getElementById("mainmenu")) {
getById("mainmenu").innerHTML += '<div class="retry-spinner" id="retrySpinner"></div>';
retrySpinner.title = miscTranslations["waiting-for-the-stream"]
retrySpinner.onclick = function(){
updateURL("cleanoutput");
location.reload();
if (urlParams.has('waitimage')){
getById("mainmenu").innerHTML += '<img id="retryimage"/>';
getById("retryimage").src = decodeURIComponent(urlParams.get('waitimage'));
getById("retryimage").onerror = function(){this.style.display='none';};
} else if (!(session.cleanOutput)){
getById("mainmenu").innerHTML += '<div class="retry-spinner" id="retrySpinner"></div>';
getById("retrySpinner").onclick = function(){
updateURL("cleanoutput");
location.reload();
}
getById("retrySpinner").title = miscTranslations["waiting-for-the-stream"]
}
if (urlParams.has('waitmessage')){
getById("mainmenu").innerHTML += '<div id="retrymessage"></div>';
getById("retrymessage").innerText = urlParams.get('waitmessage');
getById("retrySpinner").title = urlParams.get('waitmessage');
}
}
}
} catch (e) {
errorlog("Error handling QR Code failure");
errorlog(e);
}
}, 5000);
}, timeout);
log("auto playing");
var SafariVer = safariVersion();
@ -3267,7 +3359,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
warnlog(e.data.getDeviceList);
enumerateDevices().then(function(deviceInfos) {
parent.postMessage({
"deviceList": deviceInfos
"deviceList": JSON.parse(JSON.stringify(deviceInfos))
}, "*");
});
}
@ -3638,6 +3730,12 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
log(e);
midiHotkeysCommand(e.controller.number, e.rawValue);
});
} else if (session.midiHotkeys==5){
if (session.midiOffset!==false){
input.addListener('controlchange', function(e) {
midiHotkeysCommand_offset(e.controller.number, e.rawValue, session.midiOffset);
});
}
} else {
input.addListener('noteon', function(e) {
log(e);

View File

@ -7,7 +7,7 @@
body{
padding:0;
margin:0;
background-color: #0000;
background-color: #c5c2c2;
}
iframe {
border:0;
@ -89,452 +89,6 @@
padding: 10px 10px 0 15px;
border: 1px solid black;
}
@keyframes move {
100% {
transform: translate3d(0, 0, 1px) rotate(360deg);
}
}
.background {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background: #bfbfbf;
overflow: hidden;
z-index:-1;
}
.background span {
width: 50vmin;
height: 50vmin;
border-radius: 50vmin;
backface-visibility: hidden;
position: absolute;
animation: move;
animation-duration: 7;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.background span:nth-child(0) {
color: #a9a0bb;
top: 26%;
left: 54%;
animation-duration: 133s;
animation-delay: -143s;
transform-origin: 17vw 23vh;
box-shadow: 100vmin 0 13.032236536031524vmin currentColor;
}
.background span:nth-child(1) {
color: #888aa0;
top: 32%;
left: 60%;
animation-duration: 98s;
animation-delay: -19s;
transform-origin: -9vw -17vh;
box-shadow: -100vmin 0 13.361880379427102vmin currentColor;
}
.background span:nth-child(2) {
color: #a9a0bb;
top: 76%;
left: 30%;
animation-duration: 27s;
animation-delay: -382s;
transform-origin: -21vw -12vh;
box-shadow: -100vmin 0 13.29654068929897vmin currentColor;
}
.background span:nth-child(3) {
color: #a9a0bb;
top: 13%;
left: 3%;
animation-duration: 89s;
animation-delay: -71s;
transform-origin: -5vw -23vh;
box-shadow: -100vmin 0 13.269376230706396vmin currentColor;
}
.background span:nth-child(4) {
color: #888aa0;
top: 98%;
left: 83%;
animation-duration: 61s;
animation-delay: -57s;
transform-origin: 19vw -16vh;
box-shadow: 100vmin 0 13.465063933009704vmin currentColor;
}
.background span:nth-child(5) {
color: #4b6477;
top: 73%;
left: 100%;
animation-duration: 312s;
animation-delay: -390s;
transform-origin: 23vw -6vh;
box-shadow: -100vmin 0 12.719463296930117vmin currentColor;
}
.background span:nth-child(6) {
color: #888aa0;
top: 6%;
left: 84%;
animation-duration: 176s;
animation-delay: -255s;
transform-origin: 16vw 3vh;
box-shadow: -100vmin 0 13.358884039462355vmin currentColor;
}
.background span:nth-child(7) {
color: #888aa0;
top: 99%;
left: 9%;
animation-duration: 221s;
animation-delay: -385s;
transform-origin: -16vw -9vh;
box-shadow: 100vmin 0 13.435082385169103vmin currentColor;
}
.background span:nth-child(8) {
color: #a9a0bb;
top: 8%;
left: 92%;
animation-duration: 142s;
animation-delay: -99s;
transform-origin: -1vw -14vh;
box-shadow: -100vmin 0 13.456440775816723vmin currentColor;
}
.background span:nth-child(9) {
color: #a9a0bb;
top: 80%;
left: 70%;
animation-duration: 99s;
animation-delay: -124s;
transform-origin: 21vw -10vh;
box-shadow: 100vmin 0 13.007405893839119vmin currentColor;
}
.background span:nth-child(10) {
color: #888aa0;
top: 42%;
left: 2%;
animation-duration: 70s;
animation-delay: -341s;
transform-origin: -15vw -23vh;
box-shadow: 100vmin 0 13.005431373357645vmin currentColor;
}
.background span:nth-child(11) {
color: #a9a0bb;
top: 28%;
left: 2%;
animation-duration: 244s;
animation-delay: -369s;
transform-origin: -17vw -16vh;
box-shadow: 100vmin 0 13.351086475613746vmin currentColor;
}
.background span:nth-child(12) {
color: #4b6477;
top: 80%;
left: 50%;
animation-duration: 117s;
animation-delay: -399s;
transform-origin: 24vw 8vh;
box-shadow: 100vmin 0 12.979558964166843vmin currentColor;
}
.background span:nth-child(13) {
color: #888aa0;
top: 74%;
left: 65%;
animation-duration: 283s;
animation-delay: -50s;
transform-origin: 13vw 14vh;
box-shadow: 100vmin 0 13.282742227479792vmin currentColor;
}
.background span:nth-child(14) {
color: #888aa0;
top: 64%;
left: 61%;
animation-duration: 194s;
animation-delay: -278s;
transform-origin: -6vw 4vh;
box-shadow: -100vmin 0 13.333280580396286vmin currentColor;
}
.background span:nth-child(15) {
color: #a9a0bb;
top: 11%;
left: 86%;
animation-duration: 403s;
animation-delay: -329s;
transform-origin: 3vw 0vh;
box-shadow: -100vmin 0 13.1162690433691vmin currentColor;
}
.background span:nth-child(16) {
color: #4b6477;
top: 14%;
left: 59%;
animation-duration: 100s;
animation-delay: -15s;
transform-origin: -23vw 21vh;
box-shadow: -100vmin 0 13.30508866110655vmin currentColor;
}
.background span:nth-child(17) {
color: #888aa0;
top: 68%;
left: 45%;
animation-duration: 394s;
animation-delay: -137s;
transform-origin: 18vw -20vh;
box-shadow: -100vmin 0 12.809008306332636vmin currentColor;
}
.background span:nth-child(18) {
color: #a9a0bb;
top: 7%;
left: 33%;
animation-duration: 132s;
animation-delay: -346s;
transform-origin: -22vw -17vh;
box-shadow: -100vmin 0 12.940258664941906vmin currentColor;
}
.background span:nth-child(19) {
color: #a9a0bb;
top: 24%;
left: 65%;
animation-duration: 49s;
animation-delay: -44s;
transform-origin: 0vw -24vh;
box-shadow: -100vmin 0 12.733081490401828vmin currentColor;
}
.background span:nth-child(20) {
color: #888aa0;
top: 98%;
left: 49%;
animation-duration: 204s;
animation-delay: -160s;
transform-origin: -1vw 3vh;
box-shadow: -100vmin 0 13.05844646387434vmin currentColor;
}
.background span:nth-child(21) {
color: #a9a0bb;
top: 2%;
left: 29%;
animation-duration: 294s;
animation-delay: -272s;
transform-origin: 13vw -18vh;
box-shadow: -100vmin 0 12.626917095797205vmin currentColor;
}
.background span:nth-child(22) {
color: #a9a0bb;
top: 73%;
left: 32%;
animation-duration: 424s;
animation-delay: -59s;
transform-origin: 19vw 3vh;
box-shadow: 100vmin 0 13.092155905631065vmin currentColor;
}
.background span:nth-child(23) {
color: #888aa0;
top: 45%;
left: 93%;
animation-duration: 277s;
animation-delay: -215s;
transform-origin: 0vw -14vh;
box-shadow: 100vmin 0 12.768802405913084vmin currentColor;
}
.background span:nth-child(24) {
color: #4b6477;
top: 35%;
left: 40%;
animation-duration: 375s;
animation-delay: -205s;
transform-origin: -16vw -21vh;
box-shadow: -100vmin 0 12.845025825087218vmin currentColor;
}
.background span:nth-child(25) {
color: #a9a0bb;
top: 82%;
left: 77%;
animation-duration: 211s;
animation-delay: -150s;
transform-origin: 15vw -14vh;
box-shadow: 100vmin 0 12.825514275205975vmin currentColor;
}
.background span:nth-child(26) {
color: #4b6477;
top: 99%;
left: 95%;
animation-duration: 342s;
animation-delay: -118s;
transform-origin: -16vw -10vh;
box-shadow: 100vmin 0 13.09952938429165vmin currentColor;
}
.background span:nth-child(27) {
color: #a9a0bb;
top: 24%;
left: 43%;
animation-duration: 191s;
animation-delay: -249s;
transform-origin: 10vw 25vh;
box-shadow: -100vmin 0 12.948079018854608vmin currentColor;
}
.background span:nth-child(28) {
color: #888aa0;
top: 35%;
left: 83%;
animation-duration: 38s;
animation-delay: -5s;
transform-origin: -15vw 21vh;
box-shadow: -100vmin 0 12.884993041770123vmin currentColor;
}
.background span:nth-child(29) {
color: #4b6477;
top: 50%;
left: 19%;
animation-duration: 83s;
animation-delay: -367s;
transform-origin: -17vw 24vh;
box-shadow: 100vmin 0 12.943907699048086vmin currentColor;
}
.background span:nth-child(30) {
color: #4b6477;
top: 94%;
left: 43%;
animation-duration: 139s;
animation-delay: -151s;
transform-origin: 15vw 13vh;
box-shadow: -100vmin 0 13.188888046545854vmin currentColor;
}
.background span:nth-child(31) {
color: #4b6477;
top: 1%;
left: 30%;
animation-duration: 276s;
animation-delay: -118s;
transform-origin: 20vw -13vh;
box-shadow: 100vmin 0 12.67400347628477vmin currentColor;
}
.background span:nth-child(32) {
color: #a9a0bb;
top: 62%;
left: 91%;
animation-duration: 179s;
animation-delay: -95s;
transform-origin: 21vw 0vh;
box-shadow: 100vmin 0 13.078495151792405vmin currentColor;
}
.background span:nth-child(33) {
color: #a9a0bb;
top: 62%;
left: 24%;
animation-duration: 176s;
animation-delay: -417s;
transform-origin: 11vw 1vh;
box-shadow: -100vmin 0 13.180095388225237vmin currentColor;
}
.background span:nth-child(34) {
color: #4b6477;
top: 44%;
left: 7%;
animation-duration: 15s;
animation-delay: -23s;
transform-origin: -5vw 24vh;
box-shadow: -100vmin 0 12.99638150831451vmin currentColor;
}
.background span:nth-child(35) {
color: #888aa0;
top: 41%;
left: 18%;
animation-duration: 52s;
animation-delay: -66s;
transform-origin: 10vw 18vh;
box-shadow: 100vmin 0 12.881618623995024vmin currentColor;
}
.background span:nth-child(36) {
color: #888aa0;
top: 32%;
left: 75%;
animation-duration: 377s;
animation-delay: -252s;
transform-origin: 19vw -21vh;
box-shadow: -100vmin 0 13.235523992130878vmin currentColor;
}
.background span:nth-child(37) {
color: #4b6477;
top: 26%;
left: 96%;
animation-duration: 352s;
animation-delay: -359s;
transform-origin: -22vw -3vh;
box-shadow: 100vmin 0 13.203141789834469vmin currentColor;
}
.background span:nth-child(38) {
color: #4b6477;
top: 63%;
left: 64%;
animation-duration: 9s;
animation-delay: -70s;
transform-origin: 16vw 10vh;
box-shadow: 100vmin 0 12.63072769188053vmin currentColor;
}
.background span:nth-child(39) {
color: #a9a0bb;
top: 69%;
left: 81%;
animation-duration: 56s;
animation-delay: -361s;
transform-origin: -17vw 11vh;
box-shadow: 100vmin 0 13.123746520776026vmin currentColor;
}
.background span:nth-child(40) {
color: #888aa0;
top: 54%;
left: 33%;
animation-duration: 142s;
animation-delay: -2s;
transform-origin: 4vw 24vh;
box-shadow: 100vmin 0 13.216474278399133vmin currentColor;
}
.background span:nth-child(41) {
color: #4b6477;
top: 56%;
left: 10%;
animation-duration: 65s;
animation-delay: -105s;
transform-origin: 3vw -24vh;
box-shadow: 100vmin 0 13.322200697362886vmin currentColor;
}
.background span:nth-child(42) {
color: #4b6477;
top: 2%;
left: 39%;
animation-duration: 213s;
animation-delay: -62s;
transform-origin: 4vw 10vh;
box-shadow: -100vmin 0 12.580279613916804vmin currentColor;
}
.background span:nth-child(43) {
color: #888aa0;
top: 100%;
left: 49%;
animation-duration: 12s;
animation-delay: -71s;
transform-origin: 9vw -21vh;
box-shadow: 100vmin 0 13.356960223158397vmin currentColor;
}
.background span:nth-child(44) {
color: #a9a0bb;
top: 75%;
left: 59%;
animation-duration: 286s;
animation-delay: -81s;
transform-origin: -6vw 18vh;
box-shadow: 100vmin 0 12.718648874626872vmin currentColor;
}
.background span:nth-child(45) {
color: #888aa0;
top: 22%;
left: 12%;
animation-duration: 87s;
animation-delay: -298s;
transform-origin: -17vw 5vh;
box-shadow: 100vmin 0 13.066314361220197vmin currentColor;
}
</style>
<script>
@ -1073,53 +627,7 @@
</div>
<div id="container">
</div>
<div class="background">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long