Steve Seguin 2020-08-23 02:55:13 -04:00 committed by GitHub
parent d1d736549d
commit 4c4bdeb026
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 2534 additions and 694 deletions

View File

@ -39,26 +39,46 @@ $(".column").on('click', function() {
styles += '}';
/* Add keyframe to CSS */
$("#lightbox-animations").empty();
$("#lightbox-animations").get(0).sheet.insertRule(styles, 0);
/* Hide the window scrollbar */
$("body").css('overflow', 'hidden');
});
/* Click on close button when full-screen */
$(".close").on('click', function(e) {
$(this).hide();
$(".container-inner").hide();
/* Window scrollbar normal */
$("body").css('overflow', 'auto');
$(this).hide();
$(".container-inner").hide();
$("body").css('overflow', 'auto');
var bounding_box = $(this).parent().get(0).getBoundingClientRect();
$(this).parent().css({ top: bounding_box.top + 'px', left: bounding_box.left + 'px' });
var bounding_box = $(this).parent().get(0).getBoundingClientRect();
$(this).parent().css({ top: bounding_box.top + 'px', left: bounding_box.left + 'px' });
/* Show animation */
$(this).parent().addClass('out-animation');
/* Show animation */
$(this).parent().addClass('out-animation');
e.stopPropagation();
try{
var oldstream = getById('previewWebcam').srcObject;
if (oldstream){
log("old stream found");
oldstream.getTracks().forEach(function(track) {
track.stop();
oldstream.removeTrack(track);
log("stopping old track");
});
}
activatedPreview=false;
} catch (e){
errorlog(e);
}
log("Cleaned up Video");
e.stopPropagation();
});
/* On animationend : from normal to full screen & full screen to normal */
@ -70,34 +90,65 @@ if(e.originalEvent.animationName == 'inlightbox') {
}
/* On animation end from full-screen to normal */
else if(e.originalEvent.animationName == 'outlightbox') {
/* Remove fixed positioning, remove animation rules */
$(this).removeClass('in-animation').removeClass('out-animation').removeClass('columnfade');
/* Remove fixed positioning, remove animation rules */
$(this).removeClass('in-animation').removeClass('out-animation').removeClass('columnfade');
/* Remove the empty container that was earlier added */
$("#empty-container").remove();
/* Remove the empty container that was earlier added */
$("#empty-container").remove();
/* Delete the dynamic keyframe rule that was earlier created */
$("#lightbox-animations").get(0).sheet.deleteRule(0);
/* Delete the dynamic keyframe rule that was earlier created */
$("#lightbox-animations").get(0).sheet.deleteRule(0);
}
});
// multiselect dropdowns
$('#audioSource').on('mousedown touchend focusin focusout', function(e) {
var state = $('.multiselect-trigger').data('state') || 0;
if( state == 0 ) {
// open the dropdown
$('.multiselect-trigger').data('state', '1').addClass('open').removeClass('closed');
$('.multiselect-trigger').find('.chevron').removeClass('bottom');
$('.multiselect-trigger').parent().find('.multiselect-contents').show();
$('.multiselect-trigger').parent().find('.multiselect-contents').find('input[type="checkbox"]').parent().show();;
$('.multiselect-trigger').parent().find('.multiselect-contents').find('input[type="checkbox"]').show();;
var state = $('#multiselect-trigger').data('state') || 0;
if( state == 0 ) {
////open the dropdown
$('#multiselect-trigger').data('state', '1').addClass('open').removeClass('closed');
$('#multiselect-trigger').find('.chevron').removeClass('bottom');
$('#multiselect-trigger').parent().find('.multiselect-contents').show();
$('#multiselect-trigger').parent().find('.multiselect-contents').find('input[type="checkbox"]').parent().show();;
$('#multiselect-trigger').parent().find('.multiselect-contents').find('input[type="checkbox"]').show();;
}
e.preventDefault();
// e.preventDefault();
});
$('#audioSource3').on('mousedown touchend focusin focusout', function(e) {
var state = $('#multiselect-trigger3').data('state') || 0;
if( state == 0 ) {
////open the dropdown
$('#multiselect-trigger3').data('state', '1').addClass('open').removeClass('closed');
$('#multiselect-trigger3').find('.chevron').removeClass('bottom');
$('#multiselect-trigger3').parent().find('.multiselect-contents').show();
$('#multiselect-trigger3').parent().find('.multiselect-contents').find('input[type="checkbox"]').parent().show();;
$('#multiselect-trigger3').parent().find('.multiselect-contents').find('input[type="checkbox"]').show();;
}
// e.preventDefault();
});
// multiselect dropdowns
$('.multiselect-trigger').on('mousedown touchend focusin focusout', function(e) {
$('#multiselect-trigger').on('mousedown touchend focusin focusout', function(e) {
var state = $(this).data('state') || 0;
if( state == 0 ) {
// open the dropdown
$(this).data('state', '1').addClass('open').removeClass('closed');
$(this).find('.chevron').removeClass('bottom');
$(this).parent().find('.multiselect-contents').show();
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').parent().show();;
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').show();;
} else {
// close the dropdown
$(this).data('state', '0').addClass('closed').removeClass('open');
$(this).find('.chevron').addClass('bottom');
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').not(":checked").parent().hide();;
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').hide();;
}
e.preventDefault();
});
// multiselect dropdowns
$('#multiselect-trigger3').on('mousedown touchend focusin focusout', function(e) {
var state = $(this).data('state') || 0;
if( state == 0 ) {
// open the dropdown
@ -110,8 +161,6 @@ $('.multiselect-trigger').on('mousedown touchend focusin focusout', function(e)
// close the dropdown
$(this).data('state', '0').addClass('closed').removeClass('open');
$(this).find('.chevron').addClass('bottom');
//$(this).parent().find('.multiselect-contents').hide();
//$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').hide();
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').not(":checked").parent().hide();;
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').hide();;
}
@ -119,11 +168,5 @@ $('.multiselect-trigger').on('mousedown touchend focusin focusout', function(e)
});
// when no preference is checked, uncheck the others
$('#multiselect1').on('change', function(e) {
if( $(this).is(':checked') ) {
$(this).parent().parent().find('input[type="checkbox"]').not('#multiselect1').prop('checked', false);
}
e.preventDefault();
});

View File

@ -138,9 +138,12 @@ function generateInvite(){
sendstr+="&quality=2";
}
}
sendstr = 'https://obs.ninja/?push=' + sid + sendstr;
viewstr = 'https://obs.ninja/?view=' + sid + viewstr + title;
var href = window.location.href;
var dir = href.substring(0, href.lastIndexOf('/')) + "/";
sendstr = dir+'?push=' + sid + sendstr;
viewstr = dir+'?view=' + sid + viewstr + title;
getById("container-setup").style.display="none";
getById("container-links").style.display="block";
@ -162,7 +165,7 @@ document.addEventListener("dragstart", event => {
var streamId = url.split('view=');
var label = url.split('label=');
url += '&layer-name=OBS.Ninja';
url += '&layer-name=OBSN';
if (streamId.length>1) url += ': ' + streamId[1].split('&')[0];
if (label.length>1) url += ' - ' + decodeURI(label[1].split('&')[0]);

333
dual.html
View File

@ -10,17 +10,20 @@ iframe {
margin:0;
padding:0;
display:block;
margin:10px;
width:40%;;
height:40%;
margin:0px;
min-height: 420px;
min-width: 350px;
max-height: 720px;
max-width: 1280px;
float: left;
position: fixed;
}
#viewlink {
width:400px;
}
#container {
display:block;
padding:0px;
}
input{
padding:5px;
margin:5px;
@ -28,44 +31,296 @@ input{
button{
padding:5px;
margin:5px;
position:relative;
}
.menu {
z-index: 10;
float:right;
right: 20px;
color: #fff;
}
.close {
background-color: #d33;
color: #fff;
}
.reload {
background-color: #0a0;
color: #fff;
}
.popup {
z-index: 9;
background-color: #f1f1f1;
border: 1px solid #d3d3d3;
text-align: center;
min-height: 420px;
min-width: 350px;
max-height: 720px;
max-width: 1280px;
scale: 0.5;
}
.popup {
position: absolute;
/*resize: both; !*enable this to css resize*! */
overflow: auto;
}
.popup-header {
cursor: move;
background-color: #2196f3;
}
.popup .resizer-right {
width: 5px;
height: 100%;
background: transparent;
position: absolute;
right: 0;
bottom: 0;
cursor: e-resize;
}
.popup .resizer-bottom {
width: 100%;
height: 5px;
background: transparent;
position: absolute;
right: 0;
bottom: 0;
cursor: n-resize;
}
.popup .resizer-both {
width: 5px;
height: 5px;
background: transparent;
z-index: 10;
position: absolute;
right: 0;
bottom: 0;
cursor: nw-resize;
}
/*NOSELECT*/
.popup * {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
</style>
<script>
function loadIframe(){
var iframe = document.createElement("iframe");
var iframeContainer = document.createElement("div");
iframe.allow="autoplay";
iframe.src = document.getElementById("viewlink").value;
iframeContainer.appendChild(iframe);
document.getElementById("container").appendChild(iframeContainer);
var button = document.createElement("button");
button.innerHTML = "Close";
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');iframe.parentNode.parentNode.removeChild(iframeContainer);}
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Reload";
button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');}
iframeContainer.appendChild(button);
}
</script>
</head>
<body>
<input placeholder="Enter an OBS.Ninja Room Link" id="viewlink" />
<button onclick="loadIframe();">ADD</button>
<div id="container">
</div>
<button onclick="loadIframe();">Load URL</button>You can drag and resize the generated windows; multiple can be created.
<div id="container"></div>
<script>
function initDragElement(popup){
var pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
var elmnt = null;
var currentZIndex = 100; //TODO reset z index when a threshold is passed
var header = getHeader(popup);
var iframe = getIFrame(popup);
popup.onmousedown = function() {
this.style.zIndex = "" + ++currentZIndex;
};
if (header) {
header.parentPopup = popup;
header.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
elmnt = this.parentPopup;
elmnt.style.zIndex = "" + ++currentZIndex;
e = e || window.event;
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
if (!elmnt) {
return;
}
e = e || window.event;
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = elmnt.offsetTop - pos2 + "px";
elmnt.style.left = elmnt.offsetLeft - pos1 + "px";
iframe.style.top = elmnt.offsetTop - pos2 + "px";
iframe.style.left = elmnt.offsetLeft - pos1 + "px";
}
function closeDragElement() {
/* stop moving when mouse button is released:*/
document.onmouseup = null;
document.onmousemove = null;
}
function getHeader(element) {
var headerItems = element.getElementsByClassName("popup-header");
if (headerItems.length === 1) {
return headerItems[0];
}
return null;
}
function getIFrame(element) {
var headerItems = element.getElementsByTagName("iframe");
if (headerItems.length === 1) {
return headerItems[0];
}
return null;
}
}
function initResizeElement(p) {
var iframe = getIFrame(p);
var element = null;
var startX, startY, startWidth, startHeight;
var right = document.createElement("div");
right.className = "resizer-right";
p.appendChild(right);
right.addEventListener("mousedown", initDrag, false);
right.parentPopup = p;
var bottom = document.createElement("div");
bottom.className = "resizer-bottom";
p.appendChild(bottom);
bottom.addEventListener("mousedown", initDrag, false);
bottom.parentPopup = p;
var both = document.createElement("div");
both.className = "resizer-both";
p.appendChild(both);
both.addEventListener("mousedown", initDrag, false);
both.parentPopup = p;
function initDrag(e) {
element = this.parentPopup;
startX = e.clientX;
startY = e.clientY;
startWidth = parseInt(
document.defaultView.getComputedStyle(element).width,
10
);
startHeight = parseInt(
document.defaultView.getComputedStyle(element).height,
10
);
document.documentElement.addEventListener("mousemove", doDrag, false);
document.documentElement.addEventListener("mouseup", stopDrag, false);
document.documentElement.addEventListener("click", stopDrag, false)
}
function doDrag(e) {
if (e.buttons==0){
stopDrag(e);
return false;
}
element.style.width = startWidth + e.clientX - startX + "px";
element.style.height = startHeight + e.clientY - startY + "px";
iframe.style.width = startWidth + e.clientX - startX + "px";
iframe.style.height = startHeight + e.clientY - startY + "px";
}
function stopDrag(e) {
document.documentElement.removeEventListener("mousemove", doDrag, false);
document.documentElement.removeEventListener("mouseup", stopDrag, false);
}
function getIFrame(element) {
var headerItems = element.getElementsByTagName("iframe");
if (headerItems.length === 1) {
return headerItems[0];
}
return null;
}
}
function loadIframe(){
var iframeContainer = document.createElement("div");
iframeContainer.className="popup";
var button = document.createElement("button");
button.innerHTML = "Move";
button.className = "popup-header menu";
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Close";
button.className = "menu close";
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');iframe.parentNode.parentNode.removeChild(iframeContainer);}
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Reload";
button.className = "menu reload";
button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');}
iframeContainer.appendChild(button);
var iframe = document.createElement("iframe");
iframe.allow="autoplay";
iframe.src = document.getElementById("viewlink").value || "https://obs.ninja";
iframeContainer.appendChild(iframe);
document.getElementById("container").appendChild(iframeContainer);
initDragElement(iframeContainer);
initResizeElement(iframeContainer);
}
</script>
</body>
</html>

View File

@ -4,6 +4,7 @@
body{
padding:0;
margin:0;
background-color: rgb(253,253,253);
}
iframe {
border:0;
@ -11,8 +12,8 @@ iframe {
padding:0;
display:block;
margin:10px;
width:320px;
height:180px;
width:640px;
height:320px;
}
#viewlink {
width:400px;
@ -36,70 +37,160 @@ function loadIframe(){
var iframe = document.createElement("iframe");
var iframeContainer = document.createElement("div");
iframe.allow="autoplay";
var iframesrc = document.getElementById("viewlink").value;
iframe.allow="autoplay;camera;microphone";
iframe.allowtransparency="true"
if (iframesrc==""){
iframesrc="https://obs.ninja/";
}
if (document.getElementById("clean").checked){
iframe.src = document.getElementById("viewlink").value+"&cleanoutput";
} else {
iframe.src = document.getElementById("viewlink").value;
if (iframesrc.includes("?")){
iframesrc+='&';
} else {
iframesrc+='?';
}
iframesrc+="cleanoutput";
}
if (document.getElementById("transparent").checked){
if (iframesrc.includes("?")){
iframesrc+='&';
} else {
iframesrc+='?';
}
iframesrc+="transparent";
}
if (document.getElementById("hidemenu").checked){
if (iframesrc.includes("?")){
iframesrc+='&';
} else {
iframesrc+='?';
}
iframesrc+="hidemenu";
}
iframe.src = iframesrc;
iframeContainer.appendChild(iframe);
document.getElementById("container").appendChild(iframeContainer);
var button = document.createElement("button");
button.innerHTML = "Mute";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":true}, '*');}
button.innerHTML = "Mute Speaker";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":true}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Un-Mute";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":false}, '*');}
button.innerHTML = "Un-Mute Speaker";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":false}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Toggle Mute";
button.innerHTML = "Toggle Speaker";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":"toggle"}, '*');}
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Mute Mic";
button.onclick = function(){iframe.contentWindow.postMessage({"mic":false}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Un-Mute Mic";
button.onclick = function(){iframe.contentWindow.postMessage({"mic":true}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Toggle Mic";
button.onclick = function(){iframe.contentWindow.postMessage({"mic":"toggle"}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Disconnect";
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');}
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Low Bitrate";
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":30}, '*');}
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":30}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "High Bitrate";
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":5000}, '*');}
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":5000}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Default Bitrate";
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":-1}, '*');}
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":-1}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Reload";
button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');}
button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "50% Volume";
button.onclick = function(){iframe.contentWindow.postMessage({"volume":0.5}, '*');}
button.onclick = function(){iframe.contentWindow.postMessage({"volume":0.5}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "100% Volume";
button.onclick = function(){iframe.contentWindow.postMessage({"volume":1.0}, '*');}
button.onclick = function(){iframe.contentWindow.postMessage({"volume":1.0}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Request Stats";
button.onclick = function(){iframe.contentWindow.postMessage({"getStats":true}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "Say Hello";
button.onclick = function(){iframe.contentWindow.postMessage({"sendChat":"Hello!"}, '*');};
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "previewWebcam()";
button.onclick = function(){iframe.contentWindow.postMessage({"function":"previewWebcam"}, '*');}; // publishScreen
iframeContainer.appendChild(button);
var button = document.createElement("button");
button.innerHTML = "CLOSE IFRAME";
button.onclick = function(){iframeContainer.parentNode.removeChild(iframeContainer);};
iframeContainer.appendChild(button);
//////////// LISTEN FOR EVENTS
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
/// If you have a routing system setup, you could have just one global listener for all iframes instead.
eventer(messageEvent, function (e) {
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
if ("stats" in e.data){
var outputWindow = document.createElement("outputWindow");
outputWindow.innerHTML = e.data.stats;
iframeContainer.appendChild(outputWindow);
}
if ("gotChat" in e.data){
var outputWindow = document.createElement("outputWindow");
outputWindow.innerHTML = e.data.gotChat.msg;
outputWindow.style.border="1px dotted black";
iframeContainer.appendChild(outputWindow);
}
});
}
</script>
@ -109,6 +200,8 @@ function loadIframe(){
<input placeholder="Enter an OBS.Ninja View URL here" id="viewlink" />
<button onclick="loadIframe();">ADD</button>
<input type="checkbox" id="clean" checked>Clean Output
<input type="checkbox" id="transparent" checked>Transparent
<input type="checkbox" id="hidemenu">Hide Menu
<div id="container">
</div>

View File

@ -1,5 +1,19 @@
<html>
<head>
<script type="text/javascript">
// MS Internet Explorer must not be given a chance to fail before I can give the user an error message.
try {
var msie = window.navigator.userAgent.indexOf("MSIE ");
if (msie>0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)){ // If MSIE or IE 11
alert("Internet Explorer is not supported.\n\nPlease consider using Google Chrome instead\n\nYou will be forwarded to the download page for Google Chrome now.");
console.error("INTERNET EXPLORER IS EVIL");
window.location = "https://www.google.com/chrome/";
}
} catch(e){
console.error(e);
}
</script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
<meta content="utf-8" http-equiv="encoding" />
@ -33,12 +47,12 @@
<meta property="twitter:image" content="./images/obsNinja_logo_full.png" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<!-- <script src="//console.re/connector.js" data-channel="obsninjaalpha" id="consolerescript"></script> -->
<!--<script src="//console.re/connector.js" data-channel="obsninjaalpha" id="consolerescript"></script>-->
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css">
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script type="text/javascript" src="./thirdparty/qrcode.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<link rel="stylesheet" href="./main.css?ver=3" />
<link rel="stylesheet" href="./main.css?ver=10" />
</head>
<body id="main" class="cat">
<span itemprop="image" itemscope itemtype="image/png">
@ -48,8 +62,8 @@
<span itemprop="thumbnail" itemscope itemtype="http://schema.org/ImageObject">
<link itemprop="url" href="./images/obsNinja_logo_full.png" />
</span>
<script language="javascript" type="text/javascript" src="./thirdparty/CodecsHandler.js?ver=8"></script>
<script language="javascript" type="text/javascript" src="./webrtc.js?ver=11"></script>
<script language="javascript" type="text/javascript" src="./thirdparty/CodecsHandler.js?ver=17"></script>
<script language="javascript" type="text/javascript" src="./webrtc.js?ver=33"></script>
<input id="zoomSlider" type="range" style="display: none;" />
<div id="header">
<a id="logoname" href="./" style="text-decoration: none; color: white; margin: 2px;">
@ -71,7 +85,7 @@
onclick="popupMessage(event);copyFunction(this)"
class="task"
onmousedown="copyFunction(this)"
style="font-weight: bold; color: #afa; cursor: grab; background-color: #0000; font-size: 115%; min-width: 300px; max-width: 800px;"
style="font-weight: bold; color: #afa; cursor: grab; background-color: #0000; font-size: 115%; min-width: 335px; max-width: 800px;"
/>
<i class="las la-paperclip task" style="color: #DDD;" onclick="popupMessage(event);copyFunction(document.getElementById('reshare'));" onmouseover="this.style.cursor='pointer'"></i>
</div>
@ -91,31 +105,38 @@
</div>
<div id="controlButtons">
<div id="chatbutton" title="Toggle the Chat" onclick="toggleChat()" class="advanced float" style="cursor: pointer;" alt="Toggle the Chat">
<i id="chattoggle" class="toggleSize las la-comment-alt my-float"></i>
<div id="chatNotification"></div>
</div>
<div id="mutebutton" title="Mute the Mic" onclick="toggleMute()" class="advanced float" style="cursor: pointer;" alt="Toggle the mic">
<i id="mutetoggle" class="toggleSize las la-microphone my-float"></i>
</div>
<div id="mutevideobutton" title="Disable the Camera" onclick="toggleVideoMute()" class="advanced float" style="cursor: pointer;" alt="Toggle the camera">
<i id="mutevideotoggle" class="toggleSize las la-eye my-float"></i>
</div>
<div
id="helpbutton"
title="Show Help Info"
onclick="alert('Email steve@seguin.email if the system breaks or check https://reddit.com/r/obsninja for support.\n\nThere are some advanced options hidden away, such as persistent stream links and custom resolutions; see the Wiki.')"
class="advanced float"
style="cursor: pointer;"
alt="How to Use This with OBS"
>
<i class="toggleSize las la-question-circle my-float"></i>
<div id="settingsbutton" title="Settings" onclick="toggleSettings(this)" class="advanced float" style="cursor: pointer;" alt="Toggle the Settings Menu">
<i id="settingstoggle" class="toggleSize las la-cog my-float"></i>
</div>
<div id="hangupbutton" title="Hangup the Call" onclick="hangup()" class="advanced float" style="cursor: pointer;" alt="Disconnect and End">
<i class="toggleSize my-float las la-phone rotate225" aria-hidden="true"></i>
</div>
</div>
<span
id="helpbutton"
title="Show Help Info"
onclick="alert('Email steve@seguin.email if the system breaks or check https://reddit.com/r/obsninja for support.\n\nThere are some advanced options hidden away, such as persistent stream links and custom resolutions; see the Wiki.')"
style="cursor: pointer; display:none;"
alt="How to Use This with OBS"
>
<i class="las la-question-circle " style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 24px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;"></i>
</span>
<span title="Language Options" onclick="toggle(document.getElementById('languages'));" id="translateButton">
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 10px; color: #d9e4eb; padding: 0; margin: 2px 2px 0 0; font-size: 140%;" class="las la-language" aria-hidden="true"></i>
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 2px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-language" aria-hidden="true"></i>
</span>
<div id="mainmenu" class="row" style="opacity: 0; align: center;">
<div id="container-1" class="column columnfade" style="background-color: #ddd; overflow-y: auto;">
<div id="container-1" class="column columnfade" style=" overflow-y: auto;">
<h2>
<span data-translate="add-group-chat">Add Group Chat to OBS</span>
</h2>
@ -148,8 +169,8 @@
<br />
<button onclick="toggle(document.getElementById('roomnotes'),this);">
<span data-translate="show-tips">Show me some tips..</span>
</button>
<ul style="padding: 10px; margin: auto auto; max-width: 500px; display: none; text-align: left;" id="roomnotes">
</button><br />
<ul style=" margin: auto auto; max-width: 500px; display: none; text-align: left;" id="roomnotes">
<br />
<span data-translate="added-notes">
<u>
@ -169,27 +190,27 @@
</div>
</div>
</div>
<div id="container-3" class="column columnfade" onclick="previewWebcam()" style="background-color: #ddd; overflow-y: auto;">
<div id="container-3" class="column columnfade" onclick="previewWebcam()" style=" overflow-y: auto;">
<h2 id="add_camera">
<span data-translate="add-your-camera">Add your Camera to OBS</span>
</h2>
<div class="container-inner">
<br />
<p>
<video id="previewWebcam" oncanplay="updateStats();" muted controls autoplay playsinline style="max-width: 640px; max-width: 83vw; max-height: 30vh;"></video>
<video id="previewWebcam" class="previewWebcam" oncanplay="updateStats();" disablePictureInPicture controlsList="nodownload" muted autoplay playsinline ></video>
</p>
<div id="infof"></div>
<button onclick="publishWebcam()" id="gowebcam" class="gowebcam" disabled>
<span data-translate="waiting-for-camera">Waiting for Camera to Load</span>
</button>
<br />
<span class="videoMenu">
<span id="videoMenu" class="videoMenu">
<i class="las la-video"></i><span data-translate="video-source"> Video Source </span>
<select id="videoSource" ></select>
<span id="gear_webcam" style="display: inline-block;" onclick="toggle(document.getElementById('videoSettings'));">
&nbsp;&nbsp;
<i class="las la-cog" style="font-size: 170%; vertical-align: middle;" aria-hidden="true"></i>
<i class="las la-cog" style="font-size: 140%; vertical-align: middle;" aria-hidden="true"></i>
</span>
</span>
<br />
@ -213,17 +234,16 @@
<div id="webcamstats" style="padding: 5px 0 0 0;"></div>
</form>
</span>
<br />
</center>
<div class="form-group multiselect">
<a class="form-control multiselect-trigger" tabindex="3">
<div id="audioMenu" class="form-group multiselect" alt="tip: Hold CTRL (command) to select Multiple" title="tip: Hold CTRL (command) to select Multiple">
<a id="multiselect-trigger" class="form-control multiselect-trigger" tabindex="3">
<div id="audioTitle" class="title">
<i class="las la-microphone-alt"></i><span data-translate="select-audio-source"> Audio Source(s) </span>
<i class="chevron bottom" aria-hidden="true"></i>
<i id='chevarrow1' class="chevron bottom" aria-hidden="true"></i>
<div class="meter" id="meter1"></div>
</div>
</a>
<ul id="audioSource" class="multiselect-contents">
<ul id="audioSource" class="multiselect-contents" >
<li>
<input type="checkbox" id="multiselect1" name="multiselect1" style="display: none;" checked value="ZZZ" />
<label for="multiselect1">
@ -236,7 +256,7 @@
<span id="headphonesDiv" style="text-align:left; margin:17px 0; max-width: 550px; min-width: 420px; background-color: #f3f3f3; display: none; padding: 10px 10px; border: 1px solid #ccc; vertical-align: middle;">
<div id="audioTitle2" class="title">
<i class="las la-headphones"></i><span data-translate="select-output-source"> Audio Output Destination:</span></div>
<select id="outputSource" style="background-color: #FFF; padding:5px; display: display:inline-block;vertical-align: middle;"></select>
<select id="outputSource" ></select>
</span>
@ -250,7 +270,7 @@
</div>
</div>
<div id="container-2" class="column columnfade" style="background-color: #ddd; overflow-y: auto;">
<div id="container-2" class="column columnfade" style=" overflow-y: auto;">
<h2 id="add_screen">
<span data-translate="remote-screenshare-obs">Remote Screenshare into OBS</span>
</h2>
@ -290,10 +310,10 @@
</span>
<br />
</center>
<p>
<p id="audioScreenShare1">
<span data-translate="audio-sources">Audio Sources</span>
<br />
<select id="audioSourceScreenshare" multiple style="height: 60px; width: 200px; resize: both; overflow: auto; padding: 5px;" onchange="requestAudioStream();">
<select id="audioSourceScreenshare" multiple alt="tip: Hold CTRL (command) to select Multiple" title="tip: Hold CTRL (command) to select Multiple" style="height: 60px; width: 200px; resize: both; overflow: auto; padding: 5px;" onchange="requestAudioStream();">
<option value="screenshare" selected>
<span data-translate="screen-shrae-audio">Screen Share Audio (default)</span>
</option>
@ -320,7 +340,7 @@
</div>
</div>
</div>
<div id="container-4" class="column columnfade" style="background-color: #ddd; overflow-y: auto;">
<div id="container-4" class="column columnfade" style=" overflow-y: auto;">
<h2>
<span data-translate="create-reusable-invite">Create Reusable Invite</span>
</h2>
@ -450,13 +470,13 @@
</li>
<li>Some users will have
<a href="https://github.com/steveseguin/obsninja/wiki/FAQ#video-is-pixelated">"pixelation" problems</a> with videos. Adding
<b>&codec=vp9</b> to the OBS links will often correct it.
<a href="https://github.com/steveseguin/obsninja/wiki/FAQ#video-is-pixelated">"pixel smearing"</a> problems with videos. Avoid Wi-Fi to reduce it or add
<b>&codec=vp9</b> to the OBS view links to prevent it.
</li>
<br />
Site last updated: July 20th, 2020. The previous version can be found at
<a href="https://obs.ninja/v8/">https://obs.ninja/v8/</a> if you are having new issues.
Site last updated: <a href="https://www.reddit.com/r/OBSNinja/comments/ib7vhk/version_10_released_text_chat_and_more_added_see/">August 17th, 2020</a>. The previous version can be found at
<a href="https://obs.ninja/v9/">https://obs.ninja/v9/</a> if you are having new issues.
<br />
@ -464,9 +484,8 @@
<h3>
<i>
Check out the
<a href="https://www.reddit.com/r/OBSNinja/">sub-reddit</a>
<i class="lab la-reddit-alien"></i> for help and advanced info. I'm also on
<a href="https://www.reddit.com/r/OBSNinja/">sub-reddit
<i class="lab la-reddit-alien"></i> </a>for help and see the <a href="https://github.com/steveseguin/obsninja/wiki/">Wiki for advanced info</a>. I'm also on
<a href="https://discord.gg/EksyhGA">Discord</a> and you can email me at steve@seguin.email
</i>
@ -489,9 +508,6 @@
<a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a>
</div>
</div>
<div id="gridlayout"></div>
<div id="controls_blank" style="display: none;">
<center>
@ -500,13 +516,13 @@
<span data-translate="remote-control-for-obs">Remote Control for OBS</span>
</b>
<br />
<button data-value="0" style="font-size: 112%;" onclick="directEnable(this);">
<button data-value="0" style="font-size: 112%;" onclick="directEnable(this, event);">
<span data-translate="add-to-group">Add to Group Scene</span>
</button>
<button style="font-size: 112%;" onclick="directMute(this);">
<button style="font-size: 112%;" onclick="directMute(this, event);">
<span data-translate="mute">Mute</span>
</button>
<button style="font-size: 112%;" onclick="recordVideo(this)">
<button style="font-size: 112%;" onclick="recordVideo(this, event)">
<span data-translate="record">Record</span>
</button>
<br />
@ -517,6 +533,40 @@
<hr />
</center>
</div>
<div id="popupSelector" style="display:none;">
<span id="videoMenu3" class="videoMenu">
<i class="las la-video"></i><span data-translate="video-source"> Video Source </span>
<select id="videoSource3" ></select>
</span>
<br />
<br />
<div id="audioMenu3" class="form-group multiselect" alt="tip: Hold CTRL (command) to select Multiple" title="tip: Hold CTRL (command) to select Multiple" style="padding: 10px; background-color:#f3f3f3;">
<a id="multiselect-trigger3" class="form-control multiselect-trigger" tabindex="3">
<div id="audioTitle2" class="title">
<i class="las la-microphone-alt"></i><span data-translate="select-audio-source"> Audio Source(s) </span>
<i id="chevarrow2" class="chevron bottom" aria-hidden="true"></i>
</div>
</a>
<ul id="audioSource3" style="background-color:white;" class="multiselect-contents">
<li>
</li>
</ul>
</div>
<br />
<span id="headphonesDiv3" style="display: inline-block;">
<div id="audioTitle3" class="title">
<i class="las la-headphones"></i><span data-translate="select-output-source"> Audio Output Destination:</span>
</div>
<select id="outputSource3" ></select>
</span>
<br />
<button id="shareScreenGear" style="padding:20px;" onclick="grabScreen()"><b>Share Screen</b><br /><i style="padding:5px; font-size:300%;" class="las la-desktop"></i></button><br />
<button onclick="toggleSettings()" style="background-color:#EFEFEF;padding:10px 12px 12px 2px;"><i class="chevron right" style="font-size:150%;top:3px;position:relative;"></i> <b>Close Settings</b></button>
</p>
</div>
<nav id="context-menu" class="context-menu">
<ul class="context-menu__items">
<li class="context-menu__item">
@ -533,6 +583,21 @@
</li>
</ul>
</nav>
<div id="chatModule" style="display:none;">
<div id="chatBody">
<div class="inMessage">
Welcome to OBS.Ninja! You can send text messages directly to connected peers from here.
</div>
<div class="outMessage">
Names identifying connected peers will be a feature in an upcoming release.
</div>
</div>
<input id="chatInput" placeholder="Enter chat message to send here"onkeypress="EnterButtonChat(event)" />
<button style="width:60px;background-color:#EEE;" onclick="sendChatMessage()">Send</button>
</div>
<div id="messagePopup" class="popup-message"></div>
<div id="languages" class="popup-message" style="display: none; right: 0; bottom: 25px; position: absolute;">
<b>Available Languages:</b>
@ -560,6 +625,7 @@
<br />
</div>
<script>
var session = WebRTC.Media; // session is a required global variable if configuring manually. Run before loading main.js but after webrtc.js.
session.streamID = session.generateStreamID(); // randomly generates a streamID for this session. You can set your own programmatically if needed
@ -618,7 +684,7 @@
// If you wish to change branding, blank offers a good clean start.
<script type="text/javascript" id="main-js" src="./main.js" data-translation="blank"></script>
-->
<script type="text/javascript" id="main-js" src="./main.js?ver=11"></script>
<script type="text/javascript" src="./animations.js?ver=1"></script>
<script type="text/javascript" id="main-js" src="./main.js?ver=33"></script>
<script type="text/javascript" src="./animations.js?ver=8"></script>
</body>
</html>

366
main.css
View File

@ -10,7 +10,7 @@
.meter {
display: inline-block;
width: 100px;
width: 0px;
height: 10px;
background: green;
transition: all 52ms linear;
@ -69,17 +69,18 @@ button {
}
.credits {
color:black;
color:#101020;
position:fixed;
bottom:0;
right:0;
z-index:-1;
font-size:80%;
}
.credits >a {
color:black;
color:#101020;
}
.credits >a:visited{
color:black;
color:#101020;
}
.chevron{
@ -100,11 +101,15 @@ button {
width: 0.32em;
}
.chevron.bottom:before {
.chevron.bottom::before {
top: .28em;
transform: rotate(135deg);
}
.chevron.right::before {
top: .28em;
transform: rotate(45deg);
}
.pressed {
background: #e3e3e3;
@ -123,11 +128,7 @@ hr {
height:2px;border-width:0;color:gray;background-color:gray;
}
#videosource {
max-width:100%;
max-height:100%;
background-color:white;
}
/* Clear floats after the columns */
.row:after {
content: "";
@ -186,6 +187,7 @@ hr {
min-width: 300px;
padding:10px 10px 0px 10px !important;
}
.directorsgrid .vidcon {
display: inline-block !important;
max-width: 400px !important;
@ -193,6 +195,81 @@ hr {
background: #E3E4EF;
}
.puslate {
border-radius: 50%;
box-shadow: 0 0 0 0 rgba(14, 19, 26, 1);
transform: scale(1);
animation: pulse 2s infinite;
}
.notification {
position: relative;
top: -40px;
right: -33px;
padding: 2px 0;
border-radius: 50%;
background: red;
color: white;
width: 11px;
height: 11px;
margin: 0;
}
video::-webkit-media-controls-current-time-display{
display:none;
}
video::-webkit-media-controls-time-remaining-display{
display:none;
}
video::-webkit-media-controls-timeline{
display:none;
}
video::-webkit-media-controls-timeline-container{
display:none;
}
video::-webkit-media-controls-toggle-closed-captions-button{
display:none;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(14, 19, 26, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 10px rgba(2, 3, 4, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(14, 19, 26, 0);
}
}
.icn-spinner {
/* animation: spin-animation 3s infinite; */
display: inline-block;
}
@keyframes spin-animation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
html {
border:0;
@ -202,7 +279,7 @@ html {
li {
margin: 0.1em 0;
padding-left: 0.1em;
line-height: 1.4em;
line-height: 1.3em;
}
body {
@ -227,6 +304,11 @@ body {
}
.previewWebcam{
max-width: 640px;
max-width: 83vw;
max-height: 30vh;
}
.gowebcam {
font-size:110%;
@ -237,6 +319,10 @@ body {
padding:10px 50px;
}
.mainmenuclass{
display:inherit;
}
.gobutton {
font-size:110%;
padding:10px;
@ -299,11 +385,17 @@ body {
top:0px;
right:0px;
}
}
@media only screen and (max-width: 650px) {
.mainmenuclass{
display:inline-block;
}
.outer {
width:50px;
}
@ -354,6 +446,11 @@ body {
min-width: 100% !important;
}
#headphonesDiv3 {
max-width: 100% !important;
min-width: 100% !important;
overflow: hidden !important;
}
#headphonesDiv {
max-width: 100% !important;
min-width: 100% !important;
@ -364,6 +461,10 @@ body {
width: 100% !important;
}
#outputSource3 {
width: 100% !important;
}
#audioSourceScreenshare {
max-width: 90% !important;
min-width: 90% !important;
@ -376,11 +477,32 @@ body {
overflow: hidden !important;
}
#popupSelector{
padding: 20px 5px 0px 15px !important;
font-size:92%;
width: 385px !important
}
}
#popupSelector {
background: linear-gradient(6deg, rgba(221, 221, 221, 0) 4%, rgb(221, 221, 221) 30%, rgba(120,120,100,.5) 100%);
transition: all 0.2s linear 0s;
padding: 20px 20px 0px 20px;
position: fixed;
top: 0px;
height: 90%;
width: 490px;
right:-400px;
}
h2 {
color: white;
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+/Edge */
user-select: none; /* Standard */
}
@ -467,12 +589,19 @@ body {
font-size:100%;
/* Add shadows to create the "card" effect */
box-shadow: 0 4px 8px 0 rgba(0,0,0,.1);
background-color: #ddd;
transition: box-shadow 0.1s ease-in-out;
}
/* On mouse-over, add a deeper shadow */
.column:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,.3);
}
.column:active{
box-shadow: 0 8px 16px 0 rgba(0,0,0,.5);
}
.column > h2 {color:black;}
@ -524,8 +653,15 @@ img {
#container-3{
background-repeat: no-repeat;
background-size: 80px;
transition: background-image 0.3s ease-in-out;
-webkit-transition: background-image 0.3s ease-in-out;
background-position: 50% 65%;
background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTk2LjYsMjYuOGgtODYuMWMtMi4yLDAtNC4xLDEuOC00LjEsNC4xdjY3LjJjMCwyLjIgMS44LDQuMSA0LjEsNC4xaDg2LjFjMi4yLDAgNC4xLTEuOCA0LjEtNC4xdi0xOS40bDE0LjksMTQuOWMwLjgsMC44IDEuOCwxLjIgMi45LDEuMiAwLjUsMCAxLjEtMC4xIDEuNi0wLjMgMS41LTAuNiAyLjUtMi4xIDIuNS0zLjh2LTUyLjVjMC0xLjYtMS0zLjEtMi41LTMuOC0xLjUtMC42LTMuMy0wLjMtNC40LDAuOWwtMTQuOSwxNC45di0xOS4zYy0wLjEtMi4zLTEuOS00LjEtNC4yLTQuMXptLTQuMSwzMy4zdjguOCAyNS4yaC03OHYtNTkuMmg3OHYyNS4yem0yMS45LTEydjMyLjlsLTEzLjctMTMuN3YtNS40bDEzLjctMTMuOHoiIGZpbGw9IiMwMDAwMDAiLz4KICA8L2c+Cjwvc3ZnPgo=)
}
#container-4 {
@ -545,9 +681,12 @@ img {
.container-inner {
display: none;
background-color: rgb(221, 221, 221);
padding:0 0 80px 0;
max-height: 100%;
min-height: 90%;
}
#add_screen{
padding-bottom:20px;
}
.float{
opacity: 0.8;
width:45px;
@ -557,6 +696,7 @@ img {
border-radius:38px;
text-align:center;
margin:5px;
pointer-events: auto;
}
.float2{
@ -569,6 +709,7 @@ img {
text-align:center;
z-index:10;
margin:5px;
pointer-events: auto;
}
.rotate225 {
@ -605,6 +746,7 @@ img {
align-items: center;
height: 60px;
border: 0;
pointer-events: none;
}
@ -638,6 +780,7 @@ img {
border-radius:38px;
text-align:center;
margin:5px;
pointer-events: auto;
}
.float2{
@ -650,6 +793,7 @@ img {
text-align:center;
z-index:10;
margin:5px;
pointer-events: auto;
}
}
@ -767,7 +911,13 @@ video {
background-image:url("data:image/svg+xml,%3Csvg viewBox='-42 0 512 512.002' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m210.351562 246.632812c33.882813 0 63.222657-12.152343 87.195313-36.128906 23.972656-23.972656 36.125-53.304687 36.125-87.191406 0-33.875-12.152344-63.210938-36.128906-87.191406-23.976563-23.96875-53.3125-36.121094-87.191407-36.121094-33.886718 0-63.21875 12.152344-87.191406 36.125s-36.128906 53.308594-36.128906 87.1875c0 33.886719 12.15625 63.222656 36.132812 87.195312 23.976563 23.96875 53.3125 36.125 87.1875 36.125zm0 0'/%3E%3Cpath d='m426.128906 393.703125c-.691406-9.976563-2.089844-20.859375-4.148437-32.351563-2.078125-11.578124-4.753907-22.523437-7.957031-32.527343-3.308594-10.339844-7.808594-20.550781-13.371094-30.335938-5.773438-10.15625-12.554688-19-20.164063-26.277343-7.957031-7.613282-17.699219-13.734376-28.964843-18.199219-11.226563-4.441407-23.667969-6.691407-36.976563-6.691407-5.226563 0-10.28125 2.144532-20.042969 8.5-6.007812 3.917969-13.035156 8.449219-20.878906 13.460938-6.707031 4.273438-15.792969 8.277344-27.015625 11.902344-10.949219 3.542968-22.066406 5.339844-33.039063 5.339844-10.972656 0-22.085937-1.796876-33.046874-5.339844-11.210938-3.621094-20.296876-7.625-26.996094-11.898438-7.769532-4.964844-14.800782-9.496094-20.898438-13.46875-9.75-6.355468-14.808594-8.5-20.035156-8.5-13.3125 0-25.75 2.253906-36.972656 6.699219-11.257813 4.457031-21.003906 10.578125-28.96875 18.199219-7.605469 7.28125-14.390625 16.121094-20.15625 26.273437-5.558594 9.785157-10.058594 19.992188-13.371094 30.339844-3.199219 10.003906-5.875 20.945313-7.953125 32.523437-2.058594 11.476563-3.457031 22.363282-4.148437 32.363282-.679688 9.796875-1.023438 19.964844-1.023438 30.234375 0 26.726562 8.496094 48.363281 25.25 64.320312 16.546875 15.746094 38.441406 23.734375 65.066406 23.734375h246.53125c26.625 0 48.511719-7.984375 65.0625-23.734375 16.757813-15.945312 25.253906-37.585937 25.253906-64.324219-.003906-10.316406-.351562-20.492187-1.035156-30.242187zm0 0'/%3E%3C/svg%3E");
}
/* context menu */
.mirrorControl::-webkit-media-controls-enclosure {
padding: 0px;
height: 30px;
transform: scaleX(-1);
-webkit-transform: scaleX(-1);
}
.context-menu {
display: none;
@ -828,7 +978,7 @@ video {
#audioTitle{
text-align:left;
padding: 7px 10px;
padding: 7px 0px;
}
#audioTitle2{
@ -851,59 +1001,131 @@ video {
border-bottom-right-radius: 4px;
}
#headphonesDiv3{
text-align:left;
margin:17px 0;
width: 450px;
background-color: #f3f3f3;
padding: 10px 10px;
border: 1px solid #ccc;
vertical-align: middle;
}
#headphonesDiv{
text-align:left;
margin:17px 0;
width: 450px;
background-color: #f3f3f3;
padding: 10px 10px;
border: 1px solid #ccc;
vertical-align: middle;
}
#videoSettings {
margin: auto auto;
background-color: #f3f3f3;
width: 420px;
width: 450px;
padding: 10px 0;
margin: 0 0 5px 0;
margin: 0px 0 0px 0;
border: 1px solid #ccc;
}
#audioMenu {
margin:15px 0 0 0 ;
}
#videoSource {
background-color: #FFF;
display: display:inline-block;
display: inline-block;
vertical-align: middle;
max-width:260px;
max-height:100%;
background-color:white;
padding: 3px;
font-size:93%;
}
#videoSettings3 {
margin: auto auto;
background-color: #f3f3f3;
width: 450px;
padding: 10px 0;
margin: 0 0 5px 0;
border: 1px solid #ccc;
padding: 3px;
font-size: 90%;
}
#videoSource3 {
background-color: #FFF;
display: inline-block;
vertical-align: middle;
padding: 3px;
font-size:93%;
}
#outputSource {
background-color: #FFF;
display: inline-block;
vertical-align: middle;
padding: 4px;
font-size:93%;
max-width: 100%;
}
#outputSource3 {
background-color: #FFF;
display: inline-block;
vertical-align: middle;
padding: 3px;
font-size:93%;
max-width: 100%;
}
.videoMenu{
background-color: #f3f3f3;
width: 420px;
width: 450px;
display: inline-block;
padding: 5px 10px;
padding: 10px 10px;
border: 1px solid #ccc;
vertical-align: middle;
text-align:left;
}
div.multiselect {
background-color:#FFF;
width: 420px;
width: 450px;
white-space: nowrap;
overflow:hidden;
margin:auto auto;
border: 1px solid #ccc;
border-bottom:0;
display: inline-block;
padding: 4px 10px 10px 10px;
background-color:#f3f3f3;
}
.multiselect .multiselect-contents {
display: block;
margin: 0;
font-size:80%;
padding: 5px 5px 5px;
padding: 3px 5px 1px;
border-top: 0;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
text-align:left;
background-color:#f3f3f3;
background-color: white;
}
.multiselect .multiselect-contents li {
list-style: none;
font-size:130%;
font-size:120%;
padding:2px;
overflow:hidden;
}
.select .select-trigger:hover {
cursor: pointer;
@ -955,13 +1177,13 @@ label {
input[type=checkbox]
{
/* Double-sized Checkboxes */
-ms-transform: scale(1.3); /* IE */
-moz-transform: scale(1.3); /* FF */
-webkit-transform: scale(1.3); /* Safari and Chrome */
-o-transform: scale(1.3); /* Opera */
transform: scale(1.3);
-ms-transform: scale(1.4); /* IE */
-moz-transform: scale(1.4); /* FF */
-webkit-transform: scale(1.4); /* Safari and Chrome */
-o-transform: scale(1.4); /* Opera */
transform: scale(1.4);
padding: 5px;
margin: 0 5px;
margin: 0 5px 0 1px;
}
#screenshare {
@ -978,4 +1200,80 @@ input[type=checkbox]
border-image-width:0;
background-size: contain;
background-color: rgba(0,0,0,0);
}
}
.inMessage{
color: #000;
margin:3px;
border-radius: 5px;
background: #FFF8;
padding: 5px;
text-align:left;
margin: 10px 3px;
}
.outMessage{
color: #000;
margin:3px;
border-radius: 5px;
background: #FFF7;
padding: 5px;
text-align:right;
margin: 10px 3px;
}
#chatBody{
z-index: 12;
background-color: #FFF1;
width: 100%;
border-radius: 5px;
padding: 1px 7px;
}
#chatModule{
bottom:50px;
position:fixed;
margin:10px;
align-self: center;
width:400px;
max-width:100%;
}
#chatInput{
color: #000;
background-color:#FFFE;
max-width:700px;
min-width:320px;
font-size:105%;
margin-left:7px;
padding:3px;
}
@media only screen and (max-width: 390px) {
#chatBody{
z-index: 12;
background-color: #FFF1;
width: 100%;
border-radius: 5px;
padding: 1px 7px;
margin:0px;
}
#chatModule{
bottom:50px;
position:fixed;
margin:0px;
align-self: center;
width:400px;
max-width:100%;
}
#chatInput{
max-width:99%;
min-width: 240px;
margin-left: 11px;
font-size: 100%;
}
}

2089
main.js

File diff suppressed because it is too large Load Diff

View File

@ -248,12 +248,13 @@ var CodecsHandler = (function() {
var sendPayloadType = videoMLine.split(pattern)[1].split(' ')[0];
var fmtpLine = sdpLines[findLine(sdpLines, 'a=rtpmap', sendPayloadType)];
var codecName = fmtpLine.split('a=rtpmap:' + sendPayloadType)[1].split('/')[0];
codec = codecName || codec; // Try to find first Codec; else use expected/default
params = params || {};
var xgoogle_min_bitrate = params.min.toString();
var xgoogle_max_bitrate = params.max.toString();
var min_bitrate = params.min.toString() || '30';
var max_bitrate = params.max.toString() || '2500';
var codecIndex = findLine(sdpLines, 'a=rtpmap', codec+'/90000');
var codecPayload;
@ -272,17 +273,21 @@ var CodecsHandler = (function() {
}
if (!rtxIndex) {
sdpLines[mLineIndex] += '\r\nb=AS:' + max_bitrate;
sdp = sdpLines.join('\r\n');
return sdp;
}
}
var rtxFmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + rtxPayload.toString());
if (rtxFmtpLineIndex !== null) {
var rtxFmtpLineIndexChromium = findLine(sdpLines, 'a=fmtp:' + rtxPayload.toString());
if (rtxFmtpLineIndexChromium !== null){
var appendrtxNext = '\r\n';
appendrtxNext += 'a=fmtp:' + codecPayload + ' x-google-min-bitrate=' + (xgoogle_min_bitrate || '2500') + '; x-google-max-bitrate=' + (xgoogle_max_bitrate || '2500');
sdpLines[rtxFmtpLineIndex] = sdpLines[rtxFmtpLineIndex].concat(appendrtxNext);
appendrtxNext += 'a=fmtp:' + codecPayload + ' x-google-min-bitrate=' + min_bitrate + '; x-google-max-bitrate=' + max_bitrate;
sdpLines[rtxFmtpLineIndexChromium] = sdpLines[rtxFmtpLineIndexChromium].concat(appendrtxNext);
sdp = sdpLines.join('\r\n');
}
return sdp;
}

File diff suppressed because one or more lines are too long