v23.5 updates

This commit is contained in:
steveseguin 2023-06-14 17:19:29 -04:00
parent 49c7590123
commit ed1716c23c
8 changed files with 1434 additions and 248 deletions

167
fileshare.html Normal file
View File

@ -0,0 +1,167 @@
<!DOCTYPE html>
<html>
<head>
<title>WebRTC File Sharing</title>
<style>
body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
background-color: #f7f7f7;
}
/* Container Styles */
.container {
margin: 0 auto;
max-width: 600px;
padding: 20px;
background-color: #ffffff;
border-radius: 5px;
box-shadow: 0px 0px 5px rgba(0,0,0,0.1);
}
/* Header Styles */
h1 {
margin: 0;
text-align: center;
font-weight: normal;
font-size: 36px;
color: #333333;
margin-bottom: 20px;
}
/* File Selector Styles */
#file-selector {
display: flex;
flex-direction: column;
align-items: center;
margin: 20px;
}
#file-selector label {
font-size: 20px;
margin-bottom: 10px;
}
#file-selector input[type="file"] {
display: none;
}
#file-selector button {
font-size: 16px;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
#file-selector button:hover {
background-color: #3e8e41;
}
/* Progress Container Styles */
#progress-container {
display: none;
flex-direction: column;
align-items: center;
margin: 20px;
}
#progress-bar {
width: 100%;
height: 30px;
background-color: #f1f1f1;
border-radius: 5px;
overflow: hidden;
margin-bottom: 10px;
}
#progress-bar-inner {
height: 100%;
background-color: #4CAF50;
text-align: center;
line-height: 30px;
color: white;
transition: width 0.3s ease;
}
#status {
font-size: 16px;
margin-bottom: 10px;
}
#connections {
font-size: 14px;
color: #999999;
}
/* Input Styles */
input[type="file"] {
padding: 10px;
border-radius: 5px;
border: 1px solid #dddddd;
margin-bottom: 10px;
}
/* Button Styles */
button {
font-size: 16px;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #3e8e41;
}
</style>
</head>
<body>
<h1>WebRTC File Sharing</h1>
<div id="file-selector">
<label for="file-input">Select a file:</label>
<input type="file" id="file-input" />
<button id="share-button">Share</button>
</div>
<div id="progress-container" style="display:none">
<div id="progress-bar">
<div id="progress-bar-inner"></div>
</div>
<div id="status">Connecting...</div>
<div id="connections">0 connections</div>
</div>
<script>
var fileInput = document.getElementById("file-input");
var shareButton = document.getElementById("share-button");
var progressContainer = document.getElementById("progress-container");
var progressBarInner = document.getElementById("progress-bar-inner");
var status = document.getElementById("status");
var connections = document.getElementById("connections");
var connectionCount = 0;
shareButton.addEventListener("click", function() {
if (fileInput.files.length > 0) {
// Display progress bar and status message
progressContainer.style.display = "block";
status.innerText = "Connecting...";
// TODO: Use WebRTC to share the file with other users
// Update progress bar and status messages
progressBarInner.style.width = "100%";
status.innerText = "File shared successfully.";
}
});
// TODO: Use WebRTC to display the number of connections, progress, and speed
</script>
</body>
</html>

835
lib.js

File diff suppressed because it is too large Load Diff

117
main.css
View File

