mirror of
https://github.com/SrIzan10/vdo.ninja.git
synced 2026-05-01 11:05:24 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4adf5fbe2d | ||
|
|
cee772d031 | ||
|
|
15030fe123 | ||
|
|
3882583d6c | ||
|
|
d66a44e57c | ||
|
|
8cbd26e34b | ||
|
|
98c293d436 | ||
|
|
14cf419e31 | ||
|
|
74670f5dd0 | ||
|
|
58e07f58d9 | ||
|
|
bc5fd78196 | ||
|
|
612949ba64 | ||
|
|
2bf59f0c2a | ||
|
|
495f508919 | ||
|
|
2de7c38d7f | ||
|
|
2be4038885 | ||
|
|
b92af980fb | ||
|
|
f734d63118 | ||
|
|
3859cb2762 | ||
|
|
8934838954 | ||
|
|
e5f203e178 | ||
|
|
a296ba8417 | ||
|
|
a843d3d04d | ||
|
|
bb1061f22f | ||
|
|
29458e4a87 |
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
365
electron.html
365
electron.html
@@ -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>
|
||||
54
index.html
54
index.html
@@ -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');
|
||||
|
||||
25
main.css
25
main.css
@@ -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
226
main.js
@@ -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]) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -272,4 +272,4 @@
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user