mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-26 04:48:29 +00:00
Add files via upload
This commit is contained in:
parent
10ef9193b0
commit
a22388a24b
10
iframe.html
10
iframe.html
@ -177,6 +177,16 @@ function loadIframe(){ // this is pretty important if you want to avoid camera
|
|||||||
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":false}, '*');};
|
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":false}, '*');};
|
||||||
iframeContainer.appendChild(button);
|
iframeContainer.appendChild(button);
|
||||||
|
|
||||||
|
var button = document.createElement("button");
|
||||||
|
button.innerHTML = "Start Recording";
|
||||||
|
button.onclick = function(){iframe.contentWindow.postMessage({"record":true}, '*');};
|
||||||
|
iframeContainer.appendChild(button);
|
||||||
|
|
||||||
|
var button = document.createElement("button");
|
||||||
|
button.innerHTML = "Stop Recording";
|
||||||
|
button.onclick = function(){iframe.contentWindow.postMessage({"record":false}, '*');};
|
||||||
|
iframeContainer.appendChild(button);
|
||||||
|
|
||||||
var button = document.createElement("button");
|
var button = document.createElement("button");
|
||||||
button.innerHTML = "Say Hello";
|
button.innerHTML = "Say Hello";
|
||||||
button.onclick = function(){iframe.contentWindow.postMessage({"sendChat":"Hello!"}, '*');};
|
button.onclick = function(){iframe.contentWindow.postMessage({"sendChat":"Hello!"}, '*');};
|
||||||
|
|||||||
49
index.html
49
index.html
@ -55,7 +55,7 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
|
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
|
||||||
<link rel="stylesheet" href="./main.css?ver=48" />
|
<link rel="stylesheet" href="./main.css?ver=52" />
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.min.js"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body id="main" class="hidden">
|
<body id="main" class="hidden">
|
||||||
@ -67,18 +67,21 @@
|
|||||||
<link itemprop="url" href="./media/obsNinja_logo_full.png" />
|
<link itemprop="url" href="./media/obsNinja_logo_full.png" />
|
||||||
</span>
|
</span>
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=29"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=29"></script>
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=179"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=181"></script>
|
||||||
<input id="zoomSlider" type="range" style="display: none;" />
|
<input id="zoomSlider" type="range" style="display: none;" />
|
||||||
<div id="header">
|
<div id="header">
|
||||||
|
|
||||||
<a id="logoname" href="./" style="text-decoration: none; color: white; margin: 2px;">
|
<a id="logoname" href="./" style="text-decoration: none; color: white; margin: 2px;">
|
||||||
<span data-translate="logo-header">
|
<span data-translate="logo-header">
|
||||||
<font id="qos">O</font>BS.Ninja
|
<font id="qos">O</font>BS.Ninja
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div id="head1" style="display: inline-block; padding:1px; position: relative;">
|
<div id="head1" style="display: inline-block; padding:1px; position: relative;">
|
||||||
<input type="text" autocorrect="off" autocapitalize="none" id="joinroomID" name="joinroomID" size="22" placeholder="Join by Room Name here" alt="Enter a room name to join" title="Enter a room name to quick join" onkeyup="jumptoroom(event)"/>
|
<input type="text" autocorrect="off" autocapitalize="none" id="joinroomID" name="joinroomID" size="22" placeholder="Join by Room Name here" alt="Enter a room name to join" title="Enter a room name to quick join" onkeyup="jumptoroom(event)"/>
|
||||||
<button onclick="jumptoroom();" role="button" aria-pressed="false" alt="Join room" title="Join room" >GO</button>
|
<button onclick="jumptoroom();" role="button" aria-pressed="false" alt="Join room" title="Join room" >GO</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="head5" class="advanced"></div>
|
||||||
<div id="head3" style="display: inline-block;" class="advanced">
|
<div id="head3" style="display: inline-block;" class="advanced">
|
||||||
<font style="color: #888;" id="copythisurl">
|
<font style="color: #888;" id="copythisurl">
|
||||||
<span data-translate="copy-this-url">Copy this URL into an OBS "Browser Source"</span> <i style="color: #CCC;" class="las la-long-arrow-alt-right"></i>
|
<span data-translate="copy-this-url">Copy this URL into an OBS "Browser Source"</span> <i style="color: #CCC;" class="las la-long-arrow-alt-right"></i>
|
||||||
@ -145,7 +148,7 @@
|
|||||||
<i class="toggleSize my-float las la-dot-circle" style="position: relative;" aria-hidden="true"></i>
|
<i class="toggleSize my-float las la-dot-circle" style="position: relative;" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<span id="miniPerformer" style="pointer-events: auto;" class="advanced"></span>
|
<span id="miniPerformer" style="pointer-events: auto;" class="advanced"></span>
|
||||||
<span id="rooms" style="padding-top:3px;pointer-events: auto;color:#fff;"></span>
|
<span id="rooms" style="padding-top:3px;padding-left:6px;pointer-events: auto;color:#fff;"></span>
|
||||||
|
|
||||||
<div id="hangupbutton2" onmousedown="event.preventDefault(); event.stopPropagation();" title="Cancel the Director's Video/Audio" onclick="hangup2()" class="advanced float" tabindex="25" role="button" aria-pressed="false" onkeyup="enterPressedClick(event,this);" style="cursor: pointer;" alt="Disconnect Direcotor's cam">
|
<div id="hangupbutton2" onmousedown="event.preventDefault(); event.stopPropagation();" title="Cancel the Director's Video/Audio" onclick="hangup2()" class="advanced float" tabindex="25" role="button" aria-pressed="false" onkeyup="enterPressedClick(event,this);" style="cursor: pointer;" alt="Disconnect Direcotor's cam">
|
||||||
<i class="toggleSize my-float las la-phone rotate225" aria-hidden="true"></i>
|
<i class="toggleSize my-float las la-phone rotate225" aria-hidden="true"></i>
|
||||||
@ -164,7 +167,7 @@
|
|||||||
<span
|
<span
|
||||||
id="helpbutton"
|
id="helpbutton"
|
||||||
title="Show Help Info"
|
title="Show Help Info"
|
||||||
onclick="alert('For support, please browse https://reddit.com/r/obsninja or join the live chat on Discord at https://discord.obs.ninja.\n\nThe Wiki also contains many help guides and advanced settings, located at https://wiki.obs.ninja.\n\nTo access the video stats menu, hold CTRL (command) and Left-Click on a video. Most video issues can be fixed by using Wired Internet instead of Wi-Fi.')"
|
onclick="warnUser('For support, please browse https://reddit.com/r/obsninja or join the live chat on Discord at https://discord.obs.ninja.\n\nThe Wiki also contains many help guides and advanced settings, located at https://wiki.obs.ninja.\n\nTo access the video stats menu, hold CTRL (command) and Left-Click on a video. Most video issues can be fixed by using Wired Internet instead of Wi-Fi.')"
|
||||||
style="cursor: pointer; display:none;"
|
style="cursor: pointer; display:none;"
|
||||||
alt="How to Use This with OBS"
|
alt="How to Use This with OBS"
|
||||||
>
|
>
|
||||||
@ -786,13 +789,13 @@
|
|||||||
<input type="checkbox" data-param="&l" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&l" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Ask for Display Name
|
Ask for display name
|
||||||
<Br />
|
<Br />
|
||||||
<label class="switch" title="Display Names will be shown in the bottom-left corner of videos">
|
<label class="switch" title="Display Names will be shown in the bottom-left corner of videos">
|
||||||
<input type="checkbox" data-param="&sl" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&sl" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Show Display Names
|
Show display names
|
||||||
</div>
|
</div>
|
||||||
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px;">
|
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px;">
|
||||||
<label class="switch" title="Request 1080p60 from the Guest instead of 720p60, if possible">
|
<label class="switch" title="Request 1080p60 from the Guest instead of 720p60, if possible">
|
||||||
@ -805,13 +808,13 @@
|
|||||||
<input type="checkbox" data-param="&ad" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&ad" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Auto-select Default Microphone
|
Auto-select default microphone
|
||||||
<Br />
|
<Br />
|
||||||
<label class="switch" title="The default camera device will selected automatically">
|
<label class="switch" title="The default camera device will selected automatically">
|
||||||
<input type="checkbox" data-param="&vd" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&vd" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Auto-select Default Camera
|
Auto-select default camera
|
||||||
<Br />
|
<Br />
|
||||||
<label class="switch" title="The guest won't have access to changing camera settings or screenshare">
|
<label class="switch" title="The guest won't have access to changing camera settings or screenshare">
|
||||||
<input type="checkbox" data-param="&ns" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&ns" onchange="updateLink(1,this);">
|
||||||
@ -824,50 +827,50 @@
|
|||||||
<input type="checkbox" data-param="&np" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&np" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Disable Self-Preview
|
Disable self-preview
|
||||||
<Br />
|
<Br />
|
||||||
<label class="switch" title="Guests will have an option to poke the Director by pressing a button">
|
<label class="switch" title="Guests will have an option to poke the Director by pressing a button">
|
||||||
<input type="checkbox" data-param="&hand" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&hand" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Display 'Raise-Hand' button
|
Display 'raise-hand' button
|
||||||
<Br />
|
<Br />
|
||||||
<label class="switch" title="Add an audio compressor to the guest's microphone">
|
<label class="switch" title="Add an audio compressor to the guest's microphone">
|
||||||
<input type="checkbox" data-param="&comp" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&comp" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Enable Audio Compressor
|
Enable audio compressor
|
||||||
<Br />
|
<Br />
|
||||||
<label class="switch" title="Add an Equalizer to the guest's microphone that the director can control">
|
<label class="switch" title="Add an Equalizer to the guest's microphone that the director can control">
|
||||||
<input type="checkbox" data-param="&eq" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&eq" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Enable Equalizer as Option
|
Enable equalizer as option
|
||||||
</div>
|
</div>
|
||||||
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px; height: 20px;">
|
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px; height: 20px;">
|
||||||
<label class="switch" title="The guest can only see the Director's video, if provided">
|
<label class="switch" title="The guest can only see the Director's video, if provided">
|
||||||
<input type="checkbox" data-param="&broadcast" id="broadcastSlider" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&broadcast" id="broadcastSlider" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Only see the Director's Feed
|
Only see the director's feed
|
||||||
<br />
|
<br />
|
||||||
<label class="switch" title="The guest's microphone will be muted on joining. They can unmute themselves.">
|
<label class="switch" title="The guest's microphone will be muted on joining. They can unmute themselves.">
|
||||||
<input type="checkbox" data-param="&m" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&m" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Mute Microphone by Default
|
Mute microphone by default
|
||||||
<Br />
|
<Br />
|
||||||
<label class="switch" title="Have the guest join muted, so only the director can Unmute the guest.">
|
<label class="switch" title="Have the guest join muted, so only the director can Unmute the guest.">
|
||||||
<input type="checkbox" data-param="&g=0" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="&g=0" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Unmute by Director Only
|
Unmute by director only
|
||||||
<Br />
|
<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">
|
||||||
<input type="checkbox" data-param="" id="obfuscate_director_1" onchange="updateLink(1,this);">
|
<input type="checkbox" data-param="" id="obfuscate_director_1" onchange="updateLink(1,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Obfuscate Link and Parameters
|
Obfuscate link and parameters
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -890,7 +893,7 @@
|
|||||||
<input type="checkbox" data-param="&sl" onchange="updateLink(3,this);">
|
<input type="checkbox" data-param="&sl" onchange="updateLink(3,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Show Display Names
|
Show display names
|
||||||
</div>
|
</div>
|
||||||
<div style="display:inline-block;top: 12px; height: 20px; position: relative; margin-left:10px;">
|
<div style="display:inline-block;top: 12px; height: 20px; position: relative; margin-left:10px;">
|
||||||
<label class="switch">
|
<label class="switch">
|
||||||
@ -904,7 +907,7 @@
|
|||||||
<input type="checkbox" data-param="&mono" onchange="updateLink(3,this);">
|
<input type="checkbox" data-param="&mono" onchange="updateLink(3,this);">
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
Force Mono Audio
|
Force mono audio
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -939,7 +942,7 @@
|
|||||||
|
|
||||||
<button data-action-type="addToScene" style="grid-column: 1;" data-value="0" title="Add this Video to any remote '&scene=1'" onclick="directEnable(this, event, 1);">
|
<button data-action-type="addToScene" style="grid-column: 1;" data-value="0" title="Add this Video to any remote '&scene=1'" onclick="directEnable(this, event, 1);">
|
||||||
<i class="las la-plus-square"></i>
|
<i class="las la-plus-square"></i>
|
||||||
<span data-translate="add-to-scene">Add to Scene</span>
|
<span data-translate="add-to-scene">add to scene</span>
|
||||||
</button>
|
</button>
|
||||||
<button data-action-type="mute-scene" style="grid-column: 2;" title="Remotely Mute this Audio in all remote '&scene' views" onclick="directMute(this, event);">
|
<button data-action-type="mute-scene" style="grid-column: 2;" title="Remotely Mute this Audio in all remote '&scene' views" onclick="directMute(this, event);">
|
||||||
<i class="las la-microphone-slash"></i>
|
<i class="las la-microphone-slash"></i>
|
||||||
@ -1072,7 +1075,11 @@
|
|||||||
<span data-translate="advanced-camera-settings"><i class="las la-sliders-h"></i> Video Settings</span>
|
<span data-translate="advanced-camera-settings"><i class="las la-sliders-h"></i> Video Settings</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<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="requestKeyframeScene(this, event);">
|
||||||
|
<i class="las la-first-aid"></i>
|
||||||
|
<span data-translate="force-keyframe">Rainbow Puke</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1289,7 +1296,7 @@
|
|||||||
<script type="text/javascript" id="main-js" src="./main.js" data-translation="blank"></script>
|
<script type="text/javascript" id="main-js" src="./main.js" data-translation="blank"></script>
|
||||||
<script type="text/javascript" crossorigin="anonymous" id="mixer-js" src="./mixer.js?ver=2"></script>
|
<script type="text/javascript" crossorigin="anonymous" id="mixer-js" src="./mixer.js?ver=2"></script>
|
||||||
-->
|
-->
|
||||||
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=168"></script>
|
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=174"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
setTimeout(function(){ // lazy load
|
setTimeout(function(){ // lazy load
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
|
|||||||
32
main.css
32
main.css
@ -139,6 +139,14 @@ button.grey {
|
|||||||
background-size: 50%;
|
background-size: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#miniPerformer>#previewWebcam{
|
||||||
|
width: 80px;
|
||||||
|
height: 45px;
|
||||||
|
margin: 5px;
|
||||||
|
background-color: #464749 !important;
|
||||||
|
background-size: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
#reportbutton{
|
#reportbutton{
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
@ -196,6 +204,15 @@ button.white:active {
|
|||||||
background-color: #0F131D;
|
background-color: #0F131D;
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
}
|
}
|
||||||
|
#head5 {
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
pointer-events: none;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
#overlayMsgs{
|
#overlayMsgs{
|
||||||
margin:0 auto;
|
margin:0 auto;
|
||||||
@ -516,7 +533,7 @@ button.btnArmTransferRoom:hover{
|
|||||||
}
|
}
|
||||||
|
|
||||||
button.btnArmTransferRoom.selected{
|
button.btnArmTransferRoom.selected{
|
||||||
background-color: var(--red-accent);
|
background-color: #840000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-height: 540px){
|
@media only screen and (max-height: 540px){
|
||||||
@ -554,6 +571,9 @@ button.btnArmTransferRoom.selected{
|
|||||||
#head4{
|
#head4{
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
#head5{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
#head2{
|
#head2{
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
@ -1127,6 +1147,7 @@ label {
|
|||||||
/* padding: 30px; */
|
/* padding: 30px; */
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
|
color: #636363
|
||||||
}
|
}
|
||||||
.fullcolumn {
|
.fullcolumn {
|
||||||
float: left;
|
float: left;
|
||||||
@ -2203,8 +2224,8 @@ span#guestTips {
|
|||||||
color: white;
|
color: white;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
background: rgba(0, 0, 0, .5);
|
background: rgba(0, 0, 0, .5);
|
||||||
pointer-events:none;
|
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
pointer-events:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2401,7 +2422,9 @@ input:checked + .slider:before {
|
|||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
z-index:1;
|
z-index:2;
|
||||||
|
width:400px;
|
||||||
|
max-width:90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alertModalInner {
|
.alertModalInner {
|
||||||
@ -2411,10 +2434,11 @@ input:checked + .slider:before {
|
|||||||
|
|
||||||
.alertModalClose {
|
.alertModalClose {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -2px;
|
top: -4px;
|
||||||
right: 4px;
|
right: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
|
font-size: 1.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alertModalBackdrop {
|
.alertModalBackdrop {
|
||||||
|
|||||||
469
main.js
469
main.js
@ -133,6 +133,28 @@ function updateURL(param, force = false, cleanUrl = false) {
|
|||||||
urlParams = new URLSearchParams(window.location.search);
|
urlParams = new URLSearchParams(window.location.search);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function warnUser(message){
|
||||||
|
// Allows for multiple alerts to stack better.
|
||||||
|
// Every modal and backdrop has an increasing z-index
|
||||||
|
// to block the previous modal
|
||||||
|
zindex = document.querySelectorAll('.alertModal').length;
|
||||||
|
message = message.replace(/\n/g,"<br />");
|
||||||
|
modalTemplate =
|
||||||
|
`<div class="alertModal" onclick="closeModal(this)" style="z-index:${zindex + 2}">
|
||||||
|
<div class="alertModalInner">
|
||||||
|
<span class='alertModalClose'>×</span>
|
||||||
|
<span class='alertModalMessage'>${message}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="alertModalBackdrop" style="z-index:${zindex + 1}"></div>`;
|
||||||
|
document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal(element){
|
||||||
|
element.nextElementSibling.outerHTML = ''; // Delete backdrop
|
||||||
|
element.outerHTML = ''; // Delete modal
|
||||||
|
}
|
||||||
|
|
||||||
var filename = false;
|
var filename = false;
|
||||||
try {
|
try {
|
||||||
filename = window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1);
|
filename = window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1);
|
||||||
@ -153,13 +175,13 @@ try {
|
|||||||
var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/'));
|
var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/'));
|
||||||
tmpHref = tmpHref + "/?" + filename;
|
tmpHref = tmpHref + "/?" + filename;
|
||||||
filename = false;
|
filename = false;
|
||||||
//alert("Please ensure your URL is correctly formatted.");
|
//warnUser("Please ensure your URL is correctly formatted.");
|
||||||
window.history.pushState({path: tmpHref.toString()}, '', tmpHref.toString());
|
window.history.pushState({path: tmpHref.toString()}, '', tmpHref.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filename = filename2.split("&")[0];
|
filename = filename2.split("&")[0];
|
||||||
if (filename2 != filename) {
|
if (filename2 != filename) {
|
||||||
alert("Warning: Please ensure your URL is correctly formatted.");
|
warnUser("Warning: Please ensure your URL is correctly formatted.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -204,13 +226,13 @@ var sanitizeStreamID = function(streamID) {
|
|||||||
if (streamID.length < 1) {
|
if (streamID.length < 1) {
|
||||||
streamID = session.generateStreamID(8);
|
streamID = session.generateStreamID(8);
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("No streamID was provided; one will be generated randomily.\n\nStream ID: " + streamID);
|
warnUser("No streamID was provided; one will be generated randomily.\n\nStream ID: " + streamID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var streamID_sanitized = streamID.replace(/[\W]+/g, "_");
|
var streamID_sanitized = streamID.replace(/[\W]+/g, "_");
|
||||||
if (streamID !== streamID_sanitized) {
|
if (streamID !== streamID_sanitized) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Info: Only AlphaNumeric characters should be used for the stream ID.\n\nThe offending characters have been replaced by an underscore");
|
warnUser("Info: Only AlphaNumeric characters should be used for the stream ID.\n\nThe offending characters have been replaced by an underscore");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (streamID_sanitized.length > 24) {
|
if (streamID_sanitized.length > 24) {
|
||||||
@ -283,13 +305,13 @@ var sanitizeRoomName = function(roomid) {
|
|||||||
var sanitized = roomid.replace(/[\W]+/g, "_");
|
var sanitized = roomid.replace(/[\W]+/g, "_");
|
||||||
if (sanitized !== roomid) {
|
if (sanitized !== roomid) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Info: Only AlphaNumeric characters should be used for the room name.\n\nThe offending characters have been replaced by an underscore");
|
warnUser("Info: Only AlphaNumeric characters should be used for the room name.\n\nThe offending characters have been replaced by an underscore");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sanitized.length > 30) {
|
if (sanitized.length > 30) {
|
||||||
sanitized = sanitized.substring(0, 30);
|
sanitized = sanitized.substring(0, 30);
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("The Room name should be less than 31 alPhaNuMeric characters long.\n\nWe will trim it to length.");
|
warnUser("The Room name should be less than 31 alPhaNuMeric characters long.\n\nWe will trim it to length.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sanitized;
|
return sanitized;
|
||||||
@ -306,13 +328,13 @@ var sanitizePassword = function(passwrd) {
|
|||||||
passwrd = passwrd.trim();
|
passwrd = passwrd.trim();
|
||||||
if (passwrd.length < 1) {
|
if (passwrd.length < 1) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("The password provided was blank.");
|
warnUser("The password provided was blank.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var sanitized = encodeURIComponent(passwrd);//.replace(/[\W]+/g, "_");
|
var sanitized = encodeURIComponent(passwrd);//.replace(/[\W]+/g, "_");
|
||||||
//if (sanitized !== passwrd) {
|
//if (sanitized !== passwrd) {
|
||||||
// if (!(session.cleanOutput)) {
|
// if (!(session.cleanOutput)) {
|
||||||
// alert("Info: Only AlphaNumeric characters should be used in the password.\n\nThe offending characters have been replaced by an underscore");
|
// warnUser("Info: Only AlphaNumeric characters should be used in the password.\n\nThe offending characters have been replaced by an underscore");
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
return sanitized;
|
return sanitized;
|
||||||
@ -671,7 +693,10 @@ if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(naviga
|
|||||||
|
|
||||||
if ((iOS) || (iPad)) {
|
if ((iOS) || (iPad)) {
|
||||||
window.addEventListener('resize', function() { // Safari is the new IE.
|
window.addEventListener('resize', function() { // Safari is the new IE.
|
||||||
|
var msg = {};
|
||||||
|
msg.requestSceneUpdate = true;
|
||||||
|
session.sendMessage(msg);
|
||||||
|
|
||||||
if ( window.matchMedia("(orientation: portrait)").matches ) {
|
if ( window.matchMedia("(orientation: portrait)").matches ) {
|
||||||
document.getElementsByTagName("html")[0].style.height = "100vh";
|
document.getElementsByTagName("html")[0].style.height = "100vh";
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
@ -691,7 +716,7 @@ if (/CriOS/i.test(navigator.userAgent) && (iOS || iPad)) {
|
|||||||
try {
|
try {
|
||||||
navigator.mediaDevices.getUserMedia;
|
navigator.mediaDevices.getUserMedia;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert("Chrome on this device does not support the required technology to use this site.\n\nPlease use Safari instead or update your iOS and browser version.");
|
warnUser("Chrome on this device does not support the required technology to use this site.\n\nPlease use Safari instead or update your iOS and browser version.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -849,7 +874,7 @@ if (urlParams.has('portrait') || urlParams.has('916') || urlParams.has('vertical
|
|||||||
if (urlParams.has('record')) {
|
if (urlParams.has('record')) {
|
||||||
if (safariVersion()) {
|
if (safariVersion()) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Your browser or device is not supported. Try Chrome if on macOS.");
|
warnUser("Your browser or device is not supported. Try Chrome if on macOS.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
session.recordLocal = urlParams.get('record');
|
session.recordLocal = urlParams.get('record');
|
||||||
@ -861,6 +886,9 @@ if (urlParams.has('record')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (urlParams.has('pcm')) {
|
||||||
|
session.pcm = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (urlParams.has('bigbutton')) {
|
if (urlParams.has('bigbutton')) {
|
||||||
session.bigmutebutton = true;
|
session.bigmutebutton = true;
|
||||||
@ -2173,7 +2201,7 @@ if (urlParams.has('turn')) {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("TURN server parameters were wrong.");
|
warnUser("TURN server parameters were wrong.");
|
||||||
}
|
}
|
||||||
errorlog(e);
|
errorlog(e);
|
||||||
}
|
}
|
||||||
@ -2188,7 +2216,7 @@ if (urlParams.has('privacy') || urlParams.has('private') || urlParams.has('relay
|
|||||||
session.configuration.iceTransportPolicy = "relay"; // https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate/address
|
session.configuration.iceTransportPolicy = "relay"; // https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate/address
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Privacy mode failed to configure.");
|
warnUser("Privacy mode failed to configure.");
|
||||||
}
|
}
|
||||||
errorlog(e);
|
errorlog(e);
|
||||||
}
|
}
|
||||||
@ -2308,6 +2336,20 @@ if (isIFrame) { // reduce CPU load if not needed.
|
|||||||
toggleSpeakerMute();
|
toggleSpeakerMute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("record" in e.data) {
|
||||||
|
if (e.data.record == false) { // mute
|
||||||
|
if ("recording" in session.videoElement) {
|
||||||
|
recordLocalVideo("stop");
|
||||||
|
}
|
||||||
|
} else if (e.data.record == true){
|
||||||
|
if ("recording" in session.videoElement) {
|
||||||
|
// already recording
|
||||||
|
} else {
|
||||||
|
recordLocalVideo("start");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ("volume" in e.data) {
|
if ("volume" in e.data) {
|
||||||
@ -2563,6 +2605,20 @@ eventer(messageEvent, function(e) { // this listens for child IFRAMES.
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function requestKeyframeScene(ele) {
|
||||||
|
var UUID = ele.dataset.UUID;
|
||||||
|
if (ele.dataset.active == "true") {
|
||||||
|
} else {
|
||||||
|
ele.dataset.active = "true";
|
||||||
|
ele.classList.add("pressed");
|
||||||
|
session.requestKeyframe(UUID, true);
|
||||||
|
setTimeout(function(el){
|
||||||
|
el.dataset.active = "false";
|
||||||
|
el.classList.remove("pressed");
|
||||||
|
}, 1000, ele)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function pokeIframeAPI(action, value = null, UUID = null) {
|
function pokeIframeAPI(action, value = null, UUID = null) {
|
||||||
if (!isIFrame){return;}
|
if (!isIFrame){return;}
|
||||||
try {
|
try {
|
||||||
@ -2695,7 +2751,7 @@ function applyEffects(track, stream) {
|
|||||||
|
|
||||||
var audioTracks = session.streamSrc.getAudioTracks();
|
var audioTracks = session.streamSrc.getAudioTracks();
|
||||||
|
|
||||||
session.streamSrc = session.canvas.captureStream(30);
|
session.streamSrc = session.canvas.captureStream(35);
|
||||||
|
|
||||||
audioTracks.forEach(function(trk) {
|
audioTracks.forEach(function(trk) {
|
||||||
session.streamSrc.addTrack(trk);
|
session.streamSrc.addTrack(trk);
|
||||||
@ -2716,10 +2772,10 @@ function applyEffects(track, stream) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
session.canvasSource.srcObject.addTrack(track, stream);
|
session.canvasSource.srcObject.addTrack(track, stream);
|
||||||
session.canvasSource.width = track.getSettings().width || 640;
|
session.canvasSource.width = 640;
|
||||||
session.canvasSource.height = track.getSettings().height || 360;
|
session.canvasSource.height = 360;
|
||||||
session.canvas.width = track.getSettings().width || 640;
|
session.canvas.width = 640;
|
||||||
session.canvas.height = track.getSettings().height || 360;
|
session.canvas.height = 360;
|
||||||
|
|
||||||
var audioTracks = session.streamSrc.getAudioTracks();
|
var audioTracks = session.streamSrc.getAudioTracks();
|
||||||
|
|
||||||
@ -2729,6 +2785,34 @@ function applyEffects(track, stream) {
|
|||||||
session.streamSrc.addTrack(trk);
|
session.streamSrc.addTrack(trk);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
session.canvasSource.requestVideoFrameCallback(draw2CanvasBlur);
|
||||||
|
session.canvasSource.requestVideoFrameCallback(segmentFilterBlur);
|
||||||
|
|
||||||
|
session.videoElement.srcObject = session.streamSrc;
|
||||||
|
warnlog("APPLY EFFECTS DONE");
|
||||||
|
} else if ((session.effects == 4) || (session.effects == 5)){
|
||||||
|
|
||||||
|
session.canvasSource.srcObject.getTracks().forEach(function(trk) {
|
||||||
|
session.canvasSource.srcObject.removeTrack(trk);
|
||||||
|
});
|
||||||
|
|
||||||
|
session.canvasSource.srcObject.addTrack(track, stream);
|
||||||
|
session.canvasSource.width = 512;
|
||||||
|
session.canvasSource.height = 288;
|
||||||
|
session.canvas.width = 512;
|
||||||
|
session.canvas.height = 288;
|
||||||
|
|
||||||
|
var audioTracks = session.streamSrc.getAudioTracks();
|
||||||
|
|
||||||
|
session.streamSrc = session.canvas.captureStream(30);
|
||||||
|
|
||||||
|
audioTracks.forEach(function(trk) {
|
||||||
|
session.streamSrc.addTrack(trk);
|
||||||
|
});
|
||||||
|
|
||||||
|
session.canvasSource.requestVideoFrameCallback(draw2CanvasGreen);
|
||||||
|
session.canvasSource.requestVideoFrameCallback(segmentFilterGreen);
|
||||||
|
|
||||||
session.videoElement.srcObject = session.streamSrc;
|
session.videoElement.srcObject = session.streamSrc;
|
||||||
warnlog("APPLY EFFECTS DONE");
|
warnlog("APPLY EFFECTS DONE");
|
||||||
} else {
|
} else {
|
||||||
@ -2738,6 +2822,53 @@ function applyEffects(track, stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function draw2CanvasBlur(now, metadata) { //
|
||||||
|
try {
|
||||||
|
if (mask) {
|
||||||
|
bodyPix.drawBokehEffect(session.canvas, session.canvasSource, mask, 3, 6, false);
|
||||||
|
}
|
||||||
|
} catch (e){
|
||||||
|
errorlog(e);
|
||||||
|
}
|
||||||
|
session.canvasSource.requestVideoFrameCallback(draw2CanvasBlur);
|
||||||
|
}
|
||||||
|
async function segmentFilterBlur(now, metadata) { // runs at like 15fps
|
||||||
|
//warnlog(".");
|
||||||
|
try {
|
||||||
|
if (net){
|
||||||
|
session.canvasSource.width = metadata.width;
|
||||||
|
session.canvasSource.height = metadata.height;
|
||||||
|
mask = await net.segmentPerson(session.canvasSource);
|
||||||
|
}
|
||||||
|
} catch (e){
|
||||||
|
errorlog(e);
|
||||||
|
}
|
||||||
|
session.canvasSource.requestVideoFrameCallback(segmentFilterBlur);
|
||||||
|
}
|
||||||
|
function draw2CanvasGreen(now, metadata) { // runs fast; maybe like 30fps
|
||||||
|
//warnlog("!");
|
||||||
|
try {
|
||||||
|
if (mask) {
|
||||||
|
bodyPix.drawMask(session.canvas, session.canvasSource, mask, 1, 0, false);
|
||||||
|
}
|
||||||
|
} catch (e){
|
||||||
|
// errorlog(e);
|
||||||
|
}
|
||||||
|
session.canvasSource.requestVideoFrameCallback(draw2CanvasGreen);
|
||||||
|
}
|
||||||
|
async function segmentFilterGreen(now, metadata) { // runs at like 15fps
|
||||||
|
//warnlog(".");
|
||||||
|
try {
|
||||||
|
session.canvasSource.width = metadata.width;
|
||||||
|
session.canvasSource.height = metadata.height;
|
||||||
|
var segment = await net.segmentPerson(session.canvasSource);
|
||||||
|
mask = bodyPix.toMask(segment, {r: 0, g: 0, b: 0, a: 0}, {r: 0, g: 255, b: 0, a: 255});
|
||||||
|
} catch (e){
|
||||||
|
// errorlog(e);
|
||||||
|
}
|
||||||
|
session.canvasSource.requestVideoFrameCallback(segmentFilterGreen);
|
||||||
|
}
|
||||||
|
|
||||||
function drawFace() {
|
function drawFace() {
|
||||||
var faceAlignment = (function() {
|
var faceAlignment = (function() {
|
||||||
var vid = session.canvasSource;
|
var vid = session.canvasSource;
|
||||||
@ -3249,26 +3380,33 @@ function printValues(obj) { // see: printViewStats
|
|||||||
|
|
||||||
|
|
||||||
function printMyStats(menu) { // see: setupStatsMenu
|
function printMyStats(menu) { // see: setupStatsMenu
|
||||||
|
|
||||||
var scrollLeft = getById("menuStatsBox").scrollLeft;
|
var scrollLeft = getById("menuStatsBox").scrollLeft;
|
||||||
var scrollTop = getById("menuStatsBox").scrollTop;
|
var scrollTop = getById("menuStatsBox").scrollTop;
|
||||||
menu.innerHTML = "";
|
menu.innerHTML = "";
|
||||||
|
|
||||||
session.stats.outbound_connections = Object.keys(session.pcs).length;
|
session.stats.outbound_connections = Object.keys(session.pcs).length;
|
||||||
session.stats.inbound_connections = Object.keys(session.rpcs).length;
|
session.stats.inbound_connections = Object.keys(session.rpcs).length;
|
||||||
printViewValues(session.stats);
|
|
||||||
|
|
||||||
function printViewValues(obj) {
|
function printViewValues(obj) {
|
||||||
|
|
||||||
|
if (!(document.getElementById("menuStatsBox"))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (var key in obj) {
|
for (var key in obj) {
|
||||||
if (typeof obj[key] === "object") {
|
if (typeof obj[key] === "object") {
|
||||||
printViewValues(obj[key]);
|
printViewValues(obj[key]);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (key.startsWith("_")){continue;}
|
||||||
|
|
||||||
var stat = sanitizeChat(key);
|
var stat = sanitizeChat(key);
|
||||||
var value = obj[key];
|
var value = obj[key];
|
||||||
if (typeof value == "string") {
|
if (typeof value == "string") {
|
||||||
value = sanitizeChat((value));
|
value = sanitizeChat((value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value === false){continue;}
|
||||||
|
|
||||||
if (key == 'local_relayIP') {
|
if (key == 'local_relayIP') {
|
||||||
value = "<a href='https://whatismyipaddress.com/ip/" + value + "' target='_blank'>" + value + "</a>";
|
value = "<a href='https://whatismyipaddress.com/ip/" + value + "' target='_blank'>" + value + "</a>";
|
||||||
@ -3291,21 +3429,105 @@ function printMyStats(menu) { // see: setupStatsMenu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printViewValues(session.stats);
|
||||||
menu.innerHTML += "<button onclick='session.forcePLI(null,event);' data-translate='send-keyframe-to-viewer'>Send Keyframe to Viewers</button>";
|
menu.innerHTML += "<button onclick='session.forcePLI(null,event);' data-translate='send-keyframe-to-viewer'>Send Keyframe to Viewers</button>";
|
||||||
for (var uuid in session.pcs) {
|
for (var uuid in session.pcs) {
|
||||||
|
printViewValues(session.pcs[uuid].stats);
|
||||||
|
menu.innerHTML += "<hr>";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
getById("menuStatsBox").scrollLeft = scrollLeft;
|
||||||
|
getById("menuStatsBox").scrollTop = scrollTop;
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateLocalStats(){
|
||||||
|
|
||||||
|
var totalBitrate = 0;
|
||||||
|
var cpuLimited = false;
|
||||||
|
for (var uuid in session.pcs) {
|
||||||
|
if ("video_bitrate_kbps" in session.pcs[uuid].stats){
|
||||||
|
totalBitrate+=session.pcs[uuid].stats.video_bitrate_kbps || 0;
|
||||||
|
}
|
||||||
|
if ("audio_bitrate_kbps" in session.pcs[uuid].stats){
|
||||||
|
totalBitrate+=session.pcs[uuid].stats.audio_bitrate_kbps || 0;
|
||||||
|
}
|
||||||
|
if ("quality_limitation_reason" in session.pcs[uuid].stats){
|
||||||
|
if (session.pcs[uuid].stats.quality_limitation_reason == "cpu"){
|
||||||
|
cpuLimited=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(function(UUID) {
|
setTimeout(function(UUID) {
|
||||||
|
if (!( session.pcs[UUID])){return;}
|
||||||
session.pcs[UUID].getStats().then(function(stats) {
|
session.pcs[UUID].getStats().then(function(stats) {
|
||||||
|
if ("audio_bitrate_kbps" in session.pcs[UUID].stats){
|
||||||
|
session.pcs[UUID].stats.audio_bitrate_kbps=0;
|
||||||
|
}
|
||||||
stats.forEach(stat => {
|
stats.forEach(stat => {
|
||||||
if (stat.type == "outbound-rtp") {
|
if (stat.type == "outbound-rtp") {
|
||||||
if (stat.kind == "video") {
|
if (stat.kind == "video") {
|
||||||
if ("qualityLimitationReason" in stat) {
|
if ("qualityLimitationReason" in stat) {
|
||||||
session.pcs[UUID].stats.quality_Limitation_Reason = stat.qualityLimitationReason;
|
session.pcs[UUID].stats.quality_limitation_reason = stat.qualityLimitationReason;
|
||||||
}
|
}
|
||||||
if ("framesPerSecond" in stat) {
|
if ("framesPerSecond" in stat) {
|
||||||
session.pcs[UUID].stats.resolution = stat.frameWidth + " x " + stat.frameHeight + " @ " + stat.framesPerSecond;
|
session.pcs[UUID].stats.resolution = stat.frameWidth + " x " + stat.frameHeight + " @ " + stat.framesPerSecond;
|
||||||
}
|
}
|
||||||
if ("encoderImplementation" in stat) {
|
if ("encoderImplementation" in stat) {
|
||||||
session.pcs[UUID].stats.encoder = stat.encoderImplementation;
|
session.pcs[UUID].stats.video_encoder = stat.encoderImplementation;
|
||||||
|
}
|
||||||
|
if ("bytesSent" in stat) {
|
||||||
|
if (session.pcs[UUID].stats._bytesSent){
|
||||||
|
if (session.pcs[UUID].stats._timestamp){
|
||||||
|
if (stat.timestamp){
|
||||||
|
session.pcs[UUID].stats.video_bitrate_kbps = parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSent)/(stat.timestamp - session.pcs[UUID].stats._timestamp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("timestamp" in stat) {
|
||||||
|
session.pcs[UUID].stats._timestamp = stat.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("bytesSent" in stat) {
|
||||||
|
session.pcs[UUID].stats._bytesSent = stat.bytesSent;
|
||||||
|
|
||||||
|
}
|
||||||
|
if ("retransmittedBytesSent" in stat) {
|
||||||
|
session.pcs[UUID].stats.retransmitted_bytes_sent = stat.retransmittedBytesSent;
|
||||||
|
}
|
||||||
|
if ("pliCount" in stat) {
|
||||||
|
session.pcs[UUID].stats.total_pli_count = stat.pliCount;
|
||||||
|
}
|
||||||
|
if ("keyFramesEncoded" in stat) {
|
||||||
|
session.pcs[UUID].stats.total_key_frames_encoded = stat.keyFramesEncoded;
|
||||||
|
}
|
||||||
|
if ("nackCount" in stat) {
|
||||||
|
session.pcs[UUID].stats.total_nack_ount = stat.nackCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (stat.kind == "audio") {
|
||||||
|
if ("bytesSent" in stat) {
|
||||||
|
if (session.pcs[UUID].stats._bytesSentAudio){
|
||||||
|
if (session.pcs[UUID].stats._timestamp2){
|
||||||
|
if (stat.timestamp){
|
||||||
|
if ("audio_bitrate_kbps" in session.pcs[UUID].stats){
|
||||||
|
session.pcs[UUID].stats.audio_bitrate_kbps += parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSentAudio)/(stat.timestamp - session.pcs[UUID].stats._timestamp2));
|
||||||
|
} else {
|
||||||
|
session.pcs[UUID].stats.audio_bitrate_kbps=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("timestamp" in stat) {
|
||||||
|
session.pcs[UUID].stats._timestamp2 = stat.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("bytesSent" in stat) {
|
||||||
|
session.pcs[UUID].stats._bytesSentAudio = stat.bytesSent;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (stat.type == "remote-candidate") {
|
} else if (stat.type == "remote-candidate") {
|
||||||
@ -3331,24 +3553,20 @@ function printMyStats(menu) { // see: setupStatsMenu
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
printViewValues(session.pcs[UUID].stats);
|
|
||||||
menu.innerHTML += "<hr>";
|
|
||||||
try {
|
|
||||||
getById("menuStatsBox").scrollLeft = scrollLeft;
|
|
||||||
getById("menuStatsBox").scrollTop = scrollTop;
|
|
||||||
} catch (e) {}
|
|
||||||
return;
|
return;
|
||||||
}).catch(() => {
|
|
||||||
printViewValues(session.pcs[UUID].stats);
|
|
||||||
menu.innerHTML += "<hr>";
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}, 0, uuid);
|
}, 0, uuid);
|
||||||
}
|
}
|
||||||
try {
|
var headerStats = "Viewers: ";
|
||||||
getById("menuStatsBox").scrollLeft = scrollLeft;
|
headerStats += Object.keys(session.pcs).length || 0;
|
||||||
getById("menuStatsBox").scrollTop = scrollTop;
|
headerStats += ", Upload (kbps): "+totalBitrate;
|
||||||
} catch (e) {}
|
if (cpuLimited){
|
||||||
|
headerStats += ", CPU Overloaded";
|
||||||
|
}
|
||||||
|
if (Object.keys(session.pcs).length){
|
||||||
|
getById("head5").classList.remove("advanced");
|
||||||
|
}
|
||||||
|
getById("head5").innerHTML = headerStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3374,7 +3592,6 @@ function updateStats(obsvc = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function toggleMute(apply = false) { // TODO: I need to have this be MUTE, toggle, with volume not touched.
|
function toggleMute(apply = false) { // TODO: I need to have this be MUTE, toggle, with volume not touched.
|
||||||
|
|
||||||
log("muting");
|
log("muting");
|
||||||
@ -4429,6 +4646,7 @@ function publishWebcam(btn = false) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function outboundAudioPipeline(stream) {
|
function outboundAudioPipeline(stream) {
|
||||||
if (session.disableWebAudio) {
|
if (session.disableWebAudio) {
|
||||||
return stream;
|
return stream;
|
||||||
@ -4678,7 +4896,6 @@ function changeHighEQ(highEQ, trackid = 0) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function audioGainNode(mediaStreamSource, audioContext) {
|
function audioGainNode(mediaStreamSource, audioContext) {
|
||||||
var gainNode = audioContext.createGain();
|
var gainNode = audioContext.createGain();
|
||||||
if (session.audioGain !== false) {
|
if (session.audioGain !== false) {
|
||||||
@ -4914,7 +5131,7 @@ function createRoom(roomname = false) {
|
|||||||
}
|
}
|
||||||
if (roomname.length == 0) {
|
if (roomname.length == 0) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Please enter a room name before continuing");
|
warnUser("Please enter a room name before continuing");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -5135,6 +5352,9 @@ function createRoomCallback(passAdd, passAdd2) {
|
|||||||
getById("chatbutton").classList.add("advanced");
|
getById("chatbutton").classList.add("advanced");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearInterval(session.updateLocalStatsInterval);
|
||||||
|
session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000);
|
||||||
|
|
||||||
if (session.autostart){
|
if (session.autostart){
|
||||||
press2talk(true);
|
press2talk(true);
|
||||||
} else {
|
} else {
|
||||||
@ -5421,11 +5641,11 @@ function requestOutputAudioStream() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
if (window.isSecureContext) {
|
if (window.isSecureContext) {
|
||||||
alert("An error has occured when trying to access the default audio device. The reason is not known.");
|
warnUser("An error has occured when trying to access the default audio device. The reason is not known.");
|
||||||
} else if ((iOS) || (iPad)) {
|
} else if ((iOS) || (iPad)) {
|
||||||
alert("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported.");
|
warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported.");
|
||||||
} else {
|
} else {
|
||||||
alert("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia");
|
warnUser("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5471,11 +5691,11 @@ function requestAudioStream() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
if (window.isSecureContext) {
|
if (window.isSecureContext) {
|
||||||
alert("An error has occured when trying to access the default audio device. The reason is not known.");
|
warnUser("An error has occured when trying to access the default audio device. The reason is not known.");
|
||||||
} else if ((iOS) || (iPad)) {
|
} else if ((iOS) || (iPad)) {
|
||||||
alert("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported.");
|
warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported.");
|
||||||
} else {
|
} else {
|
||||||
alert("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia");
|
warnUser("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6511,7 +6731,7 @@ async function getAudioOnly(selector, trackid = null, override = false) {
|
|||||||
if (override !== false) {
|
if (override !== false) {
|
||||||
if (err.name) {
|
if (err.name) {
|
||||||
if (err.constraint) {
|
if (err.constraint) {
|
||||||
alert(err['name'] + ": " + err['constraint']);
|
warnUser(err['name'] + ": " + err['constraint']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7045,7 +7265,7 @@ async function grabScreen(quality = 0, audio = true, videoOnEnd = false) {
|
|||||||
if (!navigator.mediaDevices.getDisplayMedia) {
|
if (!navigator.mediaDevices.getDisplayMedia) {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
alert("Sorry, your browser is not supported. Please use the desktop versions of Firefox or Chrome instead");
|
warnUser("Sorry, your browser is not supported. Please use the desktop versions of Firefox or Chrome instead");
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -7283,7 +7503,7 @@ async function grabScreen(quality = 0, audio = true, videoOnEnd = false) {
|
|||||||
}
|
}
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
alert(err);
|
warnUser(err);
|
||||||
}, 1); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported
|
}, 1); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7600,9 +7820,9 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel
|
|||||||
} else {
|
} else {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
if (iOS) {
|
if (iOS) {
|
||||||
alert("An error occured. Closing existing tabs in Safari may solve this issue.");
|
warnUser("An error occured. Closing existing tabs in Safari may solve this issue.");
|
||||||
} else {
|
} else {
|
||||||
alert("Error: Could not start video source.\n\nTypically this means the Camera is already be in use elsewhere. Most webcams can only be accessed by one program at a time.\n\nTry a different camera or perhaps try re-plugging in the device.");
|
warnUser("Error: Could not start video source.\n\nTypically this means the Camera is already be in use elsewhere. Most webcams can only be accessed by one program at a time.\n\nTry a different camera or perhaps try re-plugging in the device.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
activatedPreview = true;
|
activatedPreview = true;
|
||||||
@ -7617,7 +7837,7 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel
|
|||||||
getById('gowebcam').innerHTML = "Problem with Camera";
|
getById('gowebcam').innerHTML = "Problem with Camera";
|
||||||
}
|
}
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Unknown error: 'NavigatorUserMediaError'");
|
warnUser("Unknown error: 'NavigatorUserMediaError'");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (e.name === "timedOut") {
|
} else if (e.name === "timedOut") {
|
||||||
@ -7626,7 +7846,7 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel
|
|||||||
getById('gowebcam').innerHTML = "Problem with Camera";
|
getById('gowebcam').innerHTML = "Problem with Camera";
|
||||||
}
|
}
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert(e.message);
|
warnUser(e.message);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -7643,9 +7863,9 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel
|
|||||||
}
|
}
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
if (session.width || session.height || session.framerate) {
|
if (session.width || session.height || session.framerate) {
|
||||||
alert("Camera failed to load.\n\nPlease ensure your camera supports the resolution and framerate that has been manually specified. Perhaps use &quality=0 instead.");
|
warnUser("<i class='las la-exclamation-circle'></i> Camera failed to load.\n\nPlease ensure your camera supports the resolution and framerate that has been manually specified. Perhaps use &quality=0 instead.");
|
||||||
} else {
|
} else {
|
||||||
alert("Camera failed to load.\n\nPlease make sure it is not already in use by another application.\n\nPlease make sure you have accepted the camera permissions.");
|
warnUser("<i class='las la-exclamation-circle'></i> Camera failed to load.\n\nPlease make sure it is not already in use by another application.\n\nPlease make sure you have accepted the camera permissions.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9526,7 +9746,7 @@ function setupWebcamSelection(stream = null) {
|
|||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
errorlog("6597");
|
errorlog("6597");
|
||||||
errorlog(error);
|
errorlog(error);
|
||||||
//setTimeout(function(){alert("Failed to change audio output destination.");},1);
|
//setTimeout(function(){warnUser("Failed to change audio output destination.");},1);
|
||||||
});
|
});
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
@ -9836,7 +10056,7 @@ function requestBasicPermissions(constraint = {
|
|||||||
log("Setting Timer for getUserMedia");
|
log("Setting Timer for getUserMedia");
|
||||||
timerBasicCheck = setTimeout(function() {
|
timerBasicCheck = setTimeout(function() {
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Camera Access Request Timed Out\nDid you accept camera permissions? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling NDI tools.\n\nPlease also ensure that your camera and audio devices are correctly connected and not already in use. You may also need to refresh the page.");
|
warnUser("Camera Access Request Timed Out\nDid you accept camera permissions? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling NDI tools.\n\nPlease also ensure that your camera and audio devices are correctly connected and not already in use. You may also need to refresh the page.");
|
||||||
}
|
}
|
||||||
}, 10000);
|
}, 10000);
|
||||||
}
|
}
|
||||||
@ -9870,7 +10090,7 @@ function requestBasicPermissions(constraint = {
|
|||||||
//permission denied in browser
|
//permission denied in browser
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
alert("Permissions denied. Please ensure you have allowed the mic/camera permissions.");
|
warnUser("Permissions denied. Please ensure you have allowed the mic/camera permissions.");
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -9880,7 +10100,7 @@ function requestBasicPermissions(constraint = {
|
|||||||
//permission denied in browser
|
//permission denied in browser
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
alert(err);
|
warnUser(err);
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9891,11 +10111,11 @@ function requestBasicPermissions(constraint = {
|
|||||||
errorlog(e);
|
errorlog(e);
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
if (window.isSecureContext) {
|
if (window.isSecureContext) {
|
||||||
alert("An error has occured when trying to access the webcam or microphone. The reason is not known.");
|
warnUser("An error has occured when trying to access the webcam or microphone. The reason is not known.");
|
||||||
} else if ((iOS) || (iPad)) {
|
} else if ((iOS) || (iPad)) {
|
||||||
alert("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported.");
|
warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported.");
|
||||||
} else {
|
} else {
|
||||||
alert("Error acessing camera or microphone.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia");
|
warnUser("Error acessing camera or microphone.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10197,7 +10417,7 @@ if ((session.view) && (session.roomid === false)) {
|
|||||||
play();
|
play();
|
||||||
} else if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) { // Safari on Desktop does require pop up
|
} else if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) { // Safari on Desktop does require pop up
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
alert("Safari requires us to ask for an audio permission to use peer-to-peer technology. You will need to accept it in a moment if asked to view this live video");
|
warnUser("Safari requires us to ask for an audio permission to use peer-to-peer technology. You will need to accept it in a moment if asked to view this live video");
|
||||||
}
|
}
|
||||||
navigator.mediaDevices.getUserMedia({
|
navigator.mediaDevices.getUserMedia({
|
||||||
audio: true
|
audio: true
|
||||||
@ -10747,7 +10967,7 @@ function updateMessages() {
|
|||||||
var time = timeSince(messageList[i].time);
|
var time = timeSince(messageList[i].time);
|
||||||
var msg = document.createElement("div");
|
var msg = document.createElement("div");
|
||||||
////// KEEP THIS IN /////////
|
////// KEEP THIS IN /////////
|
||||||
console.log(messageList[i].msg); // Display Recieved messages for View-Only clients.
|
console.log(messageList[i].msg); // Display received messages for View-Only clients.
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
if (messageList[i].type == "sent") {
|
if (messageList[i].type == "sent") {
|
||||||
msg.innerHTML = messageList[i].msg + " <i><small> <small>- " + time + "</small></small></i>";
|
msg.innerHTML = messageList[i].msg + " <i><small> <small>- " + time + "</small></small></i>";
|
||||||
@ -10970,6 +11190,9 @@ function recordVideo(target, event, videoKbps = false) { // event.currentTarget,
|
|||||||
|
|
||||||
if (videoKbps) {
|
if (videoKbps) {
|
||||||
options.mimeType = "video/webm";
|
options.mimeType = "video/webm";
|
||||||
|
if (session.pcm){
|
||||||
|
options.mimeType += ";codecs=pcm";
|
||||||
|
}
|
||||||
if (videoKbps < 1000) {
|
if (videoKbps < 1000) {
|
||||||
options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio
|
options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio
|
||||||
} else {
|
} else {
|
||||||
@ -11028,7 +11251,7 @@ function recordVideo(target, event, videoKbps = false) { // event.currentTarget,
|
|||||||
session.requestRateLimit(35, UUID);
|
session.requestRateLimit(35, UUID);
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
alert("an error occured with the media recorder; stopping recording");
|
warnUser("an error occured with the media recorder; stopping recording");
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -11038,7 +11261,7 @@ function recordVideo(target, event, videoKbps = false) { // event.currentTarget,
|
|||||||
session.requestRateLimit(35, UUID);
|
session.requestRateLimit(35, UUID);
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
alert("stream ended! stopping recording");
|
warnUser("stream ended! stopping recording");
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -11061,7 +11284,7 @@ function updateRemoteRecordButton(UUID, recorder) {
|
|||||||
elements[0].innerHTML = '<i class="lab la-apple"></i> Not Supported';
|
elements[0].innerHTML = '<i class="lab la-apple"></i> Not Supported';
|
||||||
if (!(session.cleanOutput)) {
|
if (!(session.cleanOutput)) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
alert('The remote browser does not support recording.\n\nPerhaps try local recording instead.');
|
warnUser('The remote browser does not support recording.\n\nPerhaps try local recording instead.');
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11278,6 +11501,8 @@ function recordLocalVideo(action = null, videoKbps = 6000) { // event.currentTar
|
|||||||
|
|
||||||
var writer = writable.getWriter();
|
var writer = writable.getWriter();
|
||||||
video.recorder.writer = writer;
|
video.recorder.writer = writer;
|
||||||
|
pokeIframeAPI("recording-started");
|
||||||
|
|
||||||
video.recorder.stop = function(restart = false) {
|
video.recorder.stop = function(restart = false) {
|
||||||
if (restart) {
|
if (restart) {
|
||||||
if (getById("recordLocalbutton").dataset.state == 2) {
|
if (getById("recordLocalbutton").dataset.state == 2) {
|
||||||
@ -11285,7 +11510,7 @@ function recordLocalVideo(action = null, videoKbps = 6000) { // event.currentTar
|
|||||||
getById("recordLocalbutton").style.backgroundColor = "";
|
getById("recordLocalbutton").style.backgroundColor = "";
|
||||||
getById("recordLocalbutton").innerHTML = '<i class="toggleSize my-float las la-exclamation" ></i>';
|
getById("recordLocalbutton").innerHTML = '<i class="toggleSize my-float las la-exclamation" ></i>';
|
||||||
restart = false;
|
restart = false;
|
||||||
alert("Media Recording Stopped due to an error.");
|
warnUser("Media Recording Stopped due to an error.");
|
||||||
} else {
|
} else {
|
||||||
getById("recordLocalbutton").innerHTML = '<i class="toggleSize my-float las la-spinner" ></i>';
|
getById("recordLocalbutton").innerHTML = '<i class="toggleSize my-float las la-spinner" ></i>';
|
||||||
getById("recordLocalbutton").dataset.state = "2";
|
getById("recordLocalbutton").dataset.state = "2";
|
||||||
@ -11310,6 +11535,7 @@ function recordLocalVideo(action = null, videoKbps = 6000) { // event.currentTar
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
writer.close();
|
writer.close();
|
||||||
|
pokeIframeAPI("recording-stopped");
|
||||||
try {
|
try {
|
||||||
if (session.directorUUID) {
|
if (session.directorUUID) {
|
||||||
var msg = {};
|
var msg = {};
|
||||||
@ -11347,6 +11573,9 @@ function recordLocalVideo(action = null, videoKbps = 6000) { // event.currentTar
|
|||||||
|
|
||||||
if (videoKbps) {
|
if (videoKbps) {
|
||||||
options.mimeType = "video/webm";
|
options.mimeType = "video/webm";
|
||||||
|
if (session.pcm){
|
||||||
|
options.mimeType += ";codecs=pcm";
|
||||||
|
}
|
||||||
if (videoKbps < 1000) {
|
if (videoKbps < 1000) {
|
||||||
options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio
|
options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio
|
||||||
} else {
|
} else {
|
||||||
@ -11778,69 +12007,47 @@ function audioMeterGuest(mediaStreamSource, UUID, trackid){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (session.effects==3) {
|
|
||||||
|
if ((session.effects==3) || (session.effects==4) || (session.effects==5)){
|
||||||
|
var mask = null;
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
var script2 = document.createElement('script');
|
var script2 = document.createElement('script');
|
||||||
var net = false;
|
var net = false;
|
||||||
var segmentation = false;
|
|
||||||
var imgTmp = new Image();
|
|
||||||
var canvasTmp = document.createElement('canvas');
|
|
||||||
canvasTmp.width=640;
|
|
||||||
canvasTmp.height=360;
|
|
||||||
var ctxTmp = canvasTmp.getContext('2d');
|
|
||||||
ctxTmp.width=640;
|
|
||||||
ctxTmp.height=360;
|
|
||||||
script.onload = function() {
|
script.onload = function() {
|
||||||
document.head.appendChild(script2);
|
document.head.appendChild(script2);
|
||||||
}
|
}
|
||||||
script2.onload = function() {
|
if (session.effects==5){
|
||||||
|
script2.onload = function() {
|
||||||
//var calcBlurInterval = setInterval(function(){calcBlur();},66);
|
async function loadModel() {
|
||||||
var applyBlurInterval = setInterval(function(){applyBlur();},200);
|
net = await bodyPix.load({
|
||||||
if (session.canvas===null){return;}
|
architecture: 'ResNet50',
|
||||||
|
outputStride: 16,
|
||||||
async function applyBlur() {
|
multiplier: 1.0,
|
||||||
clearInterval(applyBlurInterval);
|
quantBytes: 4
|
||||||
try {
|
});
|
||||||
if (net===false){
|
log("LOADED MODEL"); // https://github.com/tensorflow/tfjs-models/tree/master/body-pix
|
||||||
net = await bodyPix.load({
|
|
||||||
architecture: 'MobileNetV1',
|
|
||||||
outputStride: 16,
|
|
||||||
multiplier: 0.75,
|
|
||||||
quantBytes: 2
|
|
||||||
});
|
|
||||||
log("LOADED MODEL"); // https://github.com/tensorflow/tfjs-models/tree/master/body-pix
|
|
||||||
if(session.canvas==null){
|
|
||||||
applyBlurInterval = setInterval(function(){applyBlur();},200);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
const backgroundBlurAmount = 3;
|
|
||||||
const edgeBlurAmount = 3;
|
|
||||||
ctxTmp.drawImage(session.canvasSource, 0, 0, 640, 360);
|
|
||||||
imgTmp.src = canvasTmp.toDataURL();
|
|
||||||
segmentation = await net.segmentPerson(imgTmp);
|
|
||||||
bodyPix.drawBokehEffect(session.canvas, imgTmp, segmentation, backgroundBlurAmount, edgeBlurAmount, false);
|
|
||||||
} catch(e){
|
|
||||||
errorlog(e);
|
|
||||||
session.canvasCtx.drawImage(session.canvasSource, 0, 0,session.canvas.width, session.canvas.height);
|
|
||||||
}
|
|
||||||
window.requestAnimationFrame(applyBlur);
|
|
||||||
} catch (e){
|
|
||||||
clearInterval(applyBlurInterval);
|
|
||||||
applyBlurInterval = setInterval(function(){applyBlur();},200);
|
|
||||||
}
|
}
|
||||||
|
loadModel();
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
script2.onload = function() {
|
||||||
|
async function loadModel() {
|
||||||
|
net = await bodyPix.load({
|
||||||
|
architecture: 'MobileNetV1',
|
||||||
|
outputStride: 16,
|
||||||
|
multiplier: 0.75,
|
||||||
|
quantBytes: 2
|
||||||
|
});
|
||||||
|
log("LOADED MODEL"); // https://github.com/tensorflow/tfjs-models/tree/master/body-pix
|
||||||
|
}
|
||||||
|
loadModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
script.type = 'text/javascript';
|
script.type = 'text/javascript';
|
||||||
script2.type = 'text/javascript';
|
script2.type = 'text/javascript';
|
||||||
script.src = "https://cdnjs.cloudflare.com/ajax/libs/tensorflow/1.2.1/tf.min.js"; // dynamically load this only if its needed. Keeps loading time down for all..
|
script.src = "https://cdnjs.cloudflare.com/ajax/libs/tensorflow/1.2.1/tf.min.js"; // dynamically load this only if its needed. Keeps loading time down for all..
|
||||||
script2.src = "https://cdn.jsdelivr.net/npm/@tensorflow-models/body-pix@2.1.0/dist/body-pix.min.js";
|
script2.src = "https://cdn.jsdelivr.net/npm/@tensorflow-models/body-pix@2.0.0/dist/body-pix.min.js";
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.midiHotkeys) {
|
if (session.midiHotkeys) {
|
||||||
@ -12233,31 +12440,3 @@ window.addEventListener("online", function (e) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function warnUser(message){
|
|
||||||
|
|
||||||
// Allows for multiple alerts to stack better.
|
|
||||||
// Every modal and backdrop has an increasing z-index
|
|
||||||
// to block the previous modal
|
|
||||||
zindex = document.querySelectorAll('.alertModal').length;
|
|
||||||
|
|
||||||
modalTemplate =
|
|
||||||
`<div class="alertModal" onclick="closeModal(this)" style="z-index:${zindex + 2}">
|
|
||||||
<div class="alertModalInner">
|
|
||||||
<span class='alertModalClose'>×</span>
|
|
||||||
<span class='alertModalMessage'>${message}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="alertModalBackdrop" style="z-index:${zindex + 1}"></div>`
|
|
||||||
|
|
||||||
// Insert modal at body end
|
|
||||||
document.body.insertAdjacentHTML("beforeend", modalTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeModal(element){
|
|
||||||
// Delete backdrop
|
|
||||||
element.nextElementSibling.outerHTML = ''
|
|
||||||
|
|
||||||
// Delete modal
|
|
||||||
element.outerHTML = ''
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user