mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-18 00:58:36 +00:00
Add files via upload
This commit is contained in:
parent
e8354f45c0
commit
8624f5bd67
371
electron.html
371
electron.html
@ -1,28 +1,13 @@
|
||||
<html>
|
||||
<meta charset="UTF-8">
|
||||
<head><style>
|
||||
<head>
|
||||
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
|
||||
<style>
|
||||
html {
|
||||
border:0;
|
||||
margin:0;
|
||||
outline:0;
|
||||
|
||||
}
|
||||
|
||||
a:link {
|
||||
text-decoration: bold;
|
||||
color: #CDF;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:active {
|
||||
text-decoration: underline;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
video {
|
||||
@ -38,10 +23,8 @@ body {
|
||||
padding: 0 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #141926;
|
||||
background-color: -webkit-linear-gradient(to top, #181925, #141826, #0F2027); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background-color: linear-gradient(to top, #181825, #141926, #0F2027); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
|
||||
background-color: -webkit-linear-gradient(to top, #363644, 50%, #151b29); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(to top, #363644, 50%, #151b29); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
font-size: 2em;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
display: flex;
|
||||
@ -60,26 +43,49 @@ button.glyphicon-button.active.focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
button{
|
||||
padding:10px;
|
||||
font-size: 20px;
|
||||
#gobutton{
|
||||
padding: 1em;
|
||||
font-size: 1em;
|
||||
margin: auto auto;
|
||||
height: 100%;
|
||||
font-family: system-ui;
|
||||
font-weight: bold;
|
||||
border: 2px solid #6aab23;
|
||||
background: #6aab23;
|
||||
display: flex;
|
||||
border-top-right-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
box-shadow: 0 12px 15px -10px #5ca70b;
|
||||
position: relative;
|
||||
right: 2px;
|
||||
top: 1px;
|
||||
color:white;
|
||||
cursor:pointer;
|
||||
}
|
||||
#header{
|
||||
height:80px;
|
||||
width:100%;
|
||||
background-color: #101520;
|
||||
}
|
||||
.inputfield{
|
||||
font-size: 20px;
|
||||
align-self:center;
|
||||
height:30px;
|
||||
width:780px;
|
||||
margin: auto auto;
|
||||
padding:20px
|
||||
input#changeText {
|
||||
font-size: 1em;
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
padding: 1em;
|
||||
font-weight: bold;
|
||||
font-family: system-ui;
|
||||
background: white;
|
||||
border-bottom: 4px solid #6aab23;
|
||||
box-shadow: 0px 30px 40px -32px #6aab23;
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
|
||||
.formcss{
|
||||
input#changeText:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.container{
|
||||
font-size: 20px;
|
||||
align-self:center;
|
||||
margin: auto auto;
|
||||
@ -101,9 +107,46 @@ input[type='checkbox'] {
|
||||
input[type='checkbox']:checked {
|
||||
background: #1A1;
|
||||
}
|
||||
#audioOutput{
|
||||
font-size: calc(16px + 0.3vw);
|
||||
max-width:590px
|
||||
#audioOutput, #lastUrls {
|
||||
font-size: calc(16px + 0.3vw);
|
||||
width: 730px;
|
||||
height: 100%;
|
||||
flex: 20;
|
||||
border-radius: 10px;
|
||||
padding: 1em;
|
||||
background: #eaeaea;
|
||||
cursor:pointer;
|
||||
}
|
||||
label[for="audioOutput"] {
|
||||
font-size: 3em;
|
||||
color: #FE53BB;
|
||||
text-shadow: 0px 0px 30px #fe53bb;
|
||||
padding-top: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
label[for="changeText"] {
|
||||
font-size: 3em;
|
||||
color: #00F6FF;
|
||||
text-shadow: 0px 0px 30px #00f6ff;
|
||||
padding-top: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
label[for="lastUrls"] {
|
||||
font-size: 3em;
|
||||
color: #1a1;
|
||||
text-shadow: 0px 0px 30px #1a1;
|
||||
padding-top: 10px;
|
||||
padding-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div#audioOutputContainer, #history {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
margin: 4em;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1030px) {
|
||||
@ -121,9 +164,9 @@ input[type='checkbox']:checked {
|
||||
-moz-transform-origin: 0 0;
|
||||
|
||||
}
|
||||
#audioOutput{
|
||||
font-size: calc(14px + 1.4vw);
|
||||
max-width:486px
|
||||
.container{
|
||||
/* font-size: calc(14px + 1.4vw); */
|
||||
max-width:750px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,40 +179,77 @@ input[type='checkbox']:checked {
|
||||
text-align: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
div#urlInput {
|
||||
margin: 4em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
label[for="audioOutput"], label[for="lastUrls"] {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
#warning4mac, #electronVersion {
|
||||
background: #8500f7;
|
||||
box-shadow: 0px 0px 50px 10px #8500f7ab, inset 0px 0px 10px 2px #8d08ffba;
|
||||
border: 2px solid #8500f7;
|
||||
border-radius: 10px;
|
||||
width: 90%;
|
||||
padding:1em;
|
||||
margin:0 auto;
|
||||
color:white;
|
||||
font-size:1.3em;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#warning4mac a, #electronVersion a {
|
||||
color:white;
|
||||
}
|
||||
|
||||
ul#lastUrls {
|
||||
list-style: none;
|
||||
background: #101520;
|
||||
color: white;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
ul#lastUrls li {
|
||||
padding: 5px 0px;
|
||||
}
|
||||
ul#lastUrls li:nth-child(even) {
|
||||
background-color: #182031;
|
||||
}
|
||||
|
||||
</style></head>
|
||||
<body >
|
||||
|
||||
<div id="header" style="-webkit-app-region: drag;color:white;font-size:2em">OBS.Ninja</div>
|
||||
<div class="formcss" >
|
||||
<div id="header" style="-webkit-app-region: drag;color:#6f6f6f;font-size:40px; line-height: 40px; padding: 20px; letter-spacing: 3; font-weight: bold;">OBS.Ninja</div>
|
||||
<div class="container" >
|
||||
|
||||
<div id='warning4mac' style="border:2px dotted; display:none;max-width:800px; padding:10px; margin:0 90px 20px 90px;color:white;font-size:1.3em"> ✨ Great News! OBS v26.1.2 <a href="https://github.com/obsproject/obs-browser/issues/209#issuecomment-748683083">now supports</a> OBS.Ninja without needing the Electron Capture app! 🥳</div>
|
||||
<div id='warning4mac' style="display:none;"> ✨ Great News! OBS v26.1.2 <a href="https://github.com/obsproject/obs-browser/issues/209#issuecomment-748683083">now supports</a> OBS.Ninja without needing the Electron Capture app! 🥳</div>
|
||||
<div id="electronVersion" style="display:none;">✨ Great News! <a href="https://github.com/steveseguin/electroncapture/releases/latest">Electron Capture <span id="currentElectronVersion"></span></a> is now available!<br>Update yours today to stay up-to-date with security patches.</div>
|
||||
|
||||
<div id='electronVersion' style="border:2px dotted; display:none;max-width:800px; padding:10px; margin:0 90px 20px 90px;color:white;font-size:1.3em"><center>✨ Great News! <a href="https://github.com/steveseguin/electroncapture/releases/latest">Electron Capture <span id="currentElectronVersion"></span></a> is now available!<br />Update yours today to stay up-to-date with security patches.</center></div>
|
||||
|
||||
<input type="checkbox" class="check" id="prefervp9" name="prefervp9" value="false" onclick="modURL(this);">
|
||||
<label for="prefervp9">Force VP9 Codec</label>
|
||||
|
||||
<input type="checkbox" class="check" id="showcursor" name="showcursor" value="false" onclick="modURL(this);">
|
||||
<label for="showcursor">Show Mouse Cursor</label>
|
||||
|
||||
<input type="checkbox" class="check" id="highbitrate" name="highbitrate" value="false" onclick="modURL(this);">
|
||||
<label for="highbitrate">High Video Bitrate</label>
|
||||
|
||||
<input type="checkbox" class="check" id="stereo" name="stereo" value="false" onclick="modURL(this);">
|
||||
<label for="stereo">Pro Audio Mode</label>
|
||||
|
||||
<input type="checkbox" class="check" id="buffer" name="buffer" value="false" onclick="modURL(this);">
|
||||
<label for="buffer">Lip-sync Fix</label>
|
||||
|
||||
<br>
|
||||
<div id="messageDiv" style='display:block'><br /></div>
|
||||
<div class="formcss"><center>
|
||||
<input type="text" id="changeText" class="inputfield" value="http://obs.ninja/?view=" onchange="modURL" onkeyup="enterPressed(event, gohere);" />
|
||||
<button onclick="gohere();" id="gobutton">GO</button>
|
||||
<br><br>
|
||||
<label for="audioOutput">Audio output destination: </label><select id="audioOutput"></select>
|
||||
|
||||
</center></div>
|
||||
<div class="container">
|
||||
<div id="urlInput" title="Put the link you want to load here">
|
||||
<label for="changeText">
|
||||
<i class="las la-play"></i>
|
||||
</label>
|
||||
<input type="text" id="changeText" class="inputfield" value="http://obs.ninja/?view=" onchange="modURL" onkeyup="enterPressed(event, gohere);" />
|
||||
<button onclick="gohere();" id="gobutton">GO</button>
|
||||
</div>
|
||||
<div id="audioOutputContainer" title="This option will only work with the official obs.ninja domain">
|
||||
<label for="audioOutput"><i class="las la-headphones"></i></label><select id="audioOutput"></select>
|
||||
</div>
|
||||
<div id="history" title="History of past links used. You can clear this history using the button to the left">
|
||||
<label for="lastUrls" onclick="resetHistory()">
|
||||
<i class="las la-history"></i>
|
||||
</label>
|
||||
<select id="lastUrls" onchange="setUrl()"></select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -182,26 +262,33 @@ input[type='checkbox']:checked {
|
||||
* tree. Alternative licencing options can be made available on request.
|
||||
*
|
||||
*/
|
||||
var lastUrls = JSON.parse(localStorage.getItem('lastUrls'));
|
||||
if (lastUrls != undefined) {
|
||||
document.querySelector("#changeText").value = lastUrls[0];
|
||||
if (lastUrls.length>0){
|
||||
lastUrls.forEach((url)=>{
|
||||
var o = document.createElement('option');
|
||||
o.value = url;
|
||||
o.text = url;
|
||||
document.querySelector("#lastUrls").appendChild(o);
|
||||
})
|
||||
} else {
|
||||
document.querySelector("#history").style.display="none";
|
||||
}
|
||||
} else {
|
||||
document.querySelector("#history").style.display="none";
|
||||
}
|
||||
|
||||
function setUrl(){
|
||||
document.querySelector("#changeText").value = document.querySelector("#lastUrls").value;
|
||||
gohere();
|
||||
}
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams = w.URLSearchParams || function (searchString) {
|
||||
var self = this;
|
||||
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 urlParams = new URLSearchParams(window.location.search);
|
||||
function resetHistory(){
|
||||
localStorage.clear();
|
||||
document.querySelector('#lastUrls').innerHTML = '';
|
||||
lastUrls = [];
|
||||
}
|
||||
|
||||
if (navigator.userAgent.indexOf('Mac OS X') != -1){
|
||||
document.getElementById("warning4mac").style.display="block";
|
||||
@ -231,7 +318,7 @@ if (navigator.userAgent.indexOf('Mac OS X') != -1){
|
||||
document.getElementById("electronVersion").style.display = "block";
|
||||
document.getElementById("currentElectronVersion").innerText = data.tag_name;
|
||||
}
|
||||
});
|
||||
}).catch(console.error);
|
||||
}
|
||||
if (urlParams.has('version')){
|
||||
var ver = urlParams.get('version');
|
||||
@ -313,15 +400,32 @@ function enterPressed(event, callback){
|
||||
}
|
||||
}
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams = w.URLSearchParams || function (searchString) {
|
||||
var self = this;
|
||||
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 urlParams = new URLSearchParams(window.location.search);
|
||||
var isMobile = false;
|
||||
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){ // does not detect iPad Pros.
|
||||
isMobile=true; // if iOS, default to H264? meh. let's not.
|
||||
}
|
||||
// Windows can show the cursor, since it captures in a different way.
|
||||
if (navigator.platform.indexOf("Win") != -1){
|
||||
document.getElementById("showcursor").checked=true;
|
||||
}
|
||||
//if (navigator.platform.indexOf("Win") != -1){
|
||||
// document.getElementById("showcursor").checked=true;
|
||||
//}
|
||||
|
||||
function updateURLParameter(url, param, paramVal){
|
||||
var TheAnchor = null;
|
||||
@ -374,60 +478,28 @@ if (urlParams.has('name')){
|
||||
}
|
||||
}
|
||||
|
||||
function addUrlToHistory(url){
|
||||
if (lastUrls == undefined){
|
||||
lastUrls = [];
|
||||
}
|
||||
if ( lastUrls[0] != url ) {
|
||||
lastUrls.unshift(url);
|
||||
if (lastUrls.length == 6) {
|
||||
lastUrls.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function modURL(ele=false){
|
||||
var url = document.getElementById('changeText').value;
|
||||
console.log(url);
|
||||
if ((url.split("view").length>0) || (url.split("room").length>0)){
|
||||
if (!document.getElementById("showcursor").checked){
|
||||
url=updateURLParameter(url, "nocursor", "");
|
||||
} else {
|
||||
url=updateURLParameter(url, "nocursor", false);
|
||||
}
|
||||
|
||||
if (ele!=false){
|
||||
if (ele.id =="prefervp9"){
|
||||
if (document.getElementById("prefervp9").checked){
|
||||
url=updateURLParameter(url, "codec", "vp9");
|
||||
} else {
|
||||
url=updateURLParameter(url, "codec", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ele.id =="highbitrate"){
|
||||
if (document.getElementById("highbitrate").checked){
|
||||
url=updateURLParameter(url, "bitrate", "10000");
|
||||
} else {
|
||||
url=updateURLParameter(url, "bitrate", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ele.id =="stereo"){
|
||||
if (document.getElementById("stereo").checked){
|
||||
url=updateURLParameter(url, "proaudio", "");
|
||||
document.getElementById("messageDiv").innerHTML = "Audio bitrate increased to 256-kbps.\n\nPlease note that the Sender must also have the <b>&proaudio</b> flag added for full-effect";
|
||||
document.getElementById("messageDiv").style.display="block";
|
||||
setTimeout(function(){document.getElementById("messageDiv").style.opacity="1.0";},0);
|
||||
} else {
|
||||
url=updateURLParameter(url, "proaudio", false);
|
||||
setTimeout(function(){document.getElementById("messageDiv").style.opacity="0";},0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ele.id =="buffer"){
|
||||
if (document.getElementById("buffer").checked){
|
||||
url=updateURLParameter(url, "buffer", "");
|
||||
} else {
|
||||
url=updateURLParameter(url, "buffer", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
document.getElementById('changeText').value = url;
|
||||
console.log(url);
|
||||
return url;
|
||||
}
|
||||
function gohere(){
|
||||
addUrlToHistory(document.getElementById('changeText').value);
|
||||
localStorage.setItem('lastUrls', JSON.stringify(lastUrls));
|
||||
var url = modURL(true);
|
||||
if (!(document.getElementById('changeText').value.includes("obs.ninja")) && (document.getElementById('changeText').value.includes("http")) && (document.getElementById('changeText').value.includes("&sink"))){
|
||||
alert("Notice: The &sink command is domain specific.\nVisit https://YOURDOMAIN.com/electron instead.");
|
||||
@ -437,27 +509,4 @@ function gohere(){
|
||||
getPermssions();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</html>
|
||||
10
iframe.html
10
iframe.html
@ -238,6 +238,16 @@ function loadIframe(){ // this is pretty important if you want to avoid camera
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"function":"previewWebcam"}, '*');}; // publishScreen
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Change to Camera #2";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"changeVideoDevice":2}, '*');}; // change text of add camera button
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Change to Microphone #4";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"changeAudioDevice":4}, '*');}; // change text of add camera button
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "eval('alert(\"DANGERUS\")'";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"function":"eval", "value":'alert(\"DANGERUS\")'}, '*');}; // publishScreen
|
||||
|
||||
104
index.html
104
index.html
@ -55,7 +55,7 @@
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
|
||||
<link rel="stylesheet" href="./main.css?ver=60" />
|
||||
<link rel="stylesheet" href="./main.css?ver=61" />
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.min.js"></script>
|
||||
</head>
|
||||
<body id="main" class="hidden">
|
||||
@ -717,12 +717,12 @@
|
||||
</li>
|
||||
|
||||
<br />
|
||||
⛔ Site Updated on May 5th: 📵 🚷 ⚠ THIS ALPHA BUILD IS NOT TESTED AND NOT COMPATIBLE WITH PRODUCTION ☣ ☢ 🔞
|
||||
👓🔆 Site Updated on May 13th: <a href="https://docs.obs.ninja/release-notes/v17-release-notes">v17 Release Notes</a>. The previous version can be found at <a href="https://obs.ninja/v164/">https://obs.ninja/v164/</a> if you are having issues with this minor update.
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<h3>
|
||||
🛠 For support, see the <a href="https://www.reddit.com/r/OBSNinja/">sub-reddit <i class="lab la-reddit-alien"></i></a> or join the <a href="https://discord.obs.ninja">Discord <i class="lab la-discord"></i></a>. The <a href="https://docs.obs.ninja">Docs are here</a> and my personal email is <i>steve@seguin.email</i>
|
||||
🛠 For support, see the <a href="https://www.reddit.com/r/OBSNinja/">sub-reddit <i class="lab la-reddit-alien"></i></a> or join the <a href="https://discord.gg/T4xpQVv">Discord <i class="lab la-discord"></i></a>. The <a href="https://docs.obs.ninja/">documentation is here</a> and my personal email is <i>steve@seguin.email</i>
|
||||
</h3>
|
||||
|
||||
</span>
|
||||
@ -825,7 +825,7 @@
|
||||
</div>
|
||||
<div class='directorContainer' id="customizeLinks" style='display:none;margin-top:0;padding-top:15px'>
|
||||
<div class='directorBlock' id="customizeLinks1" style='display:none;margin-top:0;padding-bottom:0;'>
|
||||
<div style="display:inline-block;top: 12px; position: relative;">
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative; margin-right:10px;">
|
||||
<label class="switch" title="Disables Echo Cancellation and improves audio quality">
|
||||
<input type="checkbox" data-param="&s" onchange="updateLink(1,this);">
|
||||
<span class="slider"></span>
|
||||
@ -845,6 +845,13 @@
|
||||
<span data-translate="remote-monitoring">Remote Monitoring</span>
|
||||
<Br />
|
||||
|
||||
<label class="switch" title="The guest will be asked if they want to reload the previous link when revisiting">
|
||||
<input type="checkbox" data-param="&sticky" onchange="updateLink(1,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="remote-monitoring">Invite saved to cookie</span>
|
||||
<Br />
|
||||
|
||||
<label class="switch" title="Guest will be prompted to enter a Display Name">
|
||||
<input type="checkbox" data-param="&l" onchange="updateLink(1,this);">
|
||||
<span class="slider"></span>
|
||||
@ -864,7 +871,7 @@
|
||||
<span data-translate="show-active-speaker">Show active speakers</span>
|
||||
|
||||
</div>
|
||||
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px;">
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative; margin-right:10px;">
|
||||
<label class="switch" title="Request 1080p60 from the Guest instead of 720p60, if possible">
|
||||
<input type="checkbox" data-param="&q" onchange="updateLink(1,this);">
|
||||
<span class="slider"></span>
|
||||
@ -902,7 +909,7 @@
|
||||
<font class="tooltip" style='cursor: help;position:relative;bottom:2px;font-family:"Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort;'>⚠<span class="tooltiptext">Uses more CPU and freezes the video if the guest doesn't keep the tab visible.</span></font> <span data-translate="virtual-backgrounds">Virtual backgrounds</span>
|
||||
|
||||
</div>
|
||||
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px;">
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative; margin-right:10px;">
|
||||
<label class="switch" title="Increase video quality that guests in room see.">
|
||||
<input type="checkbox" data-param="&trb=2000" onchange="updateLink(1,this);">
|
||||
<span class="slider"></span>
|
||||
@ -932,8 +939,15 @@
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="enable-equalizer">Enable equalizer as option</span>
|
||||
<br />
|
||||
<label class="switch">
|
||||
<input type="checkbox" data-param="&tips" onchange="updateLink(1,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="show-guest-tips" title="Show some prep suggestions to the guests on connect">Show guest setup tips</span>
|
||||
|
||||
</div>
|
||||
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px; height: 20px;">
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative; height: 20px;">
|
||||
<label class="switch" title="This low-fi video codec uses very little CPU, even with dozens of active viewers.">
|
||||
<input type="checkbox" data-param="&webp" onchange="updateLinkWebP(1,this);">
|
||||
<span class="slider"></span>
|
||||
@ -974,8 +988,16 @@
|
||||
</div>
|
||||
|
||||
<div class='directorBlock' id="customizeLinks3" style='display:none;margin-top:5px;padding-bottom:0;'>
|
||||
<div style="display:inline-block; position: relative; margin-left:10px; ">
|
||||
<div style="display:inline-block;top: 12px; position: relative;">
|
||||
<div style="display:inline-block; position: relative; margin-right:10px; ">
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative;">
|
||||
|
||||
<label class="switch">
|
||||
<input type="checkbox" data-param="&st" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="hide-audio-only-sources">Hide audio-only sources</span>
|
||||
<br />
|
||||
|
||||
<label class="switch">
|
||||
<input type="checkbox" data-param="&s" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
@ -991,29 +1013,46 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px; height: 20px;">
|
||||
<label class="switch">
|
||||
<input type="checkbox" data-param="&st" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="hide-audio-only-sources">Hide audio-only sources</span>
|
||||
<br />
|
||||
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative; margin-right:10px; height: 20px;">
|
||||
|
||||
<label class="switch" title="The active speakers are made visible automatically">
|
||||
<input type="checkbox" data-param="&sas" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="show-active-speakers">Show active speakers</span>
|
||||
<br />
|
||||
|
||||
<label class="switch" title="Set the background color to bright green">
|
||||
<input type="checkbox" data-param="&chroma" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="green-background">Green background</span>
|
||||
|
||||
<br />
|
||||
|
||||
<label class="switch" title="Fade videos in over 500ms">
|
||||
<input type="checkbox" data-param="&fadein" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="fade-videos-in">Fade-in videos</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div style="display:inline-block;top: 12px; position: relative; margin-left:10px;">
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative; margin-right:10px; height: 20px;">
|
||||
<label class="switch">
|
||||
<input type="checkbox" data-param="&sl" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="show-display-names">Show display names</span>
|
||||
<br />
|
||||
|
||||
<label class="switch" title="Add a 10px margin around all video elements">
|
||||
<input type="checkbox" data-param="&margin" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="add-margin">Add margin to videos</span>
|
||||
<br />
|
||||
<label class="switch">
|
||||
<input type="checkbox" data-param="&vb=20000" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
@ -1021,12 +1060,24 @@
|
||||
<font class="tooltip" style='cursor: help;position:relative;bottom:2px;font-family:"Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort;'>⚠<span class="tooltiptext">This can cause video playback to lag</span></font> Unlock Video Bitrate
|
||||
</div>
|
||||
|
||||
<div style="display:inline-block;top: 12px; height: 20px;position: relative; margin-left:10px;">
|
||||
<label class="switch">
|
||||
<div style="display:inline-block;margin-top: 12px; position: relative; height: 20px;">
|
||||
<label class="switch" title="Playback the video with mono-channel audio">
|
||||
<input type="checkbox" data-param="&mono" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="force-mono-audio">Force mono audio</span>
|
||||
<br />
|
||||
<label class="switch" title="Have the videos fit their respective areas, even if it means cropping a bit">
|
||||
<input type="checkbox" data-param="&cover" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="fill-video-space">Crop video to fit</span>
|
||||
<br />
|
||||
<label class="switch" title="Have videos be aligned with sizing designed for vertical video">
|
||||
<input type="checkbox" data-param="&916" onchange="updateLink(3,this);">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span data-translate="vertical-aspect-ratio">Vertical video mode</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1593,13 +1644,18 @@
|
||||
|
||||
///// Different endpoints are available; each isolated from each other.
|
||||
// session.wss = "wss://wss13.obs.ninja:443"; // US-East (Default)
|
||||
session.wss = "wss://apibackup.obs.ninja:443"; // US-West
|
||||
// session.wss = "wss://apibackup.obs.ninja:443"; // US-West
|
||||
// session.wss = "wss://jp1wss.obs.ninja:443"; // Japan
|
||||
// session.wss = "wss://au1wss.obs.ninja:443"; // Australia
|
||||
// session.wss = "wss://de1wss.obs.ninja:443"; // Germany
|
||||
// session.wss = "wss://insecure.cam:444"; // China
|
||||
|
||||
|
||||
session.wss = "wss://wss.contribute.cam:443";
|
||||
session.pie=true;
|
||||
/// Or you can use piesocket.com or any echo websocket server to host a server for your yourself.
|
||||
//session.pie = true; // Enable piesocket.com server support (or any basic relay websocket server)
|
||||
//var apiKey = "ZCu96UFf9ezeQeClK7BOCkq6Q0x0lxWAPJcgxjz5"; // get an API key from https://www.piesocket.com/ for a free API server of your own
|
||||
//session.wss = "wss://us-nyc-1.websocket.me/v3/1?api_key="+apiKey;
|
||||
|
||||
///// The following lets you set the defaults
|
||||
|
||||
// session.webcamonly // true,false
|
||||
@ -1636,7 +1692,7 @@
|
||||
<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="main-js" src="./main.js?ver=203"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=206"></script>
|
||||
<script type="text/javascript">
|
||||
setTimeout(function(){ // lazy load
|
||||
var script = document.createElement('script');
|
||||
|
||||
48
main.css
48
main.css
@ -9,6 +9,8 @@
|
||||
--regular-margin: 10px;
|
||||
--director-margin: 15px 20px 0 0;
|
||||
--fit-style: contain;
|
||||
--fadein-speed: 0;
|
||||
--video-margin: 0px;
|
||||
}
|
||||
|
||||
* {
|
||||
@ -365,7 +367,8 @@ hr {
|
||||
height: 100%;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
margin: var(--video-margin);
|
||||
}
|
||||
|
||||
#gridlayout {
|
||||
@ -1569,6 +1572,41 @@ img {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.fadein {
|
||||
animation: fadeIn var(--fadein-speed);
|
||||
-webkit-animation: fadeIn var(--fadein-speed);
|
||||
-moz-animation: fadeIn var(--fadein-speed);
|
||||
-o-animation: fadeIn var(--fadein-speed);
|
||||
-ms-animation: fadeIn var(--fadein-speed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {opacity:0;}
|
||||
100% {opacity:1;}
|
||||
}
|
||||
|
||||
@-moz-keyframes fadeIn {
|
||||
0% {opacity:0;}
|
||||
100% {opacity:1;}
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% {opacity:0;}
|
||||
100% {opacity:1;}
|
||||
}
|
||||
|
||||
@-o-keyframes fadeIn {
|
||||
0% {opacity:0;}
|
||||
100% {opacity:1;}
|
||||
}
|
||||
|
||||
@-ms-keyframes fadeIn {
|
||||
0% {opacity:0;}
|
||||
100% {opacity:1;}
|
||||
}
|
||||
|
||||
video {
|
||||
transition: opacity .25s ease-in-out;
|
||||
-moz-transition: opacity .25s ease-in-out;
|
||||
@ -2151,6 +2189,10 @@ input[type=checkbox] {
|
||||
padding: 10px;
|
||||
max-width: 1191px
|
||||
}
|
||||
@media only screen and (max-width: 390px) {
|
||||
|
||||
}
|
||||
|
||||
#directorLinksButton{
|
||||
cursor:pointer;
|
||||
}
|
||||
@ -2317,7 +2359,7 @@ a#reshare {
|
||||
|
||||
/* Tips for guests */
|
||||
span#guestTips {
|
||||
margin: 10 auto;
|
||||
margin: 0 auto 15px auto;
|
||||
width: 450px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -2598,7 +2640,7 @@ div.message-card.info:before {
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
margin:5px 5px 10px 5px;
|
||||
margin:5px 5px 2px 5px;
|
||||
width: 40px;
|
||||
height: 24px;
|
||||
bottom:20px;
|
||||
|
||||
390
main.js
390
main.js
@ -1011,6 +1011,7 @@ if (urlParams.has('screensharequality') || urlParams.has('ssq')) {
|
||||
|
||||
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
|
||||
//session.webcamonly = true;
|
||||
session.mobile = true;
|
||||
getById("shareScreenGear").style.display = "none";
|
||||
screensharebutton = false;
|
||||
screensharesupport = false;
|
||||
@ -1022,6 +1023,7 @@ if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(naviga
|
||||
|
||||
} else if ((iOS) || (iPad)) {
|
||||
getById("shareScreenGear").style.display = "none";
|
||||
session.mobile = true;
|
||||
screensharebutton = false;
|
||||
screensharesupport = false;
|
||||
getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile
|
||||
@ -1241,6 +1243,7 @@ if (urlParams.has('portrait') || urlParams.has('916') || urlParams.has('vertical
|
||||
}
|
||||
|
||||
if (urlParams.has('cover')) {
|
||||
session.cover = true;
|
||||
document.documentElement.style.setProperty('--fit-style', 'cover');
|
||||
}
|
||||
|
||||
@ -1414,13 +1417,14 @@ if (urlParams.has('sizelabel') || urlParams.has('labelsize') || urlParams.has('f
|
||||
}
|
||||
|
||||
if (urlParams.has('label') || urlParams.has('l')) {
|
||||
session.label = urlParams.get('label') || urlParams.get('l');
|
||||
session.label = urlParams.get('label') || urlParams.get('l') || null;
|
||||
var updateURLAsNeed = true;
|
||||
if (session.label == null || session.label.length == 0) {
|
||||
session.label = prompt("Please enter your display name:");
|
||||
} else {
|
||||
var updateURLAsNeed = false;
|
||||
session.label = decodeURIComponent(session.label);
|
||||
session.label = session.label.replace(/_/g, " ")
|
||||
}
|
||||
if (session.label != null) {
|
||||
session.label = sanitizeLabel(session.label); // alphanumeric was too strict.
|
||||
@ -1495,6 +1499,16 @@ if (urlParams.has('stereo') || urlParams.has('s') || urlParams.has('proaudio'))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (urlParams.has('pie')){
|
||||
session.pie = urlParams.get('pie') || true;
|
||||
if (session.pie===true){
|
||||
session.wss = "wss://us-nyc-1.websocket.me/v3/1?api_key=ZCu96UFf9ezeQeClK7BOCkq6Q0x0lxWAPJcgxjz5";
|
||||
} else {
|
||||
session.wss = "wss://us-nyc-1.websocket.me/v3/1?api_key="+session.pie;
|
||||
}
|
||||
}
|
||||
|
||||
if ((session.stereo == 1) || (session.stereo == 3) || (session.stereo == 4) || (session.stereo == 5)) {
|
||||
session.echoCancellation = false;
|
||||
session.autoGainControl = false;
|
||||
@ -1707,6 +1721,10 @@ if (urlParams.has('micdelay') || urlParams.has('delay') || urlParams.has('md'))
|
||||
session.disableWebAudio = false;
|
||||
}
|
||||
|
||||
if (urlParams.has('tips')){
|
||||
getById("guestTips").style.display="flex";
|
||||
}
|
||||
|
||||
if (urlParams.has('audiogain') || urlParams.has('gain') || urlParams.has('g')) {
|
||||
log("audio gain ENABLED");
|
||||
session.audioGain = urlParams.get('audiogain') || urlParams.get('gain') || urlParams.get('g');
|
||||
@ -1751,9 +1769,37 @@ if (urlParams.has('tallyoff') || urlParams.has('obsoff') || urlParams.has('oo'))
|
||||
|
||||
if (urlParams.has('chroma')) {
|
||||
log("Chroma ENABLED");
|
||||
getById("main").style.backgroundColor = "#" + (urlParams.get('chroma') || "000");
|
||||
getById("main").style.backgroundColor = "#" + (urlParams.get('chroma') || "0F0");
|
||||
}
|
||||
|
||||
if (urlParams.has('margin')) {
|
||||
if (urlParams.get('margin') || 10){
|
||||
try {
|
||||
var videoMargin = urlParams.get('margin') || 10;
|
||||
videoMargin = parseInt(videoMargin);
|
||||
videoMargin+="px";
|
||||
document.querySelector(':root').style.setProperty('--video-margin', videoMargin);
|
||||
} catch(e){errorlog("variable css failed");}
|
||||
}
|
||||
}
|
||||
|
||||
if (urlParams.has('fadein')) {
|
||||
if (urlParams.get('fadein') || 0){
|
||||
try {
|
||||
var fadeinspeed = parseInt(urlParams.get('fadein') || 0)/1000.0;
|
||||
fadeinspeed+="s";
|
||||
document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed);
|
||||
} catch(e){errorlog("variable css failed");}
|
||||
} else {
|
||||
try {
|
||||
var fadeinspeed = 0.5;
|
||||
fadeinspeed+="s";
|
||||
document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed);
|
||||
} catch(e){errorlog("variable css failed");}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (urlParams.has("videodevice") || urlParams.has("vdevice") || urlParams.has('vd') || urlParams.has('device') || urlParams.has('d')) {
|
||||
|
||||
session.videoDevice = urlParams.get("videodevice") || urlParams.get("vdevice") || urlParams.get("vd") || urlParams.get("device") || urlParams.get("d");
|
||||
@ -2316,6 +2362,12 @@ if (session.totalRoomBitrate===false){
|
||||
}
|
||||
|
||||
|
||||
if (urlParams.has('limittotalbitrate') || urlParams.has('ltb')){
|
||||
session.limitTotalBitrate = urlParams.get('limittotalbitrate') || urlParams.get('ltb') || 2500;
|
||||
session.limitTotalBitrate = parseInt(session.limitTotalBitrate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (urlParams.has('height') || urlParams.has('h')) {
|
||||
session.height = urlParams.get('height') || urlParams.get('h');
|
||||
@ -2903,6 +2955,16 @@ if (isIFrame) { // reduce CPU load if not needed.
|
||||
}
|
||||
}
|
||||
|
||||
if ("changeVideoDevice" in e.data) {
|
||||
warnlog(e.data.changeVideoDevice);
|
||||
changeVideoDevice(e.data.changeVideoDevice);
|
||||
}
|
||||
|
||||
if ("changeAudioDevice" in e.data) {
|
||||
warnlog(e.data.changeAudioDevice);
|
||||
changeAudioDevice(e.data.changeAudioDevice);
|
||||
}
|
||||
|
||||
|
||||
if ("sceneState" in e.data) { // TRUE OR FALSE - tells the connected peers if they are live or not via a tally light change.
|
||||
|
||||
@ -3180,7 +3242,7 @@ function setupIncomingVideoTracking(v, UUID){ // video element.
|
||||
v.volume = 1.0; // play audio automatically
|
||||
v.autoplay = true;
|
||||
v.controls = false;
|
||||
v.className += "tile";
|
||||
v.classList.add("tile");
|
||||
v.setAttribute("playsinline","");
|
||||
v.controlTimer = null;
|
||||
|
||||
@ -3363,6 +3425,10 @@ function setupIncomingVideoTracking(v, UUID){ // video element.
|
||||
}
|
||||
}
|
||||
|
||||
if (session.fadein){
|
||||
v.classList.add("fadein"); // allows the video to fade in.
|
||||
}
|
||||
|
||||
setTimeout(session.processStats, 1000, UUID);
|
||||
|
||||
}
|
||||
@ -3397,17 +3463,17 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
||||
}
|
||||
}
|
||||
|
||||
var arW = 16.0;
|
||||
var arH = 9.0;
|
||||
|
||||
if (session.aspectratio){
|
||||
if (session.aspectratio==1){
|
||||
var arW = 9.0;
|
||||
var arH = 16.0;
|
||||
arW = 9.0;
|
||||
arH = 16.0;
|
||||
} else if (session.aspectratio==2){
|
||||
var arW = 1.0;
|
||||
var arH = 1.0;
|
||||
arW = 12.0; // square root; cause why not.
|
||||
arH = 12.0;
|
||||
}
|
||||
} else {
|
||||
var arW = 16.0;
|
||||
var arH = 9.0;
|
||||
}
|
||||
|
||||
var ww = w/arW;
|
||||
@ -3922,7 +3988,7 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
||||
//vid.classList="";
|
||||
vid.style.maxWidth = "100%";
|
||||
vid.style.maxHeight = "100%";
|
||||
vid.style.margin = "auto";
|
||||
//vid.style.margin = "auto";
|
||||
|
||||
// Creates relative positioned element, important for label pos
|
||||
var holder = document.createElement("div");
|
||||
@ -3982,6 +4048,13 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
||||
holder.style.top = 0;
|
||||
}
|
||||
|
||||
if (session.cover){
|
||||
holder.style.width = "100%";
|
||||
holder.style.height = "100%";
|
||||
holder.style.left = 0;
|
||||
holder.style.top = 0;
|
||||
}
|
||||
|
||||
holder.style.position = "absolute";
|
||||
|
||||
vid.style.width = "100%";
|
||||
@ -5488,14 +5561,18 @@ function updateLocalStats(){
|
||||
}, 0, uuid);
|
||||
}
|
||||
var headerStats = "Viewers: ";
|
||||
headerStats += Object.keys(session.pcs).length || 0;
|
||||
try{
|
||||
headerStats += Object.keys(session.pcs).length || 0;
|
||||
} catch(e){}
|
||||
headerStats += ", Upload (kbps): "+totalBitrate2; // + " / "+totalBitrate;
|
||||
if (cpuLimited){
|
||||
headerStats += ", CPU Overloaded";
|
||||
}
|
||||
if (Object.keys(session.pcs).length){
|
||||
getById("head5").classList.remove("advanced");
|
||||
}
|
||||
try{
|
||||
if (Object.keys(session.pcs).length){
|
||||
getById("head5").classList.remove("advanced");
|
||||
}
|
||||
} catch(e){}
|
||||
getById("head5").innerHTML = headerStats;
|
||||
}
|
||||
|
||||
@ -7593,6 +7670,15 @@ function createRoomCallback(passAdd, passAdd2) {
|
||||
broadcastString = "&broadcast";
|
||||
getById("broadcastSlider").checked = true;
|
||||
}
|
||||
|
||||
var pie = "";
|
||||
if (session.pie){
|
||||
if (session.pie!==true){
|
||||
pie = "&pie="+session.pie;
|
||||
} else {
|
||||
pie = "&pie";
|
||||
}
|
||||
}
|
||||
|
||||
var showdirectorFlag = getById("showdirectorFlag");
|
||||
try {
|
||||
@ -7676,14 +7762,14 @@ function createRoomCallback(passAdd, passAdd2) {
|
||||
getById("directorLinks1").style.display = "inline-block";
|
||||
getById("directorLinks2").style.display = "inline-block";
|
||||
|
||||
getById("director_block_1").dataset.raw = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd;
|
||||
getById("director_block_1").href = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd;
|
||||
getById("director_block_1").innerText = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd;
|
||||
getById("director_block_1").dataset.raw = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd + pie;
|
||||
getById("director_block_1").href = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd + pie;
|
||||
getById("director_block_1").innerText = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd + pie;
|
||||
|
||||
|
||||
getById("director_block_3").dataset.raw = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2;
|
||||
getById("director_block_3").href = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2;
|
||||
getById("director_block_3").innerText = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2;
|
||||
getById("director_block_3").dataset.raw = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2 + pie;
|
||||
getById("director_block_3").href = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2 + pie;
|
||||
getById("director_block_3").innerText = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2 + pie;
|
||||
|
||||
getById("calendarButton").style.display = "inline-block";
|
||||
|
||||
@ -7894,7 +7980,16 @@ function createDirectorOnlyBox() {
|
||||
passAdd2="&password="+session.password;
|
||||
}
|
||||
}
|
||||
var soloLink = "https://"+location.host+location.pathname+"?view="+session.streamID+"&scene"+codecGroupFlag+"&room="+session.roomid+passAdd2;
|
||||
var pie = "";
|
||||
if (session.pie){
|
||||
if (session.pie!==true){
|
||||
pie = "&pie="+session.pie;
|
||||
} else {
|
||||
pie = "&pie";
|
||||
}
|
||||
}
|
||||
|
||||
var soloLink = "https://"+location.host+location.pathname+"?view="+session.streamID+"&scene"+codecGroupFlag+"&room="+session.roomid+passAdd2+pie;
|
||||
|
||||
if (document.getElementById("deleteme")) {
|
||||
getById("deleteme").parentNode.removeChild(getById("deleteme"));
|
||||
@ -9273,11 +9368,13 @@ function gotDevices2(deviceInfos) {
|
||||
});
|
||||
|
||||
for (UUID in session.rpcs) {
|
||||
session.rpcs[UUID].videoElement.setSinkId(session.sink).then(() => {
|
||||
log("New Output Device for: " + UUID);
|
||||
}).catch(error => {
|
||||
errorlog(error);
|
||||
});
|
||||
try{
|
||||
session.rpcs[UUID].videoElement.setSinkId(session.sink).then(() => {
|
||||
log("New Output Device for: " + UUID);
|
||||
}).catch(error => {
|
||||
errorlog(error);
|
||||
});
|
||||
} catch(e){warnlog(e);}
|
||||
}
|
||||
} catch (e) {
|
||||
errorlog(e);
|
||||
@ -9289,6 +9386,81 @@ function gotDevices2(deviceInfos) {
|
||||
}
|
||||
}
|
||||
|
||||
function gotDevicesRemote(deviceInfos, UUID) {
|
||||
|
||||
try {
|
||||
if (document.getElementById("remoteVideoSelect_"+UUID)){
|
||||
var videoSelect = document.getElementById("remoteVideoSelect_"+UUID);
|
||||
var length = videoSelect.options.length;
|
||||
for (i = length-1; i >= 0; i--) {
|
||||
videoSelect.options[i] = null;
|
||||
}
|
||||
} else {
|
||||
var videoSelect = document.createElement("select");
|
||||
videoSelect.id = "remoteVideoSelect_"+UUID;
|
||||
videoSelect.style = "max-width:190px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;";
|
||||
var buttonGO = document.createElement("button");
|
||||
buttonGO.innerHTML = "Apply";
|
||||
buttonGO.style = "padding: 5px;";
|
||||
buttonGO.title = "This will ask the remote guest for permission to change";
|
||||
buttonGO.onclick = function(){
|
||||
var data = {}
|
||||
data.changeCamera = videoSelect.value;
|
||||
data.UUID = UUID;
|
||||
session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER
|
||||
}
|
||||
|
||||
getById("advanced_video_director_" + UUID).appendChild(videoSelect);
|
||||
getById("advanced_video_director_" + UUID).appendChild(buttonGO);
|
||||
}
|
||||
|
||||
if (document.getElementById("remoteAudioSelect_"+UUID)){
|
||||
var audioSelect = document.getElementById("remoteAudioSelect_"+UUID);
|
||||
var length = audioSelect.options.length;
|
||||
for (i = length-1; i >= 0; i--) {
|
||||
audioSelect.options[i] = null;
|
||||
}
|
||||
} else {
|
||||
var audioSelect = document.createElement("select");
|
||||
audioSelect.id = "remoteAudioSelect_"+UUID;
|
||||
audioSelect.style = "max-width:190px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;";
|
||||
var buttonGO = document.createElement("button");
|
||||
buttonGO.innerHTML = "Apply";
|
||||
buttonGO.style = "padding: 5px;";
|
||||
buttonGO.title = "This will ask the remote guest for permission to change";
|
||||
buttonGO.onclick = function(){
|
||||
var data = {}
|
||||
data.changeMicrophone = audioSelect.value;
|
||||
data.UUID = UUID;
|
||||
session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER
|
||||
}
|
||||
getById("advanced_audio_director_" + UUID).appendChild(audioSelect);
|
||||
getById("advanced_audio_director_" + UUID).appendChild(buttonGO);
|
||||
}
|
||||
|
||||
|
||||
for (let i = 0; i !== deviceInfos.length; ++i) {
|
||||
const deviceInfo = deviceInfos[i];
|
||||
if (deviceInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if (deviceInfo.kind === 'videoinput'){
|
||||
const option = document.createElement('option');
|
||||
option.value = deviceInfo.deviceId || "default";
|
||||
option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
|
||||
videoSelect.appendChild(option);
|
||||
|
||||
} else if (deviceInfo.kind === 'audioinput'){
|
||||
const option = document.createElement('option');
|
||||
option.value = deviceInfo.deviceId || "default";
|
||||
option.text = deviceInfo.label || `microphone ${videoSelect.length + 1}`;
|
||||
audioSelect.appendChild(option);
|
||||
}
|
||||
}
|
||||
|
||||
} catch(e){errorlog(e);}
|
||||
}
|
||||
|
||||
function playtone(screen = false) {
|
||||
|
||||
if ((iOS) || (iPad)) {
|
||||
@ -9503,7 +9675,7 @@ function reconnectDevices(event) { /// TODO: Perhaps change this to only if the
|
||||
// try{
|
||||
// session.audioContext.resume();
|
||||
// } catch(e){errorlog(e);}
|
||||
resetupAudioOut();
|
||||
// resetupAudioOut();
|
||||
return;
|
||||
}
|
||||
warnlog("A media device has changed");
|
||||
@ -9673,15 +9845,18 @@ function reconnectDevices(event) { /// TODO: Perhaps change this to only if the
|
||||
function resetupAudioOut() {
|
||||
if ((iOS) || (iPad)) {
|
||||
for (var UUID in session.rpcs) {
|
||||
if (session.rpcs[UUID].videoElement) {
|
||||
session.rpcs[UUID].videoElement.pause().then(() => {
|
||||
setTimeout(function(uuid) {
|
||||
session.rpcs[uuid].videoElement.play().then(() => {
|
||||
log("toggle pause/play");
|
||||
});
|
||||
}, 0, UUID);
|
||||
|
||||
});
|
||||
if (session.rpcs[UUID].videoElement){
|
||||
try{
|
||||
session.rpcs[UUID].videoElement.pause().then(() => {
|
||||
setTimeout(function(uuid) {
|
||||
try{
|
||||
session.rpcs[uuid].videoElement.play().then(() => {
|
||||
log("toggle pause/play");
|
||||
});
|
||||
} catch(e){errorlog(e);}
|
||||
}, 0, UUID);
|
||||
});
|
||||
} catch(e){errorlog(e);}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -9979,7 +10154,8 @@ if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // this ena
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: source.id
|
||||
chromeMediaSourceId: source.id,
|
||||
maxFrameRate: 60
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -10278,6 +10454,88 @@ async function grabScreen(quality = 0, audio = true, videoOnEnd = false) {
|
||||
});
|
||||
}
|
||||
|
||||
function sendMediaDevices(UUID){
|
||||
enumerateDevices().then(function(deviceInfos){
|
||||
var data = {};
|
||||
data.UUID = UUID;
|
||||
data.mediaDevices = deviceInfos;
|
||||
session.sendMessage(data, data.UUID);
|
||||
});
|
||||
}
|
||||
|
||||
function changeVideoDevice(index, quality=0){
|
||||
enumerateDevices().then(gotDevices2).then(function() {
|
||||
activatedPreview=false;
|
||||
document.getElementById("videoSource3").selectedIndex = index+"";
|
||||
grabVideo(quality, "videosource", "#videoSource3");
|
||||
});
|
||||
}
|
||||
|
||||
function changeAudioDevice(index){
|
||||
enumerateDevices().then(gotDevices2).then(function() {
|
||||
activatedPreview=false;
|
||||
var audioSelect = document.getElementById("audioSource3").querySelectorAll("input");
|
||||
for (var i = 0; i < audioSelect.length; i++) {
|
||||
audioSelect[i].checked = false;
|
||||
}
|
||||
audioSelect[index-1].checked = true;
|
||||
grabAudio("videosource", "#audioSource3");
|
||||
});
|
||||
}
|
||||
|
||||
function changeVideoDeviceById(deviceID, UUID){
|
||||
enumerateDevices().then(gotDevices2).then(function() {
|
||||
var opts = document.getElementById("videoSource3").options;
|
||||
var index = false
|
||||
for (var opt, j = 0; opt = opts[j]; j++) {
|
||||
if (opt.value == deviceID) {
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var allow = false
|
||||
if (index!==false){
|
||||
allow = confirm("Allow the director to change your video device to :"+opts[index].text+" ?");
|
||||
}
|
||||
if (allow){
|
||||
document.getElementById("videoSource3").selectedIndex = j;
|
||||
activatedPreview=false;
|
||||
grabVideo(0, "videosource", "#videoSource3");
|
||||
setTimeout(function(uuid){
|
||||
var data = {};
|
||||
data.UUID = uuid;
|
||||
data.videoOptions = listVideoSettingsPrep();
|
||||
session.sendMessage(data, data.UUID);
|
||||
},1000, UUID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function changeAudioDeviceById(deviceID, UUID){
|
||||
var allow = false;
|
||||
allow = confirm("Allow the director to change your audio mic source?");
|
||||
if (allow){
|
||||
enumerateDevices().then(gotDevices2).then(function() {
|
||||
var audioSelect = document.getElementById("audioSource3").querySelectorAll("input");
|
||||
for (var i = 0; i < audioSelect.length; i++) {
|
||||
if (audioSelect[i].value == deviceID){
|
||||
audioSelect[i].checked=true;
|
||||
} else {
|
||||
audioSelect[i].checked = false;
|
||||
}
|
||||
}
|
||||
activatedPreview=false;
|
||||
grabAudio("videosource", "#audioSource3");
|
||||
setTimeout(function(uuid){
|
||||
var data = {};
|
||||
data.UUID = uuid;
|
||||
data.audioOptions = listAudioSettingsPrep();
|
||||
session.sendMessage(data, data.UUID);
|
||||
},1000, UUID);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var getUserMediaRequestID = 0;
|
||||
var grabVideoUserMediaTimeout = null;
|
||||
@ -11199,6 +11457,7 @@ session.publishStream = function(v, title="Stream Sharing Session"){ // stream
|
||||
getById("gridlayout").appendChild(container);
|
||||
|
||||
v.className = "tile";
|
||||
|
||||
v.muted = true;
|
||||
v.autoplay = true;
|
||||
v.controls = false;
|
||||
@ -11387,8 +11646,18 @@ session.publishStream = function(v, title="Stream Sharing Session"){ // stream
|
||||
added="&pw="+session.password;
|
||||
}
|
||||
}
|
||||
getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+added;
|
||||
getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+added;
|
||||
|
||||
var pie = "";
|
||||
if (session.pie){
|
||||
if (session.pie!==true){
|
||||
pie = "&pie="+session.pie;
|
||||
} else {
|
||||
pie = "&pie";
|
||||
}
|
||||
}
|
||||
|
||||
getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+added+pie;
|
||||
getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+added+pie;
|
||||
getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px';
|
||||
pokeIframeAPI('started-camera');
|
||||
|
||||
@ -11504,7 +11773,7 @@ session.publishScreen = function(constraints, title="Screen Sharing Session", au
|
||||
if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1){
|
||||
// Electron has no audio.
|
||||
} else {
|
||||
setTimeout(function(){warnUser("No Audio Source was detected.\n\nIf you were wanting to capture an Application's Audio, please see:\nhttp://docs.obs.ninja/audio for an alternative method.");},300);
|
||||
setTimeout(function(){warnUser("No Audio Source was detected.\n\nIf you were wanting to capture an Application's Audio, please see:\nhttps://docs.obs.ninja/help/guides-and-how-tos#audio for some guides.");},300);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11667,8 +11936,17 @@ session.publishScreen = function(constraints, title="Screen Sharing Session", au
|
||||
m.remove();
|
||||
} catch (e){}
|
||||
|
||||
getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID;
|
||||
getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID;
|
||||
var pie = "";
|
||||
if (session.pie){
|
||||
if (session.pie!==true){
|
||||
pie = "&pie="+session.pie;
|
||||
} else {
|
||||
pie = "&pie";
|
||||
}
|
||||
}
|
||||
|
||||
getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+pie;
|
||||
getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+pie;
|
||||
getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px';
|
||||
|
||||
|
||||
@ -12029,9 +12307,17 @@ session.publishFile = function(ele, event, title="Video File Sharing Session"){
|
||||
m.remove();
|
||||
} catch (e){}
|
||||
|
||||
var pie = "";
|
||||
if (session.pie){
|
||||
if (session.pie!==true){
|
||||
pie = "&pie="+session.pie;
|
||||
} else {
|
||||
pie = "&pie";
|
||||
}
|
||||
}
|
||||
|
||||
getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID;
|
||||
getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID;
|
||||
getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+pie;
|
||||
getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+pie;
|
||||
getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px';
|
||||
pokeIframeAPI('started-fileshare');
|
||||
|
||||
@ -12924,6 +13210,7 @@ function updateDirectorsVideo(data, UUID) {
|
||||
videoEle.appendChild(label);
|
||||
}
|
||||
|
||||
|
||||
for (var i in data.cameraConstraints) {
|
||||
try {
|
||||
log(i);
|
||||
@ -14414,14 +14701,23 @@ function generateQRPageCallback(hash) {
|
||||
sendstr += "&quality=2";
|
||||
}
|
||||
}
|
||||
|
||||
var pie = "";
|
||||
if (session.pie){
|
||||
if (session.pie!==true){
|
||||
pie = "&pie="+session.pie;
|
||||
} else {
|
||||
pie = "&pie";
|
||||
}
|
||||
}
|
||||
|
||||
sendstr = 'https://' + location.host + location.pathname + '?push=' + sid + sendstr + title;
|
||||
sendstr = 'https://' + location.host + location.pathname + '?push=' + sid + sendstr + title + pie;
|
||||
|
||||
if (getById("invite_obfuscate").checked) {
|
||||
sendstr = obfuscateURL(sendstr);
|
||||
}
|
||||
|
||||
viewstr = 'https://' + location.host + location.pathname + '?view=' + sid + viewstr + title;
|
||||
viewstr = 'https://' + location.host + location.pathname + '?view=' + sid + viewstr + title + pie;
|
||||
getById("gencontent").style.display = "none";
|
||||
getById("gencontent").className = ""; //
|
||||
getById("gencontent2").style.display = "block";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user