@ -1165,9 +1165,7 @@ hr {
margin: 0;
}
.queueNotification {
position: relative;
top: -40px;
right: -33px;
padding: 2px 0;
border-radius: 50%;
background: #335c3a;
@ -1284,6 +1282,22 @@ button#press2talk{
position: relative;
}
button.btnArmTransferRoom{
width:auto;
margin-left: 2px;
height:38px;
border-radius: 15px;
}
button.btnArmTransferRoom i{
margin-right:3px;
}
button.btnArmTransferRoom:hover{
background-color: var(--green-accent)!important;
}
button.btnArmTransferRoom.selected{
background-color: #840000!important;
}
#container.vidcon {
height:100%;
@ -1354,22 +1368,6 @@ button#press2talk{
100% { transform: translate(1px, -2px) rotate(-1deg); }
}
button.btnArmTransferRoom{
width:auto;
margin-left: 2px;
height:38px;
border-radius: 15px;
}
button.btnArmTransferRoom i{
margin-right:3px;
}
button.btnArmTransferRoom:hover{
background-color: var(--green-accent);
}
button.btnArmTransferRoom.selected{
background-color: #840000;
}
@media only screen and (max-height: 540px){
#gridlayout>#container.vidcon {
@ -1602,7 +1600,7 @@ body.darktheme{
.gowebcam:enabled {
background-color: #26e726 !important;
background: radial-gradient(#26e726, #2EeF2E);
color: black;
color: black!important;
font-weight: bold !important;
box-shadow: 0 0 31px 0px #244e1c44;
animation: pulsate 2s ease-out infinite;
@ -1725,7 +1723,7 @@ input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 1px #000,0 0 1px #0d0d0d;
border: 1px solid #000;
height: 24px;
width: 14px;
width: 24px;
border-radius: 3px;
cursor: pointer;
-webkit-appearance: none;
@ -1737,7 +1735,7 @@ input[type=range]::-moz-range-thumb {
box-shadow: 1px 1px 1px #000,0 0 1px #0d0d0d;
border: 1px solid #000;
height: 24px;
width: 14px;
width: 24px;
border-radius: 3px;
cursor: pointer;
background-color: var(--lighttheme-2);
@ -1747,7 +1745,7 @@ input[type=range]::-ms-thumb {
box-shadow: 1px 1px 1px #000,0 0 1px #0d0d0d;
border: 1px solid #000;
height: 24px;
width: 14px;
width: 24px;
border-radius: 3px;
cursor: pointer;
background-color: var(--lighttheme-2);
@ -1848,7 +1846,7 @@ div#chatBody a {
display: flex;
flex-wrap: wrap;
width: 100%;
max-width: min(500px, 100vh);
max-width: min(500px, 100vw);
z-index: 3;
margin-bottom: 65px;
gap: 0px 5px;
@ -1857,11 +1855,11 @@ div#chatBody a {
#chatInput {
color: #000;
background-color: #FFFE;
width: 70%;
width: calc(100% - 160px);
padding: 3px;
}
.chatBarInputButton {
width: calc(30% - 5px);
width: 50px;
margin: unset;
}
@ -3426,10 +3424,12 @@ div#roomnotes2 {
}
.directorBlue{
background-color: #5c7785 !important;
display: var(--show-codirectors) !important;
}
.directorBox{
background-color: #606383 !important;
display: var(--show-codirectors) !important;
}
/* ---- DIRECTORS PAGE - Guest Controls Box ---- */
.controlsGrid {
@ -3946,6 +3946,7 @@ a#reshare {
border-radius: 2vh;
pointer-events:none;
border: 1px black solid;
z-Index: 2;
}
.video-meter-2 {
@ -3962,6 +3963,7 @@ a#reshare {
border-radius: 5px;
pointer-events:none;
border: 5px green solid;
z-Index: 2;
}
.video-meter-director {
@ -3984,6 +3986,7 @@ a#reshare {
pointer-events:none;
border: 1px black solid;
transition: height 0.1s ease, background-color 0.1s ease;
z-Index: 2;
}
@ -4028,6 +4031,7 @@ a#reshare {
border-radius: 2vh;
background-color:#b11313;
padding: 2px 2px 2px 1px;
z-index: 2;
}
.video-mute-state-userlist {
@ -4300,6 +4304,23 @@ input:checked + .slider:before {
overflow: hidden;
overflow-wrap: break-word;
}
#publishSettings{
position: absolute;
background-color: #ddddddee;
box-shadow: 0 0 30px 10px #0000005c;
color: black;
font-size: 1.0em;
bottom: calc(50% - 130px);
left: 50%;
transform: translate(-50%, 0%);
border-radius: 10px;
font-weight: bold;
z-index:31;
width:550px;
max-width:100%;
overflow: hidden;
overflow-wrap: break-word;
}
.largeTextEntry {
width: 90%;
margin: 10px 5%;
@ -4953,12 +4974,12 @@ button:hover {
button i {
font-size: 130%;
}
.darktheme button {
.darktheme :not(.promptModalInner) > button {
background-color: var(--discord-grey-5);
border: 1px solid var(--discord-grey-8);
color: var(--discord-text);
}
.darktheme button:hover {
.darktheme :not(.promptModalInner) > button:hover {
filter: brightness(1.05);
}
@ -5080,13 +5101,13 @@ input[type='checkbox'], input[type='radio'] {
}
.darktheme input {
.darktheme :not(.promptModalInner) > input {
border: 1px solid var(--discord-grey-8);
color: var(--near-black);
border-radius: 4px;
}
.darktheme input::placeholder {
.darktheme :not(.promptModalInner) > input::placeholder {
color: var(--discord-grey-8) !important;
}
@ -5105,7 +5126,6 @@ input[type='checkbox'], input[type='radio'] {
.container-inner {
display: none;
background-color: var(--lighttheme-3);
max-height: 100%;
min-height: calc(100% - 100px);
margin-bottom:30px;
}
@ -5224,41 +5244,6 @@ input[type='checkbox'], input[type='radio'] {
cursor: not-allowed;
}
/* Buttons to disable due to them being a director */
.directorBoxColor button[data-action-type="hangup"],
.directorBoxColor button[data-action-type="toggle-remote-speaker"],
.directorBoxColor button[data-action-type="toggle-remote-display"],
.directorBoxColor button[data-action-type="mute-video-guest"],
.directorBoxColor button[data-action-type="advanced-camera-settings"],
.directorBoxColor button[data-action-type="advanced-audio-settings"],
.directorBoxColor button[data-action-type="order-down"],
.directorBoxColor button[data-action-type="order-up"],
.directorBoxColor button[data-action-type="toggle-group"],
.directorBoxColor button[data-action-type="mute-guest"],
.directorBoxColor .tooltip {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
.directorBoxColor {
border: 2px solid var(--director-box);
box-shadow: 0px 0px 15px var(--director-box);
display: var(--show-codirectors) !important;
}
.darktheme .codirectorBoxColor {
border: 2px solid var(--codirector-dark-box);
box-shadow: 0px 0px 15px var(--codirector-dark-box);
display: var(--show-codirectors) !important;
}
.codirectorBoxColor {
border: 2px solid var(--codirector-box);
box-shadow: 0px 0px 15px var(--codirector-box);
display: var(--show-codirectors) !important;
}
.darktheme .invite_setting_group {
color: var(--discord-text);
}

166
main.js
View File

@ -293,17 +293,28 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (urlParams.has('whippush') || urlParams.has('whipout') || urlParams.has('pushwhip')) { // URL or data:base64 image. Becomes local to this viewer only. This is like &avatar, but slightly different. Just CSS in this case
let whippush = urlParams.get('whippush') || urlParams.get('whipout') || urlParams.get('pushwhip');
if (whippush){
session.whipOutput = urlParams.get('whippush') || urlParams.get('whipout') || urlParams.get('pushwhip') || null;
if (session.whipOutput){
try {
session.whipOutput = decodeURIComponent(whippush);
if (session.whipOutput == 'twitch'){
session.whipOutput = "https://g.webrtc.live-video.net:4443/v2/offer";
query("#publishOutToken input[type='password']").placeholder = "Twitch stream token here";
} else {
session.whipOutput = decodeURIComponent(session.whipOutput);
}
} catch(e){
errorlog(e);
}
} else {
getById("publishOutURL").classList.remove("hidden");
}
}
if (urlParams.has('whippushtoken') || urlParams.has('whipouttoken') || urlParams.has('pushwhiptoken')) {// URL or data:base64 image. Becomes local to this viewer only. This is like &avatar, but slightly different. Just CSS in this case
session.whipOutputToken = urlParams.get('whippushtoken') || urlParams.get('whipouttoken') || urlParams.get('pushwhiptoken') || false;
if (!session.whipOutputToken){
getById("publishOutToken").classList.remove("hidden");
}
}
if (urlParams.has('whepplay')) { // URL or data:base64 image. Becomes local to this viewer only. This is like &avatar, but slightly different. Just CSS in this case
@ -328,6 +339,17 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
}
if (urlParams.has('whepplaytoken')) { // URL or data:base64 image. Becomes local to this viewer only. This is like &avatar, but slightly different. Just CSS in this case
if (urlParams.get('whepplaytoken')){
try {
session.whepInputToken = urlParams.get('whepplaytoken')
} catch(e){
errorlog(e);
}
}
}
if (urlParams.has('nomouseevents') || urlParams.has('nme')) {
session.disableMouseEvents = true;
}
@ -415,6 +437,25 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (urlParams.has('broadcasttransfer') || urlParams.has('bct')) {
log("Broadcast transfer flag set");
session.broadcastTransfer = urlParams.get('broadcasttransfer') || urlParams.get('bct') || null;
if (session.broadcastTransfer === "false") {
session.broadcastTransfer = false;
} else if (session.broadcastTransfer=== "0") {
session.broadcastTransfer = false;
} else if (session.broadcastTransfer === "no") {
session.broadcastTransfer = false;
} else if (session.broadcastTransfer === "off") {
session.broadcastTransfer = false;
} else {
session.broadcastTransfer = true;
}
if (transferSettings){
transferSettings.broadcast = session.broadcastTransfer;
}
}
if (urlParams.has('broadcast') || urlParams.has('bc')) {
log("Broadcast flag set");
session.broadcast = urlParams.get('broadcast') || urlParams.get('bc') || null;
@ -567,6 +608,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
if (urlParams.has('showdirector') || urlParams.has('sd')) {
session.showDirector = parseInt(urlParams.get('showdirector')) || parseInt(urlParams.get('sd')) || true; // if 2, video only allowed. True or 1 will be video + audio allowed.
// fyi, true is the same as 1 when == is used, so assert(1==true) is true.
}
if (urlParams.has('bitratecutoff') || urlParams.has('bitcut')) {
@ -623,6 +665,11 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
document.addEventListener('fullscreenchange', event => {
log("full screen change event");
log(event);
if (document.getElementById("previewWebcam")){
return;
}
if (session.orientation && session.mobile){
if (document.fullscreenElement) {
document.exitFullscreen();
@ -751,6 +798,8 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
getById("container-5").classList.add("skip-animation");
getById("container-5").classList.remove('pointer');
getById("sharefilebutton").style.display = "flex";
if (SafariVersion){
getById("safari_warning_fileshare").classList.remove('hidden');
} else if (!Firefox){
@ -812,6 +861,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.displaySurface = urlParams.get('displaysurface') || "monitor";
}
if (urlParams.has('locksize')){ // browser, window, or monitor (which is default selected)
session.lockWindowSize = urlParams.get('locksize') || true;
}
if (urlParams.has('intro') || urlParams.has('ib')) {
session.introButton = true;
}
@ -1118,12 +1171,24 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
getById("mutetoggle").style.top = "unset";
}
if (urlParams.has('nosettings')){
session.nosettings = true;
getById("settingsbutton").classList.add("hidden");
}
if (urlParams.has('publish')){
session.publish = true;
getById("publishSettings").style.display = "block";
}
if (urlParams.has('nopush') || urlParams.has('noseed') || urlParams.has('viewonly') || urlParams.has('viewmode')) { // this is like a scene; Seeding is disabled. Can be used with &showall to show all videos on load
session.doNotSeed=true;
session.scene = null; // not a scene, but sorta. false vs null makes a difference here.
session.videoDevice = 0;
session.audioDevice = 0;
if (session.scene===false){
session.scene = null; // not a scene, but sorta. false vs null makes a difference here.
}
session.dataMode = true; // thios will let us connect
// session.showall = true; // this can be used to SHOW the videos. (&showall)
}
@ -1167,8 +1232,12 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (session.dataMode){
session.videoDevice = 0;
session.audioDevice = 0;
if (!(session.meshcast || (session.whipOutput!==false) || session.screenshare)){
session.videoDevice = 0;
session.audioDevice = 0;
}
getById("mainmenu").classList.add("hidden");
//session.autohide = true;
//session.autostart = true;
@ -2255,6 +2324,15 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}, session.forceRetry*1000);
}
session.dbx = false;
if (urlParams.get('dropbox')){
loadScript("https://cdnjs.cloudflare.com/ajax/libs/dropbox.js/10.34.0/Dropbox-sdk.min.js", ()=>{
log("Loaded dropbox SDK");
var accessToken = urlParams.get('dropbox');
session.dbx = new Dropbox.Dropbox({ accessToken: accessToken });
});
}
try {
if (urlParams.has("darkmode") || urlParams.has("nightmode")){
session.darkmode = urlParams.get("darkmode") || urlParams.get("nightmode") || null;
@ -2542,6 +2620,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.slots = parseInt(urlParams.get('slots')) || 4;
}
if (urlParams.has('alpha')) {
session.alpha = true;
}
if (urlParams.has('chunked')) {
session.chunked = parseInt(urlParams.get('chunked')) || 2500; // sender side; enables to allows.
// session.alpha = true;
@ -3107,7 +3189,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
log("max channels is 32; channels offset");
session.audioEffects = true;
}
if (urlParams.get('playchannel')) { // must be loaded before channelOffset
session.playChannel = parseInt(urlParams.get('playchannel')); // for audio output ; not input. see: &channelcount instead.
session.audioEffects = true;
}
if (urlParams.has('enhance')) {
//if (parseInt(urlParams.get('enhance')>0){
session.enhance = true; //parseInt(urlParams.get('enhance'));
@ -4070,6 +4155,28 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.screenShareLabel = session.screenShareLabel.replace(/_/g, " ")
}
if (urlParams.has('whepshare') || urlParams.has('whepsrc')) { // URL or data:base64 image. Becomes local to this viewer only. This is like &avatar, but slightly different. Just CSS in this case
try {
session.whepSrc = urlParams.get('whepshare') || urlParams.get('whepsrc') || false;
console.log(session.whepSrc);
if (!session.whepSrc){
session.whepSrc = await promptAlt("Enter the WHEP source as a URL");
} else {
session.whepSrc = decodeURIComponent(session.whepSrc, true);
}
getById("container-6").classList.remove('hidden');
getById("container-6").classList.add("skip-animation");
getById("container-6").classList.remove('pointer');
if (session.whepSrc){
delayedStartupFuncs.push([shareWebsite, session.whepSrc]);
}
} catch(e){
errorlog(e);
}
}
if (session.roomid!==false){
if (!(session.cleanOutput)) {
if (session.roomid === "test") {
@ -4476,6 +4583,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
getById("gridlayout").classList.add("nocontrolbar");
}
if (urlParams.has('experimental')) {
session.experimental = true;
}
if (urlParams.has('flagship')) {
session.flagship = true;
}
@ -5540,38 +5651,45 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
});
window.addEventListener("online", function (e) {
log("Back ONLINE");
closeModal();
if (!session.onceConnected){ // never connected to websockets before. Let's not trigger retryWatchInterval if we don't have to.
return;
}
if (!session.retryWatchInterval()){ // ask for the streams again to watch
session.ping(); // if no streams requested, let's ping instead.
}
});
function updateConnectionStatus() {
/* function updateConnectionStatus() { // no longer works in chrome.
try{
if (!session.stats){
return;
}
log("Connection type changed from " + session.stats.network_type + " to " + Connection.type);
if (session.stats.network_type && (session.stats.network_type !== Connection.type)){
var miniInfo = {};
miniInfo.con = Connection.type;
session.sendMessage({"miniInfo":miniInfo});
if (Connection.type){
log("Connection type changed from " + session.stats.network_type + " to " + Connection.type);
if (!session.retryWatchInterval()){ // ask for the streams again to watch
if (session.stats.network_type && (session.stats.network_type !== Connection.type)){
var miniInfo = {};
miniInfo.con = Connection.type;
session.sendMessage({"miniInfo":miniInfo});
if (!session.retryWatchInterval()){ // ask for the streams again to watch
session.ping(); // if no streams requested, let's ping instead.
}
} else { // connection state changed, but doesn't seem like it actually changed...
session.ping(); // if no streams requested, let's ping instead.
}
} else { // connection state changed, but doesn't seem like it actually changed...
session.ping(); // if no streams requested, let's ping instead.
session.stats.network_type = Connection.type;
}
session.stats.network_type = Connection.type;
} catch(e){warnlog(e);}
}
@ -5579,10 +5697,12 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
try {
var Connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
if (Connection){
session.stats.network_type = Connection.type
if (Connection.type){
session.stats.network_type = Connection.type
}
Connection.addEventListener('change', updateConnectionStatus);
}
} catch (e) {log(e);} // effectiveType is not yet supported by Firefox or Safari; 2021
} catch (e) {log(e);} // effectiveType is not yet supported by Firefox or Safari; 2021 */
setInterval(function() {

View File

@ -2399,6 +2399,19 @@
document.getElementById("sources").appendChild(a);
var button = document.createElement("button");
button.innerHTML = "Publish to Twitch";
button.id = "publishTwitch";
button.onclick = function(){
var URL = window.location.href.replace("/mixer","");
URL+="/?scene=0&layout&remote&room="+roomname+additional;
URL+="&clean&chroma=000&ssar=landscape&nosettings&prefercurrenttab&selfbrowsersurface=include&displaysurface=browser&np&nopush&publish&whippush=twitch&whippushtoken";
var win = window.open( URL ,'targetWindow', 'toolbar=no,location=no,status=no,scaling=no,menubar=no,scrollbars=no,resizable=no,width=1280,height=720');
win.focus();
win.resizeTo(1280,720);
};
document.getElementById("sources").appendChild(button);
var slots = document.getElementById("col1").children;
for (var i=0;i<slots.length;i++){
slots[i].style.backgroundColor = colors[i];

376
publish.html Normal file
View File

@ -0,0 +1,376 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
<style>
html {
border:0;
margin:0;
outline:0;
overflow: hidden;
}
video {
margin: 0;
padding: 0;
overflow: hidden;
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none;
user-select: none;
}
body {
padding: 0 0px;
height: 100%;
width: 100%;
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;
flex-flow: column;
border:0;
margin:0;
outline:0;
}
button.glyphicon-button:focus,
button.glyphicon-button:active:focus,
button.glyphicon-button.active:focus,
button.glyphicon-button.focus,
button.glyphicon-button:active.focus,
button.glyphicon-button.active.focus {
outline: none !important;
}
.gobutton {
font-size:14px;
font-weight: bold;
border: none;
background: #6aab23;
display: flex;
border-radius: 0px;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
box-shadow: 0 12px 15px -10px #5ca70b, 0 2px 0px #6aab23;
color: white;
cursor: pointer;
box-sizing: border-box;
align-items: center;
padding: 0 1em;
}
.details{
font-size: 14px;
font-weight: bold;
border: none;
background: #555;
display: flex;
border-radius: 0px;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
box-shadow: 0 12px 15px -10px #444, 0 2px 0px #555;
color: white;
box-sizing: border-box;
align-items: center;
padding: 0 1em;
}
#header{
width:100%;
background-color: #101520;
}
input.changeText {
font-size: 1em;
align-self: center;
width: 100%;
padding: 1em;
font-weight: bold;
background: white;
border: 4px solid white;
box-shadow: 0px 30px 40px -32px #6aab23, 0 2px 0px #6aab23;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
transition: all 0.2s linear;
box-sizing: border-box;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
input.changeText:focus {
outline: none;
}
.container{
font-size: min(14px, 2vh);
align-self:center;
max-width: 100%;
width: 720px;
margin: auto auto;
}
label {
font: white;
font-size: 1em;
color: white;
}
input[type='checkbox'] {
-webkit-appearance:none;
width:30px;
height:30px;
background:white;
border-radius:5px;
border:2px solid #555;
cursor: pointer;
}
input[type='checkbox']:checked {
background: #1A1;
}
#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-right: 10px;
}
label[for="changeText"] {
font-size: 3em;
color: #00F6FF;
text-shadow: 0px 0px 30px #00f6ff;
padding-top: 5px;
padding-right: 10px;
}
label[for="lastUrls"] {
font-size: 3em;
color: #1a1;
text-shadow: 0px 0px 30px #1a1;
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) {
body{
zoom: 0.9;
-moz-transform: scale(0.9);
-moz-transform-origin: 0 0;
}
}
#messageDiv {
font-size: .7em;
color: #DDD;
transition: all 0.5s linear;
font-style: italic;
opacity: 0;
text-align: center;
margin: 10px 0;
}
div.urlInput {
padding: 0 0 4vh 0;
}
@media only screen and (max-width: 940px) {
body{
zoom: 0.74;
-moz-transform: scale(0.74);
-moz-transform-origin: 0 0;
}
.container{
max-width:99%;
}
div.urlInput {
}
div#audioOutputContainer, #history {
margin: 2em;
}
}
@media only screen and (max-width: 840px) {
body{
zoom: 0.64;
-moz-transform: scale(0.64);
-moz-transform-origin: 0 0;
}
}
@media only screen and (max-height: 639px) {
div.urlInput {
}
div#audioOutputContainer, #history {
margin: 2em;
}
}
@media only screen and (max-width: 767px) {
div.urlInput {
}
div#audioOutputContainer, #history {
margin: 2em 1em;
}
}
@media only screen and (max-height: 380px) {
div.urlInput {
}
div#audioOutputContainer, #history {
margin: 1em;
}
}
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;
}
.inputCombo {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
flex-grow: 1;
}
#version{
margin: 0 auto;
font-size: 30%;
display: inline-block;
color: #000A;
}
h3 {
color: #b0e3ff;
}
</style>
</head>
<body>
<div id="header" style="-webkit-app-region: drag; color:#6f6f6f;font-size:20px; line-height: 20px; padding: 5px 10px; letter-spacing: 3; font-weight: bold;">Publish VDO.Ninja video mix to Twitch</div>
<div class="container">
<div id="urlInput1" class="urlInput" title="Put the link you want to load here">
<h3>Publish a video from VDO.Ninja Scene or View link to Twitch directly</h3>
<div class="inputCombo" id="inputCombo1">
<label for="changeText">
<i class="las la-upload"></i>
</label>
<input type="text" id="changeText1" class="inputfield changeText" placeholder="VDO.Ninja scene link to publish" />
<button onclick="gohere1();" class="gobutton" id="gobutton1">GO</button>
</div>
<div class="inputCombo" style="width:350px;margin:10 0 10 auto;">
<input type="password" id="changeText1a" class="inputfield changeText" placeholder="Authentication Bearer Token (optional)" />
<div class="details">⚙️</div>
</div>
</div>
</div>
<script>
var domain = "./";
document.querySelector("#changeText1").value = localStorage.getItem('changeText1') || "";
document.querySelector("#changeText1a").value = localStorage.getItem('changeText1a') || "";
function gohere1(){
localStorage.setItem('changeText1', document.getElementById('changeText1').value);
localStorage.setItem('changeText1a', document.getElementById('changeText1a').value);
var URL = document.getElementById('changeText1').value;
URL+="&clean&chroma=000&ssar=landscape&nosettings&prefercurrenttab&selfbrowsersurface=include&displaysurface=browser&np&nopush&publish&whippush=https%3A%2F%2Fg.webrtc.live-video.net%3A4443%2Fv2%2Foffer&whippushtoken="+document.querySelector("#changeText1a").value;
var win = window.open( URL ,'targetWindow', 'toolbar=no,location=no,status=no,scaling=no,menubar=no,scrollbars=no,resizable=no,width=1280,height=720');
win.focus();
win.resizeTo(1280,720);
}
function resetHistory(){
localStorage.clear();
document.querySelector("#changeText1").value = "";
document.querySelector("#changeText1a").value = "";
}
(function (w) {
w.URLSearchParams = w.URLSearchParams || function (searchString) {
var self = this;
self.searchString = searchString;
self.get = function (name) {
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString);
if (results == null) {
return null;
}
else {
return decodeURI(results[1]) || 0;
}
};
}
})(window)
var urlParams = new URLSearchParams(window.location.search);
function enterPressed(event, callback){
if (event.keyCode === 13){ // Number 13 is the "Enter" key on the keyboard
event.preventDefault(); // Cancel the default action, if needed
callback();
}
}
var isMobile = false;
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){ // does not detect iPad Pros.
isMobile=true; // if iOS, default to H264? meh. let's not.
}
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -308,7 +308,7 @@
<button onclick="gohere1();" class="gobutton" id="gobutton1">GO</button>
</div>
<div class="inputCombo" style="width:350px;margin:10 0 10 auto;">
<input type="text" id="changeText1a" class="inputfield changeText" placeholder="Authentication Bearer Token (optional)" />
<input type="password" id="changeText1a" class="inputfield changeText" placeholder="Authentication Bearer Token (optional)" />
<div class="details">⚙️</div>
</div>
</div>
@ -321,7 +321,7 @@
<label for="changeText">
<i class="las la-upload"></i>
</label>
<input type="text" id="changeText1t" class="inputfield changeText" placeholder="Enter your Twitch stream token here" />
<input type="password" id="changeText1t" class="inputfield changeText" placeholder="Enter your Twitch stream token here" />
<button onclick="gohere1t();" class="gobutton" id="gobutton1t">GO</button>
</div>
</div>
@ -396,7 +396,7 @@ function gohere1(){
function gohere1t(){
if (document.getElementById('changeText1t').value){
localStorage.setItem('changeText1t', document.getElementById('changeText1t').value);
window.location = domain + "?push&whippush=https%3A%2F%2Ftwitch.vdo.ninja%2F"+ document.getElementById('changeText1t').value;
window.location = domain + "?push&whippush=https%3A%2F%2Fg.webrtc.live-video.net%3A4443%2Fv2%2Foffer&whippushtoken="+ document.getElementById('changeText1t').value;
}
}