mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-20 01:48:30 +00:00
right click context menu options
&sspaused added also -- minor polish bugs with the new features need to be worked out still
This commit is contained in:
parent
0b64e44e3b
commit
981841583a
44
index.html
44
index.html
@ -54,7 +54,7 @@
|
||||
transition: opacity .1s linear;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="./main.css?ver=151" />
|
||||
<link rel="stylesheet" href="./main.css?ver=152" />
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.min.js"></script>
|
||||
<style id="lightbox-animations" type="text/css"></style>
|
||||
</head>
|
||||
@ -67,7 +67,7 @@
|
||||
<link itemprop="url" href="./media/vdoNinja_logo_full.png" />
|
||||
</span>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=36"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=345"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=346"></script>
|
||||
<input id="zoomSlider" type="range" style="display: none;" />
|
||||
<div id="header">
|
||||
|
||||
@ -774,24 +774,30 @@
|
||||
|
||||
<br />
|
||||
<i>
|
||||
<font style="color: red;">Known issues:</font>
|
||||
<a href="https://docs.vdo.ninja/common-errors-and-known-issues/known-issues" title="For more known issues, click here" target="_blank"><font style="color: red;">Known issues:</font></a>
|
||||
</i>
|
||||
<br />
|
||||
<li>
|
||||
Some devices that use hardware encoding can experience video glitching; switching to VP8 or VP9 as a <a target='_blank' title='Jump to the documentation' href='https://docs.vdo.ninja/viewers-settings/codec'>codec</a> may help.
|
||||
</li>
|
||||
<li>
|
||||
Windows users, upgrading to OBS 27.2 or newer will fix video glitching issues caused by network packet loss. <a href='https://github.com/obsproject/obs-studio/releases' target="_blank">Grab the newest OBS version here</a>.
|
||||
</li>
|
||||
<li>
|
||||
Samsung smartphones (A-series) may fail to publish video with some mobile browsers; try using Firefox Mobile or the native <a href='https://docs.vdo.ninja/getting-started/native-mobile-app-versions#android-download-link'>Android app</a> in these cases.
|
||||
</li>
|
||||
<li>
|
||||
Some devices that use hardware encoding can experience video issues; switching to VP8 or VP9 as a <a target='_blank' title='Jump to the documentation' href='https://docs.vdo.ninja/viewers-settings/codec'>codec</a> may help.
|
||||
</li>
|
||||
<li>
|
||||
iPhones continue to have random audio issues, such as lowered volume or no audio at all. These are issues that Apple needs to fix.</a>.
|
||||
</li>
|
||||
<li>
|
||||
Audio may drop out in OBS Studio at random times, yet still appear active. Delete the browser source and re-create, or use the <a href="https://github.com/steveseguin/electroncapture">Electron Capture</a> app instead</a>.
|
||||
</li>
|
||||
<br />
|
||||
<h4>
|
||||
<font style="color:#daad09;">Welcome to VDO Ninja! We've rebranded! Nothing else is changing and we're staying 100% free.</font>
|
||||
</h4>
|
||||
<br />
|
||||
🎁 Welcome to v20, released December 24th. 🎄 <a target="_blank" href="https://docs.vdo.ninja/release-notes/v20">Release notes are here</a>. The previous version is <a href="https://vdo.ninja/v19/">available here</a> if you have new issues.
|
||||
🎁 Welcome to v20, released December 24th. <a target="_blank" href="https://docs.vdo.ninja/release-notes/v20">Release notes are here</a>. The previous version is <a href="https://vdo.ninja/v19/">available here</a> if you have new issues.
|
||||
|
||||
<br />
|
||||
<br />
|
||||
@ -1669,6 +1675,24 @@
|
||||
<span data-translate="picture-in-picture">Picture-in-picture</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="context-menu__item">
|
||||
<a href="#" class="context-menu__link" data-action="fullWindow">
|
||||
<i class="las la-external-link"></i>
|
||||
<span data-translate="full-window">Full-window</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="context-menu__item">
|
||||
<a href="#" class="context-menu__link" data-action="Pause">
|
||||
<i class="las la-external-link"></i>
|
||||
<span data-translate="pause-stream">Pause stream</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="context-menu__item">
|
||||
<a href="#" class="context-menu__link" data-action="Record">
|
||||
<i class="las la-external-link"></i>
|
||||
<span data-translate="record-to-disk">Record to disk</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@ -1937,11 +1961,11 @@
|
||||
// session.introOnClean = true; // this will load the page with the webcam selection screen if &push or &room is in the URL; no need to use &webcam.
|
||||
</script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=256"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=257"></script>
|
||||
<!--
|
||||
// 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" crossorigin="anonymous" id="main-js" src="./main.js?ver=290"></script>
|
||||
-->
|
||||
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=293"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
30
main.css
30
main.css
@ -76,12 +76,12 @@ table {
|
||||
padding:3%;
|
||||
}
|
||||
|
||||
#playButton {
|
||||
.playButton {
|
||||
border-radius: 50vh;
|
||||
width: min(50vw, 50vh);
|
||||
cursor: pointer;
|
||||
opacity: 100%;
|
||||
margin-top: 20vh;
|
||||
margin-top: 10vh;
|
||||
background-color: #646262;
|
||||
background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 122.88 122.88' style='enable-background:new 0 0 122.88 122.88' xml:space='preserve'%3E%3Cstyle type='text/css'%3E.st0%7Bfill-rule:evenodd;clip-rule:evenodd;%7D%3C/style%3E%3Cg%3E%3Cpath class='st0' d='M61.44,0c33.93,0,61.44,27.51,61.44,61.44s-27.51,61.44-61.44,61.44S0,95.37,0,61.44S27.51,0,61.44,0L61.44,0z M83.31,65.24c3.13-2.02,3.12-4.27,0-6.06L50.98,40.6c-2.55-1.6-5.21-0.66-5.14,2.67l0.1,37.55c0.22,3.61,2.28,4.6,5.32,2.93 L83.31,65.24L83.31,65.24z M61.44,12.48c27.04,0,48.96,21.92,48.96,48.96c0,27.04-21.92,48.96-48.96,48.96S12.48,88.48,12.48,61.44 C12.48,34.4,34.4,12.48,61.44,12.48L61.44,12.48z'/%3E%3C/g%3E%3C/svg%3E");
|
||||
display: inline-block;
|
||||
@ -89,6 +89,9 @@ table {
|
||||
background-repeat: no-repeat;
|
||||
border: #646262 7vh solid;
|
||||
}
|
||||
.paused {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
tr {
|
||||
padding:4px;
|
||||
@ -732,11 +735,11 @@ button.glyphicon-button.active.focus {
|
||||
-webkit-tap-highlight-color: transparent !important;
|
||||
outline: 0px !important;
|
||||
height:100%;
|
||||
animation: fading 0.2s;
|
||||
animation: fadeIn 0.2s;
|
||||
}
|
||||
|
||||
#controlButtons {
|
||||
position: fixed;
|
||||
position: fixed;
|
||||
z-index: 5;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
@ -1155,7 +1158,7 @@ body {
|
||||
max-width: 83vw;
|
||||
height: 30vh;
|
||||
opacity:1;
|
||||
animation: fading 0.2s;
|
||||
animation: fadeIn 0.2s;
|
||||
}
|
||||
|
||||
#getPermissions{
|
||||
@ -1716,17 +1719,20 @@ label {
|
||||
color: black;
|
||||
}
|
||||
|
||||
@keyframes fading {
|
||||
.fadeout {
|
||||
animation: fadeout 1s;
|
||||
opacity: 0!important;
|
||||
}
|
||||
|
||||
@keyframes fadeout {
|
||||
0% {
|
||||
opacity: 0
|
||||
}
|
||||
100% {
|
||||
opacity: 1
|
||||
}
|
||||
100% {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
img {
|
||||
border-radius: 5px 5px 0 0;
|
||||
margin: 5px;
|
||||
@ -2067,7 +2073,7 @@ img {
|
||||
animation-iteration-count: 1;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
@keyframes fadeIn {
|
||||
0% {opacity:0;}
|
||||
100% {opacity:1;}
|
||||
}
|
||||
|
||||
75
main.js
75
main.js
@ -100,7 +100,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
|
||||
if (!isIFrame){
|
||||
if (getChromeVersion()===65){
|
||||
if (ChromeVersion===65){
|
||||
// pass, since probably manycam and that's bugged
|
||||
} else if (getStorage("redirect") == "yes") {
|
||||
setStorage("redirect", "", 0);
|
||||
@ -235,7 +235,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
} else {
|
||||
log("MAKE DRAGGABLE");
|
||||
delayedStartupFuncs.push([makeDraggableElement, document.getElementById("subControlButtons")]);
|
||||
if (safariVersion() && !getChromeVersion()){ // if desktop Safari, so macOS, give a note saying it sucks
|
||||
if (SafariVersion && !ChromeVersion){ // if desktop Safari, so macOS, give a note saying it sucks
|
||||
getById("SafariWarning").classList.remove("advanced");
|
||||
}
|
||||
}
|
||||
@ -670,7 +670,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
|
||||
if (urlParams.has('record')) {
|
||||
if (safariVersion()) {
|
||||
if (SafariVersion) {
|
||||
if (!(session.cleanOutput)) {
|
||||
warnUser("Your browser or device is not supported. Try Chrome if on macOS.");
|
||||
}
|
||||
@ -711,8 +711,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
session.disableWebAudio = true;
|
||||
session.audioEffects = false;
|
||||
session.audioMeterGuest = false;
|
||||
session.style = 1;
|
||||
session.audioMeterGuest = false;
|
||||
}
|
||||
|
||||
if (urlParams.has('autoadd')) { // the streams we want to view; if set, but let blank, we will request no streams to watch.
|
||||
@ -1236,6 +1235,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
session.view_set = session.view.split(",");
|
||||
}
|
||||
}
|
||||
|
||||
if ((session.scene !== false) && (session.style === false) && window.obsstudio){
|
||||
session.style = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1446,10 +1449,9 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
if (!(urlParams.has('streamlabs'))) {
|
||||
|
||||
var ver1 = window.obsstudio.pluginVersion.split(".");
|
||||
var cefVersion = getChromeVersion();
|
||||
|
||||
if (ver1.length == 3) { // Should be 3, but disabled3
|
||||
if ((ver1.length == 3) && (parseInt(ver1[0]) == 2) && (cefVersion < 76) && (macOS)) {
|
||||
if ((ver1.length == 3) && (parseInt(ver1[0]) == 2) && (ChromeVersion < 76) && (macOS)) {
|
||||
updateURL("streamlabs");
|
||||
getById("main").innerHTML = "<div style='background-color:black;color:white;' data-translate='obs-macos-not-supported'><h1>Update OBS Studio to v26.1.2 or newer; older versions and StreamLabs OBS are not supported on macOS.\
|
||||
<br /><i><small><small>download here: <a href='https://github.com/obsproject/obs-studio/releases'>https://github.com/obsproject/obs-studio/releases</a></small></small></i>\
|
||||
@ -1463,9 +1465,9 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
}
|
||||
|
||||
if (navigator.userAgent.indexOf('Mac OS X') != -1) {
|
||||
session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) // oct 2021, OBS now supports vp8 and actually breaks with h264 android devices.
|
||||
}
|
||||
//if (navigator.userAgent.indexOf('Mac OS X') != -1) {
|
||||
// session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) // oct 2021, OBS now supports vp8 and actually breaks with h264 android devices.
|
||||
//}
|
||||
|
||||
if (session.disableOBS===false){
|
||||
window.addEventListener("obsSourceVisibleChanged", obsSourceVisibleChanged);
|
||||
@ -1834,13 +1836,13 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
session.webp = true;
|
||||
session.codec = false;
|
||||
}
|
||||
} else if (isOperaGX()){
|
||||
} else if (OperaGx){
|
||||
session.codec = "vp8";
|
||||
warnlog("Defaulting to VP8 manually, as H264 with remote iOS devices is not supported");
|
||||
}
|
||||
|
||||
if (urlParams.has('h264profile')) {
|
||||
session.h264profile = urlParams.get('h264profile') || "42e01f";
|
||||
session.h264profile = urlParams.get('h264profile') || "42e01f"; // 42001f
|
||||
session.h264profile = session.h264profile.substring(0, 6);
|
||||
session.h264profile = session.h264profile.toLowerCase();
|
||||
}
|
||||
@ -2100,8 +2102,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
errorlog(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (urlParams.has('cleanish')) {
|
||||
session.cleanish = true;
|
||||
}
|
||||
@ -2194,7 +2195,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
|
||||
if (urlParams.has('buffer')) { // needs to be before sync
|
||||
if ((getChromeVersion() > 50) && (getChromeVersion()< 78)){
|
||||
if ((ChromeVersion > 50) && (ChromeVersion< 78)){
|
||||
|
||||
} else {
|
||||
session.buffer = parseFloat(urlParams.get('buffer')) || 0;
|
||||
@ -2213,7 +2214,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
|
||||
if (urlParams.has('sync')) {
|
||||
if ((getChromeVersion() > 50) && (getChromeVersion()< 78)){
|
||||
if ((ChromeVersion > 50) && (ChromeVersion< 78)){
|
||||
|
||||
} else {
|
||||
session.sync = parseFloat(urlParams.get('sync'));
|
||||
@ -2289,7 +2290,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
session.icefilter = urlParams.get('icefilter');
|
||||
}
|
||||
|
||||
//if (!(getChromeVersion()>=57)){
|
||||
//if (!(ChromeVersion>=57)){
|
||||
// getById("effectSelector").disabled=true;
|
||||
// getById("effectSelector3").disabled=true;
|
||||
// getById("effectSelector").title = "Effects are only support on Chromium-based browsers";
|
||||
@ -2373,8 +2374,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
|
||||
if (urlParams.has('style') || urlParams.has('st')) {
|
||||
session.style = urlParams.get('style') || urlParams.get('st') || 1;
|
||||
if ((parseInt(session.style) == 1) || (session.style == "justvideo")) { // no audio only
|
||||
session.style = urlParams.get('style') || urlParams.get('st');
|
||||
if ((parseInt(session.style) === 0) || (session.style == "controls")) { // no audio only
|
||||
session.style = 0;
|
||||
} else if ((parseInt(session.style) == 1) || (session.style == "justvideo")) { // no audio only
|
||||
session.style = 1;
|
||||
} else if ((parseInt(session.style) == 2) || (session.style == "waveform")) { // audio waveform
|
||||
session.style = 2;
|
||||
@ -2742,7 +2745,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
getById("container-2").className = 'column columnfade advanced'; // Hide screen share
|
||||
getById("container-3").classList.add("skip-animation");
|
||||
getById("container-3").classList.remove('pointer');
|
||||
delayedStartupFuncs.push([previewWebcam]);
|
||||
delayedStartupFuncs.push([previewWebcam]);
|
||||
}
|
||||
|
||||
if (session.cleanViewer){
|
||||
@ -2755,6 +2758,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
session.screenShareElementHidden = true;
|
||||
}
|
||||
|
||||
if (urlParams.has('sspaused') || urlParams.has('sspause') || urlParams.has('ssp')) { // this way I don't need to remember what it's called. I can just guess. :D
|
||||
session.screenShareStartPaused = true;
|
||||
}
|
||||
|
||||
if (urlParams.has('zoomedbitrate') || urlParams.has('zb')) { // this way I don't need to remember what it's called. I can just guess. :D
|
||||
session.zoomedBitrate = urlParams.get('zoomedbitrate') || urlParams.get('zb') || 2500;
|
||||
session.zoomedBitrate = parseInt(session.zoomedBitrate) ;
|
||||
@ -2892,14 +2899,15 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
} else if (session.chatbutton === false) {
|
||||
getById("chatbutton").classList.add("advanced");
|
||||
}
|
||||
} else {
|
||||
if ((session.permaid === null) && (session.roomid == "")) {
|
||||
if (!(session.cleanOutput)) {
|
||||
getById("head3").classList.remove('advanced');
|
||||
getById("head3a").classList.remove('advanced');
|
||||
}
|
||||
} else if ((session.permaid === null) && (session.roomid == "")) {
|
||||
if (!(session.cleanOutput)) {
|
||||
getById("head3").classList.remove('advanced');
|
||||
getById("head3a").classList.remove('advanced');
|
||||
}
|
||||
} else if ((window.obsstudio) && (session.permaid === false) && (session.director === false) && (session.view) &&(session.roomid.length>0)) { // we already know roomid !== false
|
||||
updateURL("scene", true, false); // we also know it's not a scene, but we will assume it is in this specific case.
|
||||
}
|
||||
|
||||
|
||||
} else if (urlParams.has('director') || urlParams.has('dir')) { // if I do a short form of this, it will cause duplications in the code elsewhere.
|
||||
if (directorLanding == false) {
|
||||
@ -2939,7 +2947,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
//if (!session.activeSpeaker){
|
||||
session.audioMeterGuest = false;
|
||||
//}
|
||||
if (session.style===false){
|
||||
if ((session.style===false) && window.obsstudio){
|
||||
session.style = 1;
|
||||
}
|
||||
if (session.audioEffects === null) {
|
||||
@ -2992,7 +3000,8 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
getById("header").style.display = "none";
|
||||
getById("header").style.opacity = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (session.view) {
|
||||
getById("main").className = "";
|
||||
@ -3011,6 +3020,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}
|
||||
|
||||
if ((session.view) && (session.roomid === false)) {
|
||||
|
||||
getById("container-4").className = 'column columnfade';
|
||||
getById("container-3").className = 'column columnfade';
|
||||
getById("container-2").className = 'column columnfade';
|
||||
@ -3065,8 +3075,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
}, timeout);
|
||||
|
||||
log("auto playing");
|
||||
var SafariVer = safariVersion();
|
||||
if ((iPad || iOS) && navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 && SafariVer > 13) { // Modern iOS doesn't need pop up
|
||||
if ((iPad || iOS) && navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 && SafariVersion > 13) { // Modern iOS doesn't need pop up
|
||||
play();
|
||||
} else if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) { // Safari on Desktop does require pop up
|
||||
if (!(session.cleanOutput)) {
|
||||
@ -3147,6 +3156,12 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
errorlog(e);
|
||||
}
|
||||
|
||||
if (urlParams.has('autohide')) {
|
||||
session.autohide=true;
|
||||
}
|
||||
if (session.autohide && !session.mobile && (session.scene===false)){// && (session.roomid!==false)){
|
||||
getById("main").onmouseover = showControl;
|
||||
}
|
||||
|
||||
// Please contact steve on discord.vdo.ninja if you'd like this iFRAME tweaked, expanded, etc -- it's updated based on user request
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user