25 Commits
v17.1 ... v17.2

Author SHA1 Message Date
Steve Seguin
4adf5fbe2d Merge pull request #867 from steveseguin/v17.2.99999
V17.2.99999
2021-05-13 05:15:14 -04:00
Steve Seguin
cee772d031 Delete changepass.html 2021-05-13 05:12:17 -04:00
Steve Seguin
15030fe123 Add files via upload 2021-05-13 05:10:55 -04:00
Steve Seguin
3882583d6c Update electron.html 2021-05-13 03:15:17 -04:00
Steve Seguin
d66a44e57c Update electron.html 2021-05-13 02:50:43 -04:00
Steve Seguin
8cbd26e34b Update electron.html 2021-05-13 02:41:10 -04:00
Steve Seguin
98c293d436 Merge pull request #866 from jcalado/master
electron.html - remember last 5 used urls
2021-05-12 17:43:35 -04:00
Joel Calado
14cf419e31 last 5 urls instead of last url 2021-05-12 22:34:46 +01:00
Joel Calado
74670f5dd0 remember last used url 2021-05-12 21:11:58 +01:00
Steve Seguin
58e07f58d9 Merge pull request #865 from jcalado/master
overhaul of the electron capture UI
2021-05-12 14:25:12 -04:00
Joel Calado
bc5fd78196 overhaul of the electron capture UI 2021-05-12 19:19:43 +01:00
Steve Seguin
612949ba64 Merge pull request #864 from Jumper78/fix/link-to-advanced-settings
correct link to advanced documentation
2021-05-12 07:20:10 -04:00
Jumper78
2bf59f0c2a correct link to advanced documentation
the link to advanced documentation has pointed to a non-existing page; I pointed it to: https://docs.obs.ninja/advanced-settings
2021-05-12 13:13:08 +02:00
Steve Seguin
495f508919 Update README.md 2021-05-07 04:16:45 -04:00
Steve Seguin
2de7c38d7f Merge pull request #855 from duncanbarnes/master
iFrame styling in CSS not JS
2021-05-05 07:24:53 -04:00
Duncan Barnes
2be4038885 iFrame styling in CSS not JS
Small change, moved iframe styling to CSS, allows &css param to override iframe styling without requiring !important on the end of values.
2021-05-05 12:19:48 +01:00
Steve Seguin
b92af980fb Update update-advanced-settings-toc.yml 2021-05-04 07:39:44 -04:00
Steve Seguin
f734d63118 Update update-advanced-settings-toc.yml 2021-05-04 07:36:30 -04:00
Steve Seguin
3859cb2762 Fires every Feb 31st now 2021-05-04 07:34:44 -04:00
Steve Seguin
8934838954 Merge pull request #853 from steveseguin/jcalado-patch-1
fix typo
2021-05-02 03:28:19 -04:00
Joel Calado
e5f203e178 fix typo 2021-05-02 08:25:36 +01:00
Steve Seguin
a296ba8417 Update main.js 2021-04-26 02:37:52 -04:00
Steve Seguin
a843d3d04d Version 17.2
More bug fixes; &optimize command logic made more visible

I may do a v17.3 within the next week and a few more iterations after that, before working on v18
2021-04-25 21:27:19 -04:00
Steve Seguin
bb1061f22f Merge pull request #844 from steveseguin/generated_translations
[OBSNinja Bot] Updated translations
2021-04-23 03:15:09 -04:00
steveseguin
29458e4a87 Generated updated translations 2021-04-23 07:13:23 +00:00
11 changed files with 471 additions and 233 deletions

View File

@@ -2,7 +2,7 @@ name: Update Advanced Settings Markdown TOC
on:
workflow_dispatch:
schedule:
- cron: '0 3 * * *'
- cron: '0 0 29 2 1'
jobs:
update-toc:

View File

@@ -63,9 +63,6 @@ http://chat.overlay.ninja/
A website designed to also work with OBS.Ninja as a Broadcasting tool. Share your webcam, window, desktop, or video file with friends and family. Peer-2-peer, so privacy can be maintained, but you can also list your broadcasts for others to watch.
https://steves.app/
### StageTEN.tv
A browser-based studio solution and simplified alternative to OBS, with built-in OBS.Ninja functionality. It is a server-based approach to group interactions and live production. Steve Seguin is affiliated with StageTEn, yet StageTEN is not affiliated with OBS.Ninja.
## Privacy
I try to avoid data collection whenever possible and video streams are generally designed to be private, but use at your own risk. It is best to not share links created with OBS.Ninja with those you do not trust. I've provided instructions on how to deploy a TURN server if IP-address privacy is an issue for you. See: [turnserver.md](turnserver.md)

