syncing current alpha

This commit is contained in:
steveseguin 2023-04-06 09:52:17 -04:00
parent 97b50c3514
commit 9b205e2f53
8 changed files with 438 additions and 150 deletions

File diff suppressed because one or more lines are too long

View File

@ -20,16 +20,12 @@ iframe {
display:block;
}
</style>
</head>
<body>
<script>
(function(w) {
w.URLSearchParams = w.URLSearchParams || function(searchString) {
var self = this;
@ -57,20 +53,39 @@ if (urlEdited !== window.location.search){
}
var urlParams = new URLSearchParams(urlEdited);
var path = window.location.host+window.location.pathname.split("/").slice(0,-1).join("/");
var password = urlParams.get("passwords") || urlParams.get("password") || urlParams.get("pw") || urlParams.get("p") || null;
var rooms = "";
if (urlParams.has("rooms")){
rooms = urlParams.get("rooms");
if (urlParams.has("rooms") || urlParams.has("room") || urlParams.has("r")){
rooms = urlParams.get("rooms") || urlParams.get("room") || urlParams.get("r");
rooms = rooms.split(",");
var password = prompt("Enter the password for the rooms; leave blank for none");
if (password == null){
password = prompt("Enter the password for the rooms; leave blank for none");
}
if (password){
password = "&password="+password;
password = password.split(",");
} else {
password = "";
}
rooms.forEach(room=>{
loadIframes("https://"+path+"/../?clean&hidecodirectors&director="+room+password);
});
for (var i = 0;i<rooms.length;i++){
var pass = "";
if (password && (password.length>i)){
pass = decodeURIComponent(password[i]);
if (pass){
pass = "&password="+pass;
}
} else if (password[0]){
pass = decodeURIComponent(password[0]);
if (pass){
pass = "&password="+pass;
}
}
loadIframes("https://"+path+"/../?clean&hidecodirectors&director="+rooms[i]+pass);
}
} else {
document.write("To use, comma separate the room names. ie: https://vdo.ninja/examples/multi?rooms=xxxx,yyy,ccc");
}
@ -78,7 +93,16 @@ if (urlParams.has("rooms")){
function loadIframes(url){
var iframe = document.createElement("iframe");
iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;";
iframe.src = url;
var params = window.location.search || "";
if (params.startsWith("?")){
params = params.slice(1);
iframe.src = url + "&" + params
} else {
iframe.src = url + params
}
document.body.appendChild(iframe);
}

135
examples/rotated.html Normal file
View File

@ -0,0 +1,135 @@
<html>
<head><title>Rotated Scene</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
<style>
body{
padding:0;
margin:0;
background-color:#003;
width:100%;
height:100%;
}
iframe {
width:100%;
height:470px;
border:0;
margin:0;
padding:0;
display:block;
width: 100vh;
height: 100vw;
transform: rotate(90deg);
transform-origin: 0 0;
left: 100vw;
position: relative;
top: 0;
}
</style>
</head>
<body>
<script>
function removeStorage(cname){
localStorage.removeItem(cname);
}
function clearStorage(){
localStorage.clear();
if (!session.cleanOutput){
warnUser("The local storage and saved settings have been cleared", 1000);
}
}
function setStorage(cname, cvalue, hours=9999){ // not actually a cookie
var now = new Date();
var item = {
value: cvalue,
expiry: now.getTime() + (hours * 60 * 60 * 1000),
};
try{
localStorage.setItem(cname, JSON.stringify(item));
}catch(e){errorlog(e);}
}
function getStorage(cname) {
try {
var itemStr = localStorage.getItem(cname);
} catch(e){
errorlog(e);
return;
}
if (!itemStr) {
return "";
}
var item = JSON.parse(itemStr);
var now = new Date();
if (now.getTime() > item.expiry) {
localStorage.removeItem(cname);
return "";
}
return item.value;
}
(function(w) {
w.URLSearchParams = w.URLSearchParams || function(searchString) {
var self = this;
searchString = searchString.replace("??", "?");
self.searchString = searchString;
self.get = function(name) {
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString);
if (results == null) {
return null;
} else {
return decodeURI(results[1]) || 0;
}
};
};
})(window);
var urlEdited = window.location.search.replace(/\?\?/g, "?");
urlEdited = urlEdited.replace(/\?/g, "&");
urlEdited = urlEdited.replace(/\&/, "?");
if (urlEdited !== window.location.search){
window.history.pushState({path: urlEdited.toString()}, '', urlEdited.toString());
}
var urlParams = new URLSearchParams(urlEdited);
var rotate = parseInt(urlParams.get("rotate")) || "90";
var sdfasd = decodeURIComponent(urlParams.get("link") || "") || getStorage("savedRotateLink") || "";
var linktoload = sdfasd || prompt("What URL would you like to load? (rotated)");
setStorage("savedRotateLink", linktoload, 99999);
var iframe = document.createElement("iframe");
iframe.allow = "document-domain;encrypted-media;sync-xhr;usb;web-share;cross-origin-isolated;accelerometer;midi;geolocation;autoplay;camera;microphone;fullscreen;picture-in-picture;display-capture;";
iframe.src = linktoload;
if (rotate=="180"){
iframe.style.transform = "rotate(180deg)";
iframe.style.width = "100vw";
iframe.style.height = "100vh";
iframe.style.transformOrigin = "0 0;";
iframe.style.position = "rotate(180deg)";
iframe.style.left = "100vw";
iframe.style.top = "100vh";
} else if (rotate=="270"){
iframe.style.transform = "rotate(270deg)";
iframe.style.left = "0";
iframe.style.top = "100vh";
}
document.body.appendChild(iframe);
</script>
</body>
</html>

View File

@ -28,13 +28,13 @@
<meta name="license" content="https://github.com/steveseguin/vdo.ninja/LICENSE.md" />
<meta name="sourcecode" content="https://github.com/steveseguin/vdo.ninja" />
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" />
<link rel="icon" type="image/png" sizes="32x32" href="./media/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="./media/favicon-16x16.png" />
<link rel="icon" href="./media/favicon.ico" />
<link itemprop="thumbnailUrl" href="./media/vdoNinja_logo_full.png" />
<link id="favicon1" rel="icon" type="image/png" sizes="32x32" href="./media/favicon-32x32.png" />
<link id="favicon2" rel="icon" type="image/png" sizes="16x16" href="./media/favicon-16x16.png" />
<link id="favicon3" rel="icon" href="./media/favicon.ico" />
<link id="thumbnailUrl" itemprop="thumbnailUrl" href="./media/vdoNinja_logo_full.png" />
<!-- Primary Meta Tags -->
<title>VDO.Ninja</title>
<meta name="title" content="VDO.Ninja" />
<meta id="metaTitle" name="title" content="VDO.Ninja" />
<meta name="description" content="Bring live video from your smartphone, computer, or friends directly into your Studio. 100% free." />
<meta name="author" content="Steve Seguin" />
<!-- Open Graph / Facebook -->
@ -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=272" />
<link rel="stylesheet" href="./main.css?ver=274" />
<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" /> -->
@ -81,9 +81,9 @@
<link itemprop="url" href="./media/vdoNinja_logo_full.png" />
</span>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=45"></script>
<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=589"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=606"></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">
@ -130,7 +130,7 @@
</div>
<div id="head6" class="hidden" data-translate="only-director-can-hear-you">Only the director can hear you currently.</div>
<div id="head7" class="hidden" data-translate="director-muted-you">The director has muted you.</div>
<div id="head8" class="hidden" data-translate="director-video-muted-you">The director has disabled your camera temporarily.</div>
</div>
<div id="controlButtons" class="hidden">
<div id="obsState" class="hidden" >ACTIVE</div>
@ -1386,7 +1386,7 @@
<span data-translate="voice-chat">Solo Talk</span>
</button>
<button data-action-type="solo-video" class="btn-HL-yellow advanced" title="Solo this video everywhere" onclick="requestInfocus(this);">
<button data-action-type="solo-video" class="btn-HL-yellow advanced" title="Solo this video everywhere. (Hold CTRL/CMD to just make video larger)" onclick="requestInfocus(this, event);">
<i class="las la-user"></i>
<span data-translate="solo-video">Highlight guest</span>
</button>
@ -1483,10 +1483,14 @@
<div class="group hidden" data-cluster="2">
<!-- General Controls -->
<div class="row two">
<button data-action-type="hide-guest" title="Hide this guest everywhere" onclick="remoteMuteVideo(this, event);">
<i class="las la-video-slash"></i>
<button data-action-type="hide-guest" title="Hide this guest everywhere" onclick="remoteHideVideo(this, event);">
<i class="las la-user-slash"></i>
<span data-translate="hide-guest">hide guest</span>
</button>
<button data-action-type="mute-video-guest" title="Disable this guest's video track" onclick="remoteMuteVideo(this, event);">
<i class="las la-video-slash"></i>
<span data-translate="mute-video-guest">disable video</span>
</button>
<button class="mainonly" data-action-type="toggle-remote-speaker" title="Toggle the remote guest's speaker output" onclick="remoteSpeakerMute(this, event);">
<i class="las la-volume-off"></i> <span data-translate="toggle-remote-speaker">Deafen Guest</span>
</button>
@ -1633,7 +1637,7 @@
<i class="las la-microphone-slash"></i>
<span data-translate="mute-scene">mute in scene</span>
</button>
<button data-action-type="solo-video" class="btn-HL-yellow" title="Solo this video everywhere" onclick="requestInfocus(this);">
<button data-action-type="solo-video" class="btn-HL-yellow" title="Solo this video everywhere. (Hold CTRL/CMD to just make video larger)" onclick="requestInfocus(this, event);">
<i class="las la-user"></i>
<span data-translate="solo-video-director">Highlight</span>
</button>
@ -2069,7 +2073,7 @@
<input id="trbSettingInput" type="range" min="0" max="4000" value="500" onchange="getById('trbSettingInputManual').value=this.value;changeTRB(this);" oninput="getById('trbSettingInputFeedback').innerHTML = this.value;" style="width:calc(100% - 60px);display:inline-block;" />
<input id="trbSettingInputManual" min="0" value="500" onchange="getById('trbSettingInput').value=this.value;changeTRB(this);" oninput="getById('trbSettingInputFeedback').innerHTML = this.value;" style="width:42px;display:inline-block;text-align: center;" />
<span style="margin: 20px 0 0 0;display:block" id='highlightDirectorSpan' title="Only the director's video will be visible to guests and within group scenes">
<span style="margin: 20px 0 0 0;display:block" id='highlightDirectorSpan' title="Only the director's video will be visible to guests and within group scenes. (Hold CTRL/CMD to just make video larger)">
<input id="highlightDirector" style="width: 15px; height: 15px; margin:10px;" name="highlightDirector" data-action-type="solo-video" type="checkbox" onchange="requestInfocus(this, event);" />
<label for="highlightDirector" data-translate="highlight-director-only-video-guests-will-see">Highlight Director (only video guests will see)</label>
</span>
@ -2493,11 +2497,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=701"></script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=711"></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=571"></script>
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=578"></script>
</body>
</html>

168
lib.js
View File

@ -945,6 +945,8 @@ function youveBeenTransferred(){
} else {
document.title = miscTranslations["transferred"];
}
hideHomeCheck();
}
async function confirmAlt(inputText, block=false){
@ -1251,6 +1253,7 @@ session.sceneSync = function(UUID){
session.obsStateSync = function(data2send=false, uid=false){
if (session.disableOBS){return;}
if (!window.obsstudio){return;} // this isn't OBS
// they can disable remote control via OBS brower source drop-down itself.
var needOptimize = false;
@ -1260,8 +1263,6 @@ session.obsStateSync = function(data2send=false, uid=false){
}
}
for (var UUID in session.rpcs){
if (uid && (uid!==UUID)){continue;} // target just a single connection.
@ -1362,6 +1363,7 @@ session.getOBSOptimization = function(msg, UUID){
function getOBSDetails(){
if (session.disableOBS){return false;}
if (!window.obsstudio){return;}
if (!("details" in session.obsState)){
session.obsState.details = {};
@ -3327,6 +3329,24 @@ function hideHomeCheck(){
getById("info").classList.add("permahide");
getById("helpbutton").classList.add("permahide");
}
if (urlParams.has('headertitle')){
let pageTitle = urlParams.get('headertitle') || "";
pageTitle = decodeURIComponent(pageTitle) || "";
document.title = pageTitle
getById("metaTitle").content = pageTitle;
}
if (urlParams.has('favicon')){
let favicon = "";
if (urlParams.get('favicon')){
favicon = decodeURIComponent(urlParams.get('favicon')) || "";
}
getById("favicon1").href = favicon;
getById("favicon2").href = favicon;
getById("favicon3").href = favicon;
}
}
function switchModes(state=null){
@ -5773,6 +5793,7 @@ async function changeAvatarImage(ev, ele, set=false){
if (session.avatar && session.avatar.timer){
clearInterval(session.avatar.timer);
session.avatar.timer=null;
}
if (!session.streamSrc){
@ -6155,6 +6176,7 @@ function setAvatarImage(tracks){
if (session.avatar && session.avatar.ready){
if (session.avatar && session.avatar.timer){
clearInterval(session.avatar.timer);
session.avatar.timer=null;
}
setupCanvas();
@ -6179,11 +6201,17 @@ function setAvatarImage(tracks){
}
if (session.avatar.naturalHeight && session.avatar.naturalHeight>maxH){
height = parseInt(session.avatar.naturalHeight/session.avatar.naturalWidth*maxW);
width = parseInt(maxH/session.avatar.naturalHeight * session.avatar.naturalWidth);
height = maxH;
if (width>maxW){
width = maxW;
height = parseInt(maxW/width * height);
}
} else if (session.avatar.naturalWidth && session.avatar.naturalWidth>maxW){
width = maxW;
height = parseInt(session.avatar.naturalWidth/session.avatar.naturalHeight*maxH);
height = parseInt(maxW/session.avatar.naturalWidth*session.avatar.naturalHeight);
} else {
width = session.avatar.naturalWidth;
height = session.avatar.naturalHeight;
@ -6200,7 +6228,7 @@ function setAvatarImage(tracks){
session.avatar.timer = setInterval(function(){
log("drawing");
session.canvasCtx.drawImage(session.avatar, 0, 0, session.canvas.width, session.canvas.height);
},2000);
},200); // too slow and it takes way too long for the video to udpate when a new guest joins
applyMirror(true);
@ -9462,6 +9490,8 @@ function printMyStats(menu) { // see: setupStatsMenu
function updateLocalStats(){
if (!session){return;}
var totalBitrate = 0;
var totalBitrate2 = 0;
var cpuLimited = false;
@ -10145,7 +10175,7 @@ function updateLocalStats(){
}
if (session.director || !session.roomid){ // show stats if the director or if not in a group room
if (session.director || !session.roomid){ // show stats if the director or if not in a group room
if (cpuLimited){
headerStats += ", <span style='color: #e69a0f;' title='Your CPU is maxed out; this can cause audio, sync, and quality issues.'>🔥 CPU Overloaded</span>";
}
@ -10624,19 +10654,40 @@ function toggleVideoMute(apply = false) { // TODO: I need to have this be MUTE,
if (apply) {
session.videoMuted = !session.videoMuted;
}
if (!session.remoteVideoMuted){
getById("head8").classList.add("hidden");
}
if (session.videoMuted == false) {
session.videoMuted = true;
getById("mutevideotoggle").className = "las la-video-slash my-float toggleSize";
if (!(session.cleanOutput)){
getById("mutevideobutton").className = "float2 red";
getById("header").classList.add("red2");
if (session.remoteVideoMuted){
getById("head8").classList.remove("hidden");
}
}
if (session.streamSrc) {
session.streamSrc.getVideoTracks().forEach((track) => {
track.enabled = false;
});
}
} else if (session.remoteVideoMuted){ // the director has muted this guest's video feed
session.videoMuted = false; // just setting it back to the pre-toggled state
getById("mutevideotoggle").className = "las la-video my-float toggleSize";
if (!(session.cleanOutput)){
getById("head8").classList.remove("hidden");
getById("header").classList.add("red2");
getById("mutevideobutton").className = "float";
}
if (session.streamSrc) {
session.streamSrc.getVideoTracks().forEach((track) => {
track.enabled = false;
});
}
} else {
session.videoMuted = false;
@ -10665,10 +10716,10 @@ function toggleVideoMute(apply = false) { // TODO: I need to have this be MUTE,
session.sendMessage(msg);
}
pokeIframeAPI("video-mute-state",session.videoMuted);
pokeIframeAPI("video-mute-state", (session.videoMuted || session.remoteVideoMuted));
if (!apply){
pokeAPI("videoMuted", session.videoMuted);
pokeAPI("videoMuted", (session.videoMuted || session.remoteVideoMuted));
}
}
@ -11317,6 +11368,10 @@ function syncOtherState(sid){
remoteMute(ele, false, true);
}
} else if (other == "hide-guest"){
if (changed){
remoteHideVideo(ele, true, true);
}
} else if (other == "mute-video-guest"){
if (changed){
remoteMuteVideo(ele, true, true);
}
@ -12116,24 +12171,24 @@ function toggleQualityGear3(){
}
}
function remoteMuteVideo(ele, event=false, skipSend=false) {
log("video mute");
function remoteHideVideo(ele, event=false, skipSend=false) {
log("video hide");
if (!event || ((event.ctrlKey) || (event.metaKey))) {
ele.children[1].innerHTML = miscTranslations["armed"]
ele.style.backgroundColor = "#BF3F3F";
Callbacks.push([remoteMuteVideo, ele, false]);
Callbacks.push([remoteHideVideo, ele, false]);
log("video queued");
return;
} else {
if (ele.value == 1) {
ele.value = 0;
ele.classList.remove("pressed");
ele.innerHTML = '<i class="las la-video-slash"></i> <span data-translate="hide-guest" >hide guest</span>';
ele.innerHTML = '<i class="las la-user-slash"></i> <span data-translate="hide-guest" >hide guest</span>';
} else {
ele.value = 1;
ele.classList.add("pressed");
ele.innerHTML = '<i class="las la-video-slash"></i> <span data-translate="unhide-guest" >un-hide</span>';
ele.innerHTML = '<i class="las la-user-slash"></i> <span data-translate="unhide-guest" >un-hide</span>';
}
miniTranslate(ele);
ele.style.backgroundColor = null;
@ -12162,18 +12217,68 @@ function remoteMuteVideo(ele, event=false, skipSend=false) {
syncDirectorState(ele);
}
pokeIframeAPI("director-video-mute-state", msg.directVideoMuted, ele.dataset.UUID);
pokeAPI("directorVideoMuted", msg.directVideoMuted, session.rpcs[ele.dataset.UUID].streamID);
pokeIframeAPI("director-video-hide-state", msg.directVideoMuted, ele.dataset.UUID);
pokeAPI("directorVideoHide", msg.directVideoMuted, session.rpcs[ele.dataset.UUID].streamID);
return msg.directVideoMuted;
}
function updateDirectorVideoMute(UUID) {
function remoteMuteVideo(ele, event=false, skipSend=false) {
log("video mute");
if (!event || ((event.ctrlKey) || (event.metaKey))) {
ele.children[1].innerHTML = miscTranslations["armed"]
ele.style.backgroundColor = "#BF3F3F";
Callbacks.push([remoteMuteVideo, ele, false]);
log("video queued");
return;
} else {
if (ele.value == 1) {
ele.value = 0;
ele.classList.remove("pressed");
ele.innerHTML = '<i class="las la-video-slash"></i> <span data-translate="mute-video-guest" >disable video</span>';
} else {
ele.value = 1;
ele.classList.add("pressed");
ele.innerHTML = '<i class="las la-video-slash"></i> <span data-translate="unmute-video-guest" >allow video</span>';
}
miniTranslate(ele);
ele.style.backgroundColor = null;
}
var msg = {};
if (ele.value == 0) {
msg.remoteVideoMuted = false;
} else {
msg.remoteVideoMuted = true;
}
if (!skipSend){
session.sendRequest(msg, ele.dataset.UUID)
syncDirectorState(ele);
}
pokeIframeAPI("remote-video-mute-state", msg.remoteVideoMuted, ele.dataset.UUID);
pokeAPI("remoteVideoMuted", msg.remoteVideoMuted, session.rpcs[ele.dataset.UUID].streamID);
return msg.remoteVideoMuted;
}
function updateDirectorVideoHide(UUID) {
var ele = document.querySelectorAll('[data-action-type="hide-guest"][data--u-u-i-d="' + UUID + '"]');
if (ele[0]) {
ele[0].value = 1;
ele[0].classList.add("pressed");
ele[0].innerHTML = '<i class="las la-video-slash"></i> <span data-translate="unhide-guest" >un-hide</span>';
ele[0].innerHTML = '<i class="las la-user-slash"></i> <span data-translate="unhide-guest" >un-hide</span>';
miniTranslate(ele[0]);
}
return true;
}
function updateDirectorVideoMute(UUID) {
var ele = document.querySelectorAll('[data-action-type="mute-video-guest"][data--u-u-i-d="' + UUID + '"]');
if (ele[0]) {
ele[0].value = 1;
ele[0].classList.add("pressed");
ele[0].innerHTML = '<i class="las la-video-slash"></i> <span data-translate="unmute-video-guest" >allow video</span>';
miniTranslate(ele[0]);
}
return true;
@ -20219,7 +20324,7 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel
var senders = getSenders2(UUID);
senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams?
if (sender.track && sender.track.kind == "video") {
sender.track.enabled = false;
sender.track.enabled = false; // I'm not entirely sure if I shoudl be doing this to a video stream... but I suppose new connections won't get a stream, and old connections will just replace it?
getById("mutevideobutton").classList.add("hidden"); // hide the mute button, so they can't unmute while no video.
//session.pcs[UUID].removeTrack(sender); // replace may not be supported by all browsers. eek.
//errorlog("DELETED SENDER");
@ -20241,6 +20346,7 @@ async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "sel
if (session.avatar && session.avatar.timer){
clearInterval(session.avatar.timer);
session.avatar.timer=null;
}
var sq = 0;
@ -20859,7 +20965,7 @@ function pushOutVideoTrack(track){
if (track.kind === "audio"){
session.applyIsolatedChat();
}
session.refreshScale();
session.refreshScale();
}
@ -33839,25 +33945,25 @@ function sendRawMIDI(input, UUID=false, streamID=false){
} else if (UUID && session.rpcs[UUID] && session.rpcs[UUID].allowMIDI){
session.sendRequest(msg, UUID);
} else if (streamID){
for (var UUID in session.rpcs){
if (session.rpcs[UUID].allowMIDI && (session.rpcs[UUID].streamID === streamID)){ // specific to gstreamer code aplication
session.sendRequest(msg, UUID)
for (var UID in session.rpcs){
if (session.rpcs[UID].allowMIDI && (session.rpcs[UID].streamID === streamID)){ // specific to gstreamer code aplication
session.sendRequest(msg, UID)
return; // only one stream ID should match
}
}
} else {
var list = [];
for (var UUID in session.pcs){
if (session.pcs[UUID].allowMIDI){
if (session.sendMessage(msg, UUID)){
list.push(UUID);
for (var UID in session.pcs){
if (session.pcs[UID].allowMIDI){
if (session.sendMessage(msg, UID)){
list.push(UID);
}
}
}
for (var UUID in session.rpcs){
if (session.rpcs[UUID].allowMIDI){ // specific to gstreamer code aplication
if (!list.includes(UUID)){
session.sendRequest(msg, UUID)
for (var UID in session.rpcs){
if (session.rpcs[UID].allowMIDI){ // specific to gstreamer code aplication
if (!list.includes(UID)){
session.sendRequest(msg, UID)
}
}
}

View File

@ -4545,6 +4545,8 @@ input:checked + .slider:before {
content: "\f095"; }
.la-gamepad:before {
content: "\f11b"; }
.la-user-slash:before {
content: "\f506"; }
.la-skull-crossbones:before {
content: "\f714"; }
.la-hand-paper:before {

20
main.js
View File

@ -373,9 +373,12 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.audioEffects = false; // disable audio inbound effects also.
session.audioMeterGuest = false;
window.addEventListener('resize', function() { // Safari is the new IE.
var msg = {};
msg.requestSceneUpdate = true;
session.sendMessage(msg);
if (session.ws){
var msg = {};
msg.requestSceneUpdate = true;
session.sendMessage(msg);
}
if ( window.matchMedia("(orientation: portrait)").matches ) {
document.getElementsByTagName("html")[0].style.height = "100vh";
@ -1456,6 +1459,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
}
}
if (urlParams.has('transparent') || urlParams.has('transparency')) { // sets the window to be transparent - useful for IFRAMES?
session.transparent=true;
@ -2487,9 +2491,15 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (urlParams.has('chunked')) {
session.chunked = parseInt(urlParams.get('chunked')) || 2500;
session.alpha = true;
session.chunked = parseInt(urlParams.get('chunked')) || 2500; // sender side; enables to allows.
// session.alpha = true;
}
if (urlParams.has('nochunk') || urlParams.has('nochunked')) { // viewer side
session.nochunk = true;
}
//if (urlParams.has('viewchunked') || urlParams.has('viewchunk') || urlParams.has('allowchunked') || urlParams.has('allowchunk')) { // viewer side
// session.forceChunked = true;
//}
if (urlParams.has('token')) {
session.token = urlParams.get('token') || false;

File diff suppressed because one or more lines are too long