reconnection fix

This commit is contained in:
steveseguin 2023-05-26 11:20:27 -04:00
parent 0afd701fb9
commit aadc5fbf3e
5 changed files with 178 additions and 45 deletions

View File

@ -56,7 +56,7 @@
<meta property="twitter:image" content="./media/vdoNinja_logo_full.png" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<link rel="stylesheet" href="./main.css?ver=332" />
<link rel="stylesheet" href="./main.css?ver=335" />
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.js"></script>
<style id="lightbox-animations" type="text/css"></style>
<!-- <link rel="manifest" href="manifest.json" /> -->
@ -83,7 +83,7 @@
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=47"></script>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=643"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=645"></script>
<input id="zoomSlider" type="range" style="display: none;" />
<span id="electronDragZone" style="pointer-events: none; z-index:-10; position:absolute;top:0;left:0;width:100%;height:2%;-webkit-app-region: drag;min-height:20px;"></span>
<div id="header">
@ -1558,6 +1558,10 @@
<i class="las la-file-upload"></i>
<span data-translate="request-upload"> Request File</span>
</button>
<button class="mainonly advanced" data-action-type="mirror-guest" title="Mirror the video of this guest globally" onclick="requestMirrorGuest(this)">
<i class="las la-file-upload"></i>
<span data-translate="mirror-guest"> Mirror Video</span>
</button>
</div>
<!-- Row of Channels -->
@ -1830,16 +1834,15 @@
<br />
<button onclick="toggleSettings()" class="toggleSettings"><i class="las la-chevron-right"></i><b><span data-translate="close-settings">Close Settings</span></b></button>
<button id='advancedOptionsAudio' onclick="this.classList.toggle('highlight');toggle(getById('popupSelector_constraints_audio'),false,false); getById('popupSelector_constraints_loading').style.visibility='visible';" class="advancedToggle">
<button id='advancedOptionsAudio' onclick="toggleAudioUser(this);" class="advancedToggle">
<i class="las la-sliders-h" style="position:relative;"></i> <b>Audio</b></button>
<button id='advancedOptionsCamera' onclick="this.classList.toggle('highlight');toggle(getById('popupSelector_constraints_video'),false,false); getById('popupSelector_constraints_loading').style.visibility='visible';" class="advancedToggle">
<button id='advancedOptionsCamera' onclick="toggleVideoUser(this);" class="advancedToggle">
<i class="las la-sliders-h" style="position:relative;"></i> <b>Video</b></button>
<span class="mobileHide">
<button id='advancedOptionsGeneral' onclick="this.classList.toggle('highlight');toggle(getById('popupSelector_user_settings'),false,false); getById('popupSelector_user_settings').style.visibility='visible';" >
<i class="las la-user-cog" style="position:relative;"></i> <b><span data-translate="user">User</span></b></button>
</span>
<button id='advancedOptionsGeneral' onclick="toggleUserUser(this);" >
<i class="las la-user-cog" style="position:relative;"></i> <b><span data-translate="user">User</span></b></button>
<span id="popupSelector_constraints_audio" class="popupSelector_constraints" style="display: none;">
@ -1852,22 +1855,24 @@
</span>
<span id="popupSelector_user_settings" style="display: none; visibility:hidden">
<label title="Choose a hotkey for Hold-to-Talk. If using Electron Capture, elevate privilleges to have it become global">Hold-to-Talk Hot-key</label>
<input type="text" id="pptHotKey" placeholder="press a key here" style="padding-left: 7px;" onkeypress="event.preventDefault;event.stopPropagation();return false;" onkeyup="event.preventDefault;event.stopPropagation();return false;" onkeydown="setHotKey();"/>
<button onclick="setHotKey(false);" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">Clear</button>
<br /><br />
<label title="Draw on the Screen">Draw-on-Screen</label>
<button id='startDrawScreen' title="CTRL (cmd) + ALT + D to toggle" onclick="drawOnScreen();" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">Enable</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.erase();" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">Clear</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.stop();" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;" title="CTRL (cmd) + ALT + D to toggle" >Stop</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='red' style="background-color:red; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='blue' style="background-color:blue; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='green' style="background-color:green; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='black' style="background-color:black; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='white' style="background-color:white; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">🎨</button>
<br /><br />
<button class="generalButton" onclick="cycleStyleOptions();" id='toggleWaveformButton' title="Audio-only sources can be stylized in different ways">Cycle between several audio-visualizations styles</button>
<br />
<span class="mobileHide">
<label title="Choose a hotkey for Hold-to-Talk. If using Electron Capture, elevate privilleges to have it become global">Hold-to-Talk Hot-key</label>
<input type="text" id="pptHotKey" placeholder="press a key here" style="padding-left: 7px;" onkeypress="event.preventDefault;event.stopPropagation();return false;" onkeyup="event.preventDefault;event.stopPropagation();return false;" onkeydown="setHotKey();"/>
<button onclick="setHotKey(false);" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">Clear</button>
<br /><br />
<label title="Draw on the Screen">Draw-on-Screen</label>
<button id='startDrawScreen' title="CTRL (cmd) + ALT + D to toggle" onclick="drawOnScreen();" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">Enable</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.erase();" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">Clear</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.stop();" style="margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;" title="CTRL (cmd) + ALT + D to toggle" >Stop</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='red' style="background-color:red; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='blue' style="background-color:blue; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='green' style="background-color:green; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='black' style="background-color:black; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">✏️</button>
<button class='hidden drawActive' onclick="drawOnScreenObject.color(this);" data-color='white' style="background-color:white; margin: 0 0 0 4px; border-radius: 5px; padding: 3px 3px;">🎨</button>
<br /><br />
<button class="generalButton" onclick="cycleStyleOptions();" id='toggleWaveformButton' title="Audio-only sources can be stylized in different ways">Cycle between several audio-visualizations styles</button>
<br />
</span>
<button class="generalButton" onclick="clearStorage();" title="Clear site's local storage and settings">Clear site's local browser storage and saved settings</button>
</span>
@ -2484,11 +2489,11 @@
// session.hidehome = true; // If used, 'hide home' will make the landing page inaccessible, along with hiding a few go-home elements.
// session.record = false; // uncomment to block users from being able to record via vdo.ninja's built in recording function
</script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=818"></script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=821"></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=638"></script>
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=639"></script>
</body>
</html>