View File

@@ -1,11 +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;
overflow: hidden;
}
video {
@@ -21,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;
@@ -43,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;
@@ -84,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) {
@@ -104,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;
}
}
@@ -119,38 +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>
<input type="checkbox" class="check" id="prefervp9" name="prefervp9" value="false" onclick="modURL(this);">
<label for="prefervp9">Force VP9 Codec</label>
<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>
<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>
@@ -163,9 +262,84 @@ 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 resetHistory(){
localStorage.clear();
document.querySelector('#lastUrls').innerHTML = '';
lastUrls = [];
}
if (navigator.userAgent.indexOf('Mac OS X') != -1){
document.getElementById("warning4mac").style.display="block";
} else if (location.hostname.toLowerCase() == "obs.ninja"){
try {
if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // for now, just PC or Linux versions only.
function compareVersions(version){
version = version.split(".");
fetch('https://api.github.com/repos/steveseguin/electroncapture/releases/latest')
.then(response => response.json())
.then(data => {
console.log("recentVersion: "+data.tag_name);
var recentVersion = data.tag_name.split(".");
var ood = false;
if (recentVersion[0]>version[0]){
ood = true;
} else if (recentVersion[0]==version[0]) {
if (recentVersion[1]>version[1]){
ood = true;
} else if (recentVersion[1]==version[1]) {
if (recentVersion[2]>version[2]){
ood = true;
}
}
}
if (ood){
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');
console.log("version: "+ver);
compareVersions(ver);
} else{
var checkVersion = setTimeout(function(){ // pre 1.5.2
compareVersions("0.0.0");
},500);
const ipcRenderer = require('electron').ipcRenderer;
console.log("ELECTRON DETECTED");
ipcRenderer.on('appVersion', function(event, version) {
clearTimeout(checkVersion);
console.log("version: "+version);
compareVersions(version);
})
ipcRenderer.send('getAppVersion');
}
}
} catch(e){console.error(e);}
}
var audioOutputSelect = document.querySelector('select#audioOutput');
@@ -249,9 +423,9 @@ if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(naviga
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;
@@ -304,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.");
@@ -367,27 +509,4 @@ function gohere(){
getPermssions();
</script>
</body>
</html>
</html>

View File

@@ -55,7 +55,7 @@
}
</style>
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
<link rel="stylesheet" href="./main.css?ver=56" />
<link rel="stylesheet" href="./main.css?ver=58" />
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.min.js"></script>
</head>
<body id="main" class="hidden">
@@ -67,7 +67,7 @@
<link itemprop="url" href="./media/obsNinja_logo_full.png" />
</span>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=31"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=184"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=185"></script>
<input id="zoomSlider" type="range" style="display: none;" />
<div id="header">
@@ -167,7 +167,7 @@
<span
id="helpbutton"
title="Show Help Info"
onclick="warnUser('For support, please browse https://reddit.com/r/obsninja or join the live chat on Discord at https://discord.obs.ninja.\n\nThe Wiki also contains many help guides and advanced settings, located at https://wiki.obs.ninja.\n\nTo access the video stats menu, hold CTRL (command) and Left-Click on a video. Most video issues can be fixed by using Wired Internet instead of Wi-Fi.')"
onclick="warnUser('For support, please browse https://reddit.com/r/obsninja or join the live chat on Discord at https://discord.obs.ninja.\n\nThe documention also contains many guides and advanced settings, located at https://docs.obs.ninja.\n\nTo access the video stats menu, hold CTRL (command) and Left-Click on a video. Most video issues can be fixed by using Wired Internet instead of Wi-Fi.')"
style="cursor: pointer; display:none;"
alt="How to Use This with OBS"
>
@@ -594,7 +594,7 @@
</div>
</div>
<div>See the
<a style="text-decoration: none; color: blue;" target="_blank" href="https://docs.obs.ninja/advanced">documentation</a> for more options and info.
<a style="text-decoration: none; color: blue;" target="_blank" href="https://docs.obs.ninja/advanced-settings">documentation</a> for more options and info.
</div>
</div>
</div>
@@ -703,19 +703,19 @@
</i>
<br />
<li>
If you have <a href="https://github.com/steveseguin/obsninja/wiki/FAQ#video-is-pixelated">"pixel smearing"</a> or corrupted video, try adding <i>&codec=h264</i> or <i>&codec=vp9</i> to the OBS view link. Using Wi-Fi will make the issue worse.
If you have <a href="https://docs.obs.ninja/common-errors-and-known-issues/video-is-pixelated">"pixel smearing"</a> or corrupted video, try adding <i>&codec=h264</i> or <i>&codec=vp9</i> to the OBS view link. Using Wi-Fi will make the issue worse.
</li>
<li>
A list of less common issues can <a href="https://github.com/steveseguin/obsninja/wiki/Known-Issues-(browser-bugs-and-more)">be found here</a>.
A list of less common issues can <a href="https://docs.obs.ninja/common-errors-and-known-issues/known-issues-browser-bugs-and-more">be found here</a>.
</li>
<br />
👓🔆 Site Updated on April 20th: <a href="https://github.com/steveseguin/obsninja/wiki/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.
👓🔆 Site Updated on April 20th: <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.gg/T4xpQVv">Discord <i class="lab la-discord"></i></a>. The <a href="https://github.com/steveseguin/obsninja/wiki/">Wiki is 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>
@@ -771,7 +771,7 @@
<li>Adding &showonly=SOME_OBS_VIRTUALCAM to the guest invite links allows for only a single video to be seen by the guests; this can be output of the OBS Virtual Camera for example</li>
<br />
For advanced URL options and parameters, <a href="https://github.com/steveseguin/obsninja/wiki/Advanced-Settings">see the Wiki.</a>
For advanced URL options and parameters, <a href="https://docs.obs.ninja/advanced-settings">see the Documentation.</a>
</font>
</div>
</div>
@@ -1085,27 +1085,25 @@
</button>
<span id="sceneGroup1" class="hidden" data-cluster="1" >
<button style="width: 35.2px" data-scene="3" data-action-type="add-scene-3" title="Add to Scene 3" onclick="directEnable(this, event, 3);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="3" data-action-type="add-scene-3" title="Add to Scene 3" onclick="directEnable(this, event, 3);">
<span >S3</span>
</button>
<button style="width:35.2px;" data-scene="4" data-action-type="add-scene-4" title="Add to Scene 4" onclick="directEnable(this, event, 4);">
<button style="width:35.2px;" data-action-type="addToScene" data-scene="4" data-action-type="add-scene-4" title="Add to Scene 4" onclick="directEnable(this, event, 4);">
<span >S4</span>
</button>
<button style="width: 35.2px" data-scene="5" data-action-type="add-scene-5" title="Add to Scene 5" onclick="directEnable(this, event, 5);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="5" data-action-type="add-scene-5" title="Add to Scene 5" onclick="directEnable(this, event, 5);">
<span >S5</span>
</button>
</span>
<span id="sceneGroup2" class="hidden" data-cluster="1">
<button style="width: 35.2px" data-scene="6" data-action-type="add-scene-6" title="Add to Scene 6" onclick="directEnable(this, event, 6);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="6" data-action-type="add-scene-6" title="Add to Scene 6" onclick="directEnable(this, event, 6);">
<span >S6</span>
</button>
<button style="width: 35.2px" data-scene="7" data-action-type="add-scene-7" title="Add to Scene 7" onclick="directEnable(this, event, 7);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="7" data-action-type="add-scene-7" title="Add to Scene 7" onclick="directEnable(this, event, 7);">
<span >S7</span>
</button>
<button style="width: 35.2px" data-scene="8" data-action-type="add-scene-8" title="Add to Scene 8" onclick="directEnable(this, event, 8);">
<button style="width: 35.2px" data-action-type="addToScene" data-scene="8" data-action-type="add-scene-8" title="Add to Scene 8" onclick="directEnable(this, event, 8);">
<span >S8</span>
</button>
</span>
@@ -1235,31 +1233,31 @@
<i class="las la-plus-square"></i>
<span data-translate="add-to-scene">add to scene 1</span>
</button>
<button data-action-type="mute-scene" title="Remotely Mute this Audio in all remote '&scene' views" onclick="directMute(this, event);">
<button data-action-type="mute-scene" title="Remotely Mute this Audio in all remote '&scene' views" onclick="directMute(this, event);">
<i class="las la-microphone-slash"></i>
<span data-translate="mute-scene" >mute in scene</span>
</button>
<span id="sceneGroup1">
<button style="width: 35.2px" data-scene="2" data-action-type="add-scene-2" title="Add to Scene 2" onclick="directEnable(this, event, 2);">
<button style="width: 35.2px" data-scene="2" data-action-type="addToScene" data-action-type="add-scene-2" title="Add to Scene 2" onclick="directEnable(this, event, 2);">
<span >S2</span>
</button>
<button style="width:35.2px;" data-scene="3" data-action-type="add-scene-3" title="Add to Scene 3" onclick="directEnable(this, event, 3);">
<button style="width:35.2px;" data-scene="3" data-action-type="addToScene" data-action-type="add-scene-3" title="Add to Scene 3" onclick="directEnable(this, event, 3);">
<span >S3</span>
</button>
<button style="width: 35.2px" data-scene="4" data-action-type="add-scene-4" title="Add to Scene 4" onclick="directEnable(this, event, 4);">
<button style="width: 35.2px" data-scene="4" data-action-type="addToScene" data-action-type="add-scene-4" title="Add to Scene 4" onclick="directEnable(this, event, 4);">
<span >S4</span>
</button>
</span>
<span id="sceneGroup2">
<button style="width: 35.2px" data-scene="5" data-action-type="add-scene-5" title="Add to Scene 5" onclick="directEnable(this, event, 5);">
<button style="width: 35.2px" data-scene="5" data-action-type="addToScene" data-action-type="add-scene-5" title="Add to Scene 5" onclick="directEnable(this, event, 5);">
<span >S5</span>
</button>
<button style="width: 35.2px" data-scene="6" data-action-type="add-scene-6" title="Add to Scene 6" onclick="directEnable(this, event, 6);">
<button style="width: 35.2px" data-scene="6" data-action-type="addToScene" data-action-type="add-scene-6" title="Add to Scene 6" onclick="directEnable(this, event, 6);">
<span >S6</span>
</button>
<button style="width: 35.2px" data-scene="7" data-action-type="add-scene-7" title="Add to Scene 7" onclick="directEnable(this, event, 7);">
<button style="width: 35.2px" data-scene="7" data-action-type="addToScene" data-action-type="add-scene-7" title="Add to Scene 7" onclick="directEnable(this, event, 7);">
<span >S7</span>
</button>
</span>
@@ -1489,6 +1487,8 @@
<div id="voiceMeterTemplate" class="video-meter">
</div>
<div id="voiceMeterTemplate2" class="video-meter2">
</div>
<div id="muteStateTemplate" style="display:none;" class="video-mute-state">
<i class="las la-microphone-slash"></i>
</div>
@@ -1506,7 +1506,7 @@
<div id="screenPopup" class="popup-screen">
<button onclick="getById('screenPopup').style.display='none';margin:0;padding:0;">Close Window</button>
<div>See the
<a style="text-decoration: none; color: blue;" target="_blank" href="https://docs.obs.ninja/advanced">documentation</a> for more options and info.
<a style="text-decoration: none; color: blue;" target="_blank" href="https://docs.obs.ninja/advanced-settings">documentation</a> for more options and info.
</div>
</div>
@@ -1554,7 +1554,7 @@
}
var session = WebRTC.Media; // session is a required global variable if configuring manually. Run before loading main.js but after webrtc.js.
session.version = "17.1";
session.version = "17.2";
session.streamID = session.generateStreamID(); // randomly generates a streamID for this session. You can set your own programmatically if needed
session.defaultPassword = "someEncryptionKey123"; // Disabling improves compatibility and is helpful for debugging.
@@ -1624,7 +1624,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=192"></script>
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=194"></script>
<script type="text/javascript">
setTimeout(function(){ // lazy load
var script = document.createElement('script');

View File

@@ -226,7 +226,7 @@ button.white:active {
text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1);
width:100%;
height:100vh;
z-index: 1;
z-index: 6;
vertical-align: top;
text-align: center;
top: 0;
@@ -2395,10 +2395,33 @@ span#guestTips {
pointer-events:none;
border: 1px black solid;
}
.video-meter-director {
width: 10px;
height: 10px;
top: 8px;
right: 10px;
}
.video-meter2 {
padding:0;
width: 4px;
height:0%;
min-width:2px;
bottom: 1px;
right: 5px;
background-color:#0000;
position:absolute;
border-radius: 2vh;
pointer-events:none;
border: 1px black solid;
transition: height 0.1s ease, background-color 0.1s ease;
}
#voiceMeterTemplate{
display:none;
}
#voiceMeterTemplate2{
display:none;
}
#userList{
line-height: 1.3em;

226
main.js
View File

@@ -858,9 +858,13 @@ if (/CriOS/i.test(navigator.userAgent) && (iOS || iPad)) {
}
}
if (urlParams.has('tips')){
getById("guestTips").style.display="flex";
}
if (urlParams.has('broadcast') || urlParams.has('bc')) {
log("Broadcast flag set");
session.broadcast = urlParams.get('broadcast') || urlParams.get('bc');
session.broadcast = urlParams.get('broadcast') || urlParams.get('bc') || null;
//if ((iOS) || (iPad)) {
// session.nopreview = false;
//} else {
@@ -890,7 +894,7 @@ if (urlParams.has('showlist')) {
var directorLanding = false;
if (urlParams.has('director') || urlParams.has('dir')) {
directorLanding = urlParams.get('director') || urlParams.get('dir');
directorLanding = urlParams.get('director') || urlParams.get('dir') || null;
if (directorLanding === null) {
directorLanding = true;
} else if (directorLanding.length === 0) {
@@ -2373,7 +2377,10 @@ if (urlParams.has('activespeaker') || urlParams.has('speakerview') || urlParams
session.audioEffects = true;
session.audioMeterGuest = true;
setInterval(function(){activeSpeaker(false)},100);
}
if (urlParams.has('meter') || urlParams.has('meterstyle')){
session.meterStyle = urlParams.get('meter') || urlParams.get('meterstyle') || 1;
}
if (urlParams.has('style') || urlParams.has('st')) {
@@ -2461,6 +2468,7 @@ if (urlParams.has('turn')) {
}
} else if ((turnstring == "false") || (turnstring == "off") || (turnstring == "0")) { // disable TURN servers
if (!session.configuration){session.configuration={};}
session.configuration = {
iceServers: [
{ urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"]} // more than 4 stun+turn servers will cause firefox issues? (2 + 2 for now then)
@@ -2475,9 +2483,12 @@ if (urlParams.has('turn')) {
turn.username = turnstring[0]; // myusername
turn.credential = turnstring[1]; //mypassword
turn.urls = [turnstring[2]]; // ["turn:turn.obs.ninja:443"];
session.configuration.iceServers = [{
urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"]
}];
session.configuration = {
iceServers: [
{ urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"]} // more than 4 stun+turn servers will cause firefox issues? (2 + 2 for now then)
],
sdpSemantics: 'unified-plan' // future-proofing
};
session.configuration.iceServers.push(turn);
}
} catch (e) {
@@ -4318,7 +4329,7 @@ function TFLiteWorker(){
URL.revokeObjectURL(session.tfliteModule.img.src); // no longer needed, free memory
session.tfliteModule.img.ready = true;
}
session.tfliteModule.img.src = "./media/bg_sample.jpg";
session.tfliteModule.img.src = "./media/bg_sample.webp";
session.tfliteModule.img.ready = false;
console.log('Starting Loop');
@@ -5883,7 +5894,7 @@ function directEnable(ele, event, scene=1, director=false) { // A directing room
if (!((event.ctrlKey) || (event.metaKey))) {
if (ele.dataset.value == 1) {
ele.dataset.value = 0;
ele.className = "";
ele.classList.remove("pressed");
if (ele.children[1]){
ele.children[1].innerHTML = "Add to Scene "+scene;
if (director){
@@ -5894,7 +5905,7 @@ function directEnable(ele, event, scene=1, director=false) { // A directing room
}
} else {
ele.dataset.value = 1;
ele.className = "pressed";
ele.classList.add("pressed");
if (ele.children[1]){
ele.children[1].innerHTML = "Remove";
if (director){
@@ -5906,14 +5917,25 @@ function directEnable(ele, event, scene=1, director=false) { // A directing room
}
}
var msg = {};
msg.request = "sendroom";
msg.scene = scene;
msg.action = "display";
msg.value = ele.dataset.value;
msg.target = ele.dataset.sid;
//session.anysend(msg);
session.sendMsg(msg); // send to everyone in the room, so they know if they are on air or not.
for (var uuid in session.pcs){
if (session.pcs[uuid].stats.info && ("version" in session.pcs[uuid].stats.info) && (session.pcs[uuid].stats.info.version < 17.2)){
msg.request = "sendroom";
session.sendMsg(msg);
return;
}
}
for (var uuid in session.pcs){
if (session.pcs[uuid].scene!==false){ // send to all scenes (but scene = 0)
session.sendMessage(msg, uuid);
}
}
}
var previousURL = "";
@@ -5976,24 +5998,36 @@ function directPageReload(ele, event) {
function directMute(ele, event=false) { // A directing room only is controlled by the Director, with the exception of MUTE.
log("mute");
if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
if (ele.dataset.value == 0) {
ele.dataset.value = 1;
ele.className = "";
ele.classList.remove("pressed");
ele.children[1].innerHTML = "Mute in scene";
} else {
ele.dataset.value = 0;
ele.className = "pressed";
ele.classList.add("pressed");
ele.children[1].innerHTML = "Un-mute";
}
}
var msg = {};
msg.request = "sendroom";
msg.scene = "1";
msg.scene = true;
msg.action = "mute";
msg.value = ele.dataset.value;
msg.target = ele.dataset.sid;
session.sendMsg(msg); // send to everyone in the room, so they know if they are on air or not.
for (var uuid in session.pcs){
if (session.pcs[uuid].stats.info && ("version" in session.pcs[uuid].stats.info) && (session.pcs[uuid].stats.info.version < 17.2)){
msg.request = "sendroom";
session.sendMsg(msg);
return;
}
}
for (var uuid in session.pcs){
if (session.pcs[uuid].scene!==false){ // send to all scenes (but scene = 0)
session.sendMessage(msg, uuid);
}
}
}
function remoteSpeakerMute(ele, event=false){
@@ -6001,20 +6035,20 @@ function remoteSpeakerMute(ele, event=false){
if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
if (ele.dataset.value == 1) {
ele.dataset.value = 0;
ele.className = "";
ele.classList.remove("pressed");
ele.children[1].innerHTML = "deafen guest";
} else {
ele.dataset.value = 1;
ele.className = "pressed";
ele.classList.add("pressed");
ele.children[1].innerHTML = "Un-deafen";
}
}
var msg = {};
if (ele.dataset.value == 0) {
msg.speakerMute = ele.dataset.value;
msg.speakerMute = false
} else {
msg.speakerMute = ele.dataset.value;
msg.speakerMute = true;
}
msg.UUID = ele.dataset.UUID;
session.sendRequest(msg, ele.dataset.UUID);
@@ -6025,7 +6059,6 @@ function updateRemoteSpeakerMute(UUID) {
if (ele[0]) {
ele[0].classList.add("pressed");
ele[0].dataset.value = 1;
ele[0].className = "pressed";
ele[0].children[1].innerHTML = "Un-deafen";
}
}
@@ -6035,7 +6068,6 @@ function updateRemoteDisplayMute(UUID) {
if (ele[0]) {
ele[0].classList.add("pressed");
ele[0].dataset.value = 1;
ele[0].className = "pressed";
ele[0].children[1].innerHTML = "Un-blind";
}
}
@@ -6045,11 +6077,11 @@ function remoteDisplayMute(ele, event=false) {
if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
if (ele.dataset.value == 1) {
ele.dataset.value = 0;
ele.className = "";
ele.classList.remove("pressed");
ele.children[1].innerHTML = "blind guest";
} else {
ele.dataset.value = 1;
ele.className = "pressed";
ele.classList.add("pressed");
ele.children[1].innerHTML = "Un-blind";
}
}
@@ -6077,11 +6109,11 @@ function remoteMute(ele, event=false) {
if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
if (ele.dataset.value == 1) {
ele.dataset.value = 0;
ele.className = "";
ele.classList.remove("pressed");
ele.children[1].innerHTML = "mute guest";
} else {
ele.dataset.value = 1;
ele.className = "pressed";
ele.classList.add("pressed");
ele.children[1].innerHTML = "Un-mute guest";
}
}
@@ -6116,11 +6148,11 @@ function remoteMuteVideo(ele, event=false) {
} else {
if (ele.dataset.value == 1) {
ele.dataset.value = 0;
ele.className = "";
ele.classList.remove("pressed");
ele.children[1].innerHTML = "hide guest";
} else {
ele.dataset.value = 1;
ele.className = "pressed";
ele.classList.add("pressed");
ele.children[1].innerHTML = "Unhide guest";
}
ele.style.backgroundColor = null;
@@ -6150,7 +6182,7 @@ function updateDirectorVideoMute(UUID) {
var ele = document.querySelectorAll('[data-action-type="hide-guest"][data--u-u-i-d="' + UUID + '"]');
if (ele[0]) {
ele[0].dataset.value = 1;
ele[0].className = "pressed";
ele[0].classList.add("pressed");
ele[0].children[1].innerHTML = "Unhide guest";
}
}
@@ -6158,12 +6190,24 @@ function updateDirectorVideoMute(UUID) {
function directVolume(ele) { // NOT USED ANYMORE
log("volume");
var msg = {};
msg.request = "sendroom";
msg.scene = "1";
msg.scene = true;
msg.action = "volume";
msg.target = ele.dataset.sid; // i want to focus on the STREAM ID, not the UUID...
msg.value = ele.value;
session.sendMsg(msg); // send to everyone in the room, so they know if they are on air or not.
for (var uuid in session.pcs){
if (session.pcs[uuid].stats.info && ("version" in session.pcs[uuid].stats.info) && (session.pcs[uuid].stats.info.version < 17.2)){
msg.request = "sendroom";
session.sendMsg(msg);
return;
}
}
for (var uuid in session.pcs){
if (session.pcs[uuid].scene!==false){ // send to all scenes (but scene = 0)
session.sendMessage(msg, uuid);
}
}
}
function remoteVolumeUI(ele){
@@ -7507,7 +7551,7 @@ function getDirectorSettings(scene){
if (parseInt(eles[i].dataset.value)==1){
warnlog(eles[i]);
if (eles[i].dataset.sid){
settings.soloVideo = eles[i].dataset.sid;
settings.soloVideo = eles[i].dataset.sid; // who is solo, if someone is solo
}
}
}
@@ -7531,7 +7575,22 @@ function getDirectorSettings(scene){
}
}
}
return settings
settings.mute = {};
var eles = document.querySelectorAll('[data-action-type="mute-scene"]');
for (var i=0;i<eles.length;i++) {
if (parseInt(eles[i].dataset.value)==0){ // if muted
if (eles[i].dataset.sid){
var msg = {};
msg.action = "mute";
msg.scene = true;
msg.value = eles[i].dataset.value;
msg.target = eles[i].dataset.sid;
settings.mute[eles[i].dataset.sid]=msg;
}
}
}
return settings;
}
function requestInfocus(ele) {
@@ -7701,19 +7760,17 @@ function createControlBox(UUID, soloLink, streamID) {
</div>";
if (!session.rpcs[UUID].voiceMeter) {
session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true);
if (session.meterStyle==1){
session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate2").cloneNode(true);
} else {
session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true);
session.rpcs[UUID].voiceMeter.classList.add("video-meter-director");
session.rpcs[UUID].voiceMeter.style.opacity = 0;
}
session.rpcs[UUID].voiceMeter.id = "voiceMeter_" + UUID;
session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary
//session.rpcs[UUID].voiceMeter.style.display = "block";
session.rpcs[UUID].voiceMeter.dataset.level = 0;
}
session.rpcs[UUID].voiceMeter.style.width = "10px";
session.rpcs[UUID].voiceMeter.style.height = "10px";
session.rpcs[UUID].voiceMeter.style.top = "8px";
session.rpcs[UUID].voiceMeter.style.right = "10px";
session.rpcs[UUID].remoteMuteElement = getById("muteStateTemplate").cloneNode(true);
session.rpcs[UUID].remoteMuteElement.id = "";
session.rpcs[UUID].remoteMuteElement.style.top = "1vh";
@@ -14706,7 +14763,7 @@ function toggleQualityDirector(bitrate, UUID, ele = null) { // ele is specific t
for (var i=0;i<eles.length;i++) {
eles[i].className = "";
}
ele.className = "pressed";
ele.classList.add("pressed");
session.requestRateLimit(bitrate, UUID);
}
@@ -14761,14 +14818,7 @@ function getChatMessage(msg, label = false, director = false, overlay = false) {
label = "";
}
data.type = "recv";
messageList.push(data);
messageList = messageList.slice(-100);
if (session.beepToNotify) {
playtone();
}
updateMessages();
if (overlay) {
if (!(session.cleanOutput)){
var textOverlay = getById("overlayMsgs");
@@ -14787,6 +14837,22 @@ function getChatMessage(msg, label = false, director = false, overlay = false) {
}
}
}
if (isIFrame) {
parent.postMessage({
"gotChat": data
}, "*");
}
if (session.chatbutton===false){return;} // messages can still appear as overlays ^
messageList.push(data);
messageList = messageList.slice(-100);
if (session.beepToNotify) {
playtone();
}
updateMessages();
if (session.chat == false) {
getById("chattoggle").className = "las la-comments my-float toggleSize puslate";
@@ -14801,11 +14867,7 @@ function getChatMessage(msg, label = false, director = false, overlay = false) {
}
if (isIFrame) {
parent.postMessage({
"gotChat": data
}, "*");
}
if (session.broadcastChannel !== false) {
session.broadcastChannel.postMessage(data); /* send */
}
@@ -14863,6 +14925,7 @@ function updateClosedCaptions(msg, label, UUID) {
}
function updateMessages() {
if (session.chatbutton===false){return;}
document.getElementById("chatBody").innerHTML = "";
for (i in messageList) {
@@ -15945,21 +16008,37 @@ function audioMeterGuest(mediaStreamSource, UUID, trackid){
if (session.audioMeterGuest===false){return;} // don't show if we just want the volume levels
if (session.rpcs[UUID].voiceMeter){
if (total>15){
session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary
} else {
session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary
}
session.rpcs[UUID].voiceMeter.dataset.level = total;
} else {
session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true);
session.rpcs[UUID].voiceMeter.id = "voiceMeter_"+UUID;
if (total>15){
session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary
if (session.meterStyle==1){
session.rpcs[UUID].voiceMeter.style.height = Math.min(total,100) + "%";
if (total>75){
total = Math.min(100,(total - 75)*4);
var R = parseInt((255 * total) / 100).toString(16).padStart(2, '0');
var G = parseInt(255 * (100 - total) / 100).toString(16).padStart(2, '0');
session.rpcs[UUID].voiceMeter.style.backgroundColor = "#" + R + G + "00";
} else {
session.rpcs[UUID].voiceMeter.style.backgroundColor = "#00FF00";
}
} else {
session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary
if (total>15){
session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary
} else {
session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary
}
}
//session.rpcs[UUID].voiceMeter.style.display = "block";
} else {
if (session.meterStyle==1){
session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate2").cloneNode(true);
} else {
session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true);
if (total>15){
session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary
} else {
session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary
}
}
session.rpcs[UUID].voiceMeter.id = "voiceMeter_"+UUID;
session.rpcs[UUID].voiceMeter.dataset.level = total;
updateMixer();
}
@@ -16018,7 +16097,7 @@ function effectsDynamicallyUpdate(event, ele, preview=true){
}
} else if (effect === "5"){
if (session.tfliteModule.img){
session.tfliteModule.img.src = "./media/bg_sample.jpg";
session.tfliteModule.img.src = "./media/bg_sample.webp";
}
if ((session.effects<3) || (session.effects>5)){
session.effects = 5;
@@ -16317,7 +16396,7 @@ if (session.midiHotkeys) {
} else if (value == 3) {
var elements = document.querySelectorAll('[data-action-type="mute-guest"][data--u-u-i-d]');
if (elements[guestslot]) {
directMute(elements[guestslot], true);
remoteMute(elements[guestslot], true);
}
} else if (value == 4) {
var elements = document.querySelectorAll('[data-action-type="hangup"][data--u-u-i-d]');
@@ -16329,7 +16408,6 @@ if (session.midiHotkeys) {
if (elements[guestslot]) {
session.toggleSoloChat(elements[guestslot].dataset.UUID);
}
} else if (value == 6) {
var elements = document.querySelectorAll('[data-action-type="toggle-remote-speaker"][data--u-u-i-d]');
if (elements[guestslot]) {

View File

@@ -13,6 +13,10 @@ body {
background-color: #141926;
}
#add_screen{
display:none;
}
h1 {
color: white;
margin: 20px 0px;
@@ -24,6 +28,9 @@ h1 small {
font-size: 0.5em;
}
video {
transform: translate(0px, 0%) !important;
}
#explanation {
color: white;
font-family: sans-serif;

View File

@@ -54,6 +54,8 @@
}
}
function loadIframe() {
// this is pretty important if you want to avoid camera permission popup problems. YOu need to load the iFRAME after you load the parent body. A quick solution is like: <body onload=>loadIframe();"> !!!
@@ -70,6 +72,8 @@
streamID = urlParams.get("sid");
}
document.getElementById("remote").innerHTML = "<a style='color:#CCC' href='./monitor?sid="+streamID+"'>Remote Monitoring Link</a><br /><br /><br /><br />";
var iframe = document.createElement("iframe");
@@ -80,7 +84,7 @@
iframe.allowfullscreen ="true";
//iframe.allow = "autoplay";
var srcString = "./?push=" + streamID + "&cleanoutput&privacy&speedtest&webcam&audiodevice=0&fullscreen&transparent&remote";
var srcString = "./?push=" + streamID + "&cleanoutput&privacy&speedtest&"+testType+"&audiodevice=0&fullscreen&transparent&remote";
if (urlParams.has("turn")) {
srcString = srcString + "&turn=" + urlParams.get("turn");
@@ -363,10 +367,20 @@
</li>
</ol>
<div id="screen" style="color: #CCC; margin:10px 0;"><a href="./speedtest?screen" style="color: #CCC;">Test screen-sharing performance here</a></div>
<div id="remote"></div>
</div>
<script>
var testType= "webcam";
if (urlParams.has("screen") || urlParams.has("ss") || urlParams.has("screenshare") || urlParams.has("screentest")) {
document.getElementById("screen").innerHTML = '<a href="./speedtest" style="color: #CCC;">Test webcam-streaming performance here</a>';
testType = "quality=0&screenshare&css=speedtest.css"
}
var bitrate = {
element: "bitrate-graph",
data: 0,

View File

@@ -272,4 +272,4 @@
"enter-the-room-name-here": "Enter the room name here",
"enter-the-room-password-here": "Enter the room password here"
}
}
}

View File

@@ -1,4 +1,4 @@
## Install and setup gudie for a TURN Relay Server
## Install and setup guide for a TURN Relay Server
#### why? You may want to deploy one to ensure high compatiblity with remote guests. If you try to use the official OBS.Ninja TURN servers for a private deployment, you may find yourself getting kicked off.

File diff suppressed because one or more lines are too long