120
lib.js
View File

@ -462,6 +462,10 @@ try{
var macOS = navigator.userAgent.indexOf('Mac OS X') != -1;
macOS = macOS && !(iOS || iPad);
var Firefox = navigator.userAgent.indexOf("Firefox")>=0;
if (Firefox){
Firefox = parseInt(navigator.userAgent.split("irefox/").pop()) || true;
}
var Android = navigator.userAgent.toLowerCase().indexOf("android") > -1; //&& ua.indexOf("mobile");
var ChromeVersion = getChromeVersion();
var OperaGx = isOperaGX();
@ -3439,6 +3443,11 @@ function createRichVideoElement(UUID){ // this function is used to check and gen
}, { once: true });
if (session.rpcs[UUID].mirrorState){
applyMirrorGuest(session.rpcs[UUID].mirrorState, session.rpcs[UUID].videoElement);
} else if (session.rpcs[UUID].mirrorState===false){
applyMirrorGuest(session.rpcs[UUID].mirrorState, session.rpcs[UUID].videoElement);
}
setupIncomingVideoTracking(session.rpcs[UUID].videoElement, UUID);
pokeIframeAPI("video-element-created", "videosource_"+UUID, UUID);
@ -6020,6 +6029,32 @@ eventer(messageEvent, function(e) { // this listens for child IFRAMES.
});
function requestMirrorGuest(ele){
var UUID = ele.dataset.UUID;
if (ele.value == 1) {
ele.value = 0;
ele.classList.remove("pressed"); ele.ariaPressed = "false";
applyMirrorGuest(false, session.rpcs[UUID].videoElement);
var data = {};
data.mirrorGuestTarget = UUID;
data.mirrorGuestState = false;
session.sendPeers(data, false, UUID);
data.mirrorGuestTarget = true;
session.sendPeers(data, UUID);
} else {
ele.value = 1;
ele.classList.add("pressed"); ele.ariaPressed = "true";
applyMirrorGuest(true, session.rpcs[UUID].videoElement);
var data = {};
data.mirrorGuestTarget = UUID;
data.mirrorGuestState = true;
session.sendPeers(data, false, UUID);
data.mirrorGuestTarget = true;
session.sendPeers(data, UUID);
}
}
function requestKeyframeScene(ele) {
var UUID = ele.dataset.UUID;
if (ele.value == 1) {
@ -11380,6 +11415,8 @@ function hangup2() {
getById("miniPerformer").innerHTML = "";
getById("press2talk").dataset.enabled = false;
getById("screensharebutton").classList.add("hidden");
getById("screenshare2button").classList.add("hidden");
getById("screenshare3button").classList.add("hidden");
getById("settingsbutton").classList.add("hidden");
getById("mutebutton").classList.add("hidden");
getById("hangupbutton2").classList.add("hidden");
@ -11387,7 +11424,6 @@ function hangup2() {
getById("controlButtons").classList.remove("hidden");
//getById("mutespeakerbutton").classList.add("hidden");
getById("mutevideobutton").classList.add("hidden");
getById("screenshare2button").classList.add("hidden");
getById("screensharebutton").classList.remove("green");
getById("screensharebutton").ariaPressed = "false";
@ -13242,6 +13278,7 @@ async function publishScreen() {
getById("settingsbutton").classList.add("hidden");
getById("screenshare2button").classList.add("hidden");
getById("screensharebutton").classList.add("hidden");
getById("screenshare3button").classList.add("hidden");
getById("queuebutton").classList.add("hidden");
} else {
getById("controlButtons").classList.add("hidden");
@ -15299,8 +15336,7 @@ function joinRoom(roomname) {
updateQueue();
pokeIframeAPI("joined-room-complete");
if (session.include.length){
var keys = Object.keys(session.waitingWatchList);
if (session.include.length){ // we want to request what hasn't been requested already, since we are joining a room.
session.include.forEach(sid =>{
if (sid in session.waitingWatchList){
return;
@ -15310,6 +15346,7 @@ function joinRoom(roomname) {
});
}
}, function(error) {
return {};
});
@ -16517,10 +16554,10 @@ async function createDirectorScreenshareOnlyBox() { // sstype=3
getById("groups").remove();
if (session.hidesololinks==false){ // won't be updating the solo link to a view-only one ever, since director is always expected to be in a room
controls.innerHTML += "<div style='padding:5px;word-wrap: break-word; overflow:hidden; white-space: nowrap; overflow: hidden; font-size:0.7em; text-overflow: ellipsis;' title='A direct solo view of the video/audio stream with nothing else'> \
controls.innerHTML += "<div class='soloButton' title='A direct solo view of the video/audio stream with nothing else'> \
<a class='soloLink advanced task' data-menu='context-menu' data-sololink='true' data-drag='1' draggable='true' onclick='copyFunction(this,event)' \
value='" + soloLink + "' href='" + soloLink + "'/>" + sanitizeChat(soloLink) + "</a>\
<button class='pull-right controlsGrid' onclick='copyFunction(this.previousElementSibling,event)'><i class='las la-user'></i><span translate='copy-solo-view-link'>copy solo view link</span></button>\
<button class='pull-right controlsGrid' style='width:100%' onclick='copyFunction(this.previousElementSibling,event)'><i class='las la-user'></i><span translate='copy-solo-view-link'>copy solo view link</span></button>\
</div>\
<div id='groups'></div>";
if (session.directorUUID){
@ -19117,6 +19154,10 @@ function applyMirror(mirror) { // true unmirrors as its already mirrored
session.videoElement.style = "";
}
if (session.permaMirrored){
mirror = !mirror;
}
if (mirror) {
if (session.mirrored && session.flipped) {
session.videoElement.style.transform = "scaleX(-1) scaleY(-1)" + transFlip;
@ -22094,7 +22135,7 @@ function setEncodings(sender, settings=null, callback=null, cbarg=null){
log(settings);
// if Firefox, see if I can do something other than Active?
// if old Firefox, see if I can do something other than Active?
if (!changed){
log("SET ENCODINGS MATCH INPUT; skipping");
@ -22109,8 +22150,8 @@ function setEncodings(sender, settings=null, callback=null, cbarg=null){
setEncodings(sender);
return;
}
if (Firefox){
if (Firefox && !(Firefox >=110)){ // https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpEncodingParameters now supported in v110, but old versions will need this function still
if ("active" in settings){
warnlog("Firefox does not support track active state. We will use enable/disable for that instead.");
if (FirefoxSenders.sender){
@ -22434,8 +22475,31 @@ async function press2talk(clean = false) {
getById("press2talk").dataset.enabled = true;
getById("press2talk").outerHTML = "";
getById("mutebutton").classList.remove("hidden");
getById("screensharebutton").classList.remove("hidden");
getById("hangupbutton2").classList.remove("hidden");
if (session.screenshareType===3){
getById("screenshare3button").className = "float";
getById("screensharebutton").className = "float hidden";
getById("screenshare2button").className = "float hidden";
} else if (session.screenshareType===1){
getById("screensharebutton").className = "float";
getById("screenshare3button").className = "float hidden";
getById("screenshare2button").className = "float hidden";
} else if (session.screenshareType===2){
getById("screenshare2button").className = "float";
getById("screensharebutton").className = "float hidden";
getById("screenshare3button").className = "float hidden";
} else if (session.broadcast===null){
// sstype=1, since in self-broadcast mode
getById("screensharebutton").className = "float";
getById("screenshare2button").className = "float hidden";
getById("screenshare3button").className = "float hidden";
} else {
// sstype=3, since not in broadcast mode
getById("screensharebutton").className = "float hidden";
getById("screenshare2button").className = "float hidden";
getById("screenshare3button").className = "float";
}
checkBasicStreamsExist();
@ -27591,6 +27655,8 @@ var updateCameraConstraintsNext = false;
async function updateCameraConstraints(constraint, value = null, ctrl=false, UUID=false, save=true) {
log("updateCameraConstraintsBusy..?");
if (updateCameraConstraintsBusy){
updateCameraConstraintsNext = [constraint, value, ctrl, UUID, save];
return;
@ -27631,6 +27697,9 @@ async function updateCameraConstraints(constraint, value = null, ctrl=false, UUI
updateCameraConstraintsNext = false;
return e;
}
log("updateCameraConstraintsNext:");
log(updateCameraConstraintsNext);
try {
if (track0.getSettings){
var cameraSettings = {};
@ -27763,9 +27832,17 @@ async function updateCameraConstraints(constraint, value = null, ctrl=false, UUI
constraits.colorTemperature = session.cameraConstraints.colorTemperature.max;
}
}
} else if ((constraint=="whiteBalanceMode") && (value=="continuous")){
var constraits = {[constraint]: value};
if (session.mobile && ChromeVersion){ // trying to fix the issue that chrome mobile has.
constraits.colorTemperature = 5000;
}
} else if (constraint=="colorTemperature"){
var constraits = {[constraint]: value};
constraits.whiteBalanceMode = "manual";
} else if (constraint=="aspectRatio"){
var constraits = {[constraint]: value};
if (session.currentCameraConstraints && session.currentCameraConstraints.frameRate){
@ -27787,6 +27864,7 @@ async function updateCameraConstraints(constraint, value = null, ctrl=false, UUI
await track0.applyConstraints({
advanced: [constraits]
}).then(() => {
log("applied constraint");
if (save){
if (track0.getSettings){ // -- updateCameraConstraints
if (session.currentCameraConstraints.deviceId){
@ -27840,6 +27918,28 @@ async function updateCameraConstraints(constraint, value = null, ctrl=false, UUI
return;
}
function toggleAudioUser(ele){
ele.classList.toggle('highlight');
toggle(getById('popupSelector_constraints_audio'),false,false);
getById('popupSelector_constraints_loading').style.visibility='visible';
getById('popupSelector_constraints_video').style.display = "none";
getById('popupSelector_user_settings').style.display = "none";
}
function toggleVideoUser(ele){
ele.classList.toggle('highlight');
toggle(getById('popupSelector_constraints_video'),false,false);
getById('popupSelector_constraints_loading').style.visibility='visible';
getById('popupSelector_user_settings').style.display = "none";
getById('popupSelector_constraints_audio').style.display = "none";
}
function toggleUserUser(ele){
ele.classList.toggle('highlight');
toggle(getById('popupSelector_user_settings'),false,false);
getById('popupSelector_user_settings').style.visibility='visible';
getById('popupSelector_constraints_video').style.display = "none";
getById('popupSelector_constraints_audio').style.display = "none";
}
function setupWebcamSelection(miconly=false) {
log("setupWebcamSelection();");
@ -29340,7 +29440,7 @@ function pauseVideo(videoEle, update=true){
} else if (link.getAttribute("data-action") === "Mirror") {
if ((taskItemInContext.id == "videosource") || (taskItemInContext.id == "previewWebcam")){
session.mirrored = !session.mirrored;
applyMirror(false, taskItemInContext);
applyMirror(false);
log("session.mirrored");
} else {
if ("mirror" in taskItemInContext){

View File

@ -1878,6 +1878,9 @@ div#chatBody a {
#SubControlButtons > div i {
font-size: 28px;
}
#hangupbutton {
margin-left: 15px;
}
}
@media only screen and (max-height: 500px) {
@ -1903,8 +1906,11 @@ div#chatBody a {
margin: 3px;
}
#SubControlButtons > div i {
font-size: 24px;
font-size: 26px;
}
#hangupbutton {
margin-left: 15px!important;
}
}
@media only screen and (max-height: 410px) {
@ -1915,11 +1921,12 @@ div#chatBody a {
margin: 3px;
}
#SubControlButtons > div i {
font-size: 24px;
font-size: 26px;
}
#chatModule{
margin-bottom: 40px;
}
}
@media only screen and (max-width: 360px) {
@ -1932,6 +1939,9 @@ div#chatBody a {
#SubControlButtons > div i {
font-size: 20px;
}
#hangupbutton {
margin-left: unset;
}
}
@media only screen and (max-height: 360px) {
@ -5278,6 +5288,7 @@ input[type='checkbox'], input[type='radio'] {
overflow: auto;
z-index: 4;
-webkit-app-region: no-drag;
padding-bottom: 80px;
}
#popupSelector label {
color: black;
@ -5292,7 +5303,7 @@ input[type='checkbox'], input[type='radio'] {
padding: 4px;
}
.darktheme #popupSelector{
background-color:black;
background-color: #0004;
}
.popupSelector_constraints{
margin-top: 10px;

27
main.js
View File

@ -463,6 +463,11 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.meshcast = urlParams.get('meshcast') || "any";
meshcast(true);
}
if (urlParams.has('meshcastcode') || urlParams.has('mccode')) {
session.meshcastCode = urlParams.get('meshcastcode') || urlParams.get('mccode') || false
}
if (urlParams.has('nomeshcast')) {
session.noMeshcast = urlParams.get('nomeshcast') || true;
@ -2239,14 +2244,15 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (session.forceRetry){
setTimeout(function(){
clearInterval(session.forceRetryTimeout);
session.forceRetryTimeout = setTimeout(function(){
try {
session.retryWatchInterval();
} catch(e){
warnlog(e);
clearTimeout(this);
}
},30000);
}, session.forceRetry*1000);
}
try {
@ -5536,10 +5542,14 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
window.addEventListener("online", function (e) {
log("Back ONLINE");
closeModal();
session.ping();
if (!session.retryWatchInterval()){ // ask for the streams again to watch
session.ping(); // if no streams requested, let's ping instead.
}
});
function updateConnectionStatus() {
try{
if (!session.stats){
return;
@ -5551,12 +5561,19 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
var miniInfo = {};
miniInfo.con = Connection.type;
session.sendMessage({"miniInfo":miniInfo});
if (!session.retryWatchInterval()){ // ask for the streams again to watch
session.ping(); // if no streams requested, let's ping instead.
}
} else { // connection state changed, but doesn't seem like it actually changed...
session.ping(); // if no streams requested, let's ping instead.
}
session.stats.network_type = Connection.type;
session.ping();
} catch(e){warnlog(e);};
} catch(e){warnlog(e);}
}
try {

File diff suppressed because one or more lines are too long