mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-11 13:48:38 +00:00
- fixed issue with mobile rear camera not working - improved mobile sizing for low resolution horizontal viewing - added OBS v25 drag and drop support from Chrome on Windows. -- also spent a lot of time looking into trying to get OBS to work on Mac OS; solution was to use v23 on MacOS
996 lines
43 KiB
HTML
996 lines
43 KiB
HTML
<html>
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
|
|
|
|
<script src="//console.re/connector.js" data-channel="obsninja" id="consolerescript"></script>
|
|
|
|
<style type="text/css">
|
|
#mynetwork {
|
|
width: 600px;
|
|
height: 400px;
|
|
border: 1px solid lightgray;
|
|
}
|
|
</style>
|
|
<style>
|
|
* {
|
|
padding: 0;
|
|
margin: 0;
|
|
box-sizing: border-box;
|
|
|
|
}
|
|
.email { unicode-bidi: bidi-override; direction: rtl; user-select: none; }
|
|
.credits {
|
|
color:black;
|
|
position:absolute;
|
|
bottom:0;
|
|
right:0;
|
|
z-index:-1;
|
|
}
|
|
.credits >a {
|
|
color:black;
|
|
}
|
|
.credits >a:visited{
|
|
color:black;
|
|
}
|
|
|
|
.row {
|
|
align-content:center;
|
|
text-align: center;
|
|
margin-top:10px;
|
|
|
|
}
|
|
|
|
#videosource {
|
|
max-width:100%;
|
|
max-height:100%;
|
|
}
|
|
/* Clear floats after the columns */
|
|
.row:after {
|
|
content: "";
|
|
display: table;
|
|
clear: both;
|
|
}
|
|
|
|
html {
|
|
height: 100%;
|
|
}
|
|
|
|
|
|
body {
|
|
padding: 0 3px;
|
|
height: 100%;
|
|
width: 100%;
|
|
background: #141926;
|
|
font-family: Helvetica, Arial, sans-serif;
|
|
display: flex;
|
|
flex-flow: column;
|
|
}
|
|
|
|
.gowebcam {
|
|
padding:20px;
|
|
}
|
|
.infoblob {
|
|
color:white;
|
|
width:100%;
|
|
padding:20px;
|
|
max-width:1280px;
|
|
|
|
}
|
|
|
|
@media only screen and (max-height: 480px) {
|
|
body {
|
|
font-size: 0.5em;
|
|
}
|
|
.gowebcam {
|
|
padding:5px;
|
|
}
|
|
|
|
.infoblob {
|
|
color:white;
|
|
width:100%;
|
|
padding:80px;
|
|
max-width:1280px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
h2 {
|
|
color: white;
|
|
}
|
|
|
|
.outer {
|
|
position: relative;
|
|
margin: auto;
|
|
width: 70px;
|
|
margin-top: 0px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.inner {
|
|
width: inherit;
|
|
text-align: center;
|
|
}
|
|
|
|
label {
|
|
font-size: 1.1em;
|
|
line-height: 4em;
|
|
font-weight: bold;
|
|
text-transform: uppercase;
|
|
color: #000;
|
|
transition: all .3s ease-in;
|
|
opacity: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.inner:before, .inner:after {
|
|
position: absolute;
|
|
content: '';
|
|
height: 7px;
|
|
width: inherit;
|
|
background: #000;
|
|
left: 0;
|
|
transition: all .3s ease-in;
|
|
}
|
|
|
|
.inner:before {
|
|
top: 50%;
|
|
transform: rotate(45deg);
|
|
}
|
|
|
|
.inner:after {
|
|
bottom: 50%;
|
|
transform: rotate(-45deg);
|
|
}
|
|
|
|
.outer:hover label {
|
|
opacity: 1;
|
|
}
|
|
|
|
.outer:hover .inner:before,
|
|
.outer:hover .inner:after {
|
|
transform: rotate(0);
|
|
}
|
|
|
|
.outer:hover .inner:before {
|
|
top: 0;
|
|
}
|
|
|
|
.outer:hover .inner:after {
|
|
bottom: 0;
|
|
}
|
|
.advanced { display: none !important}
|
|
|
|
.fullcolumn {
|
|
float:left;
|
|
display: inline-block;
|
|
margin: 0 auto;
|
|
width: 100%;
|
|
text-align: center;
|
|
/* Add shadows to create the "card" effect */
|
|
box-shadow: 0 4px 8px 0 rgba(0,0,0,.1);
|
|
}
|
|
|
|
/* Create four equal columns that floats next to each other */
|
|
.column {
|
|
float:left;
|
|
display: inline-block;
|
|
margin: 1.8%;
|
|
min-width: 300px;
|
|
width: 20%;
|
|
padding: 28px;
|
|
height: 220px; /* Should be removed. Only for demonstration */
|
|
|
|
text-align: center;
|
|
|
|
/* Add shadows to create the "card" effect */
|
|
box-shadow: 0 4px 8px 0 rgba(0,0,0,.1);
|
|
}
|
|
/* On mouse-over, add a deeper shadow */
|
|
.column:hover {
|
|
box-shadow: 0 8px 16px 0 rgba(0,0,0,.3);
|
|
}
|
|
.column > h2 {color:black;}
|
|
|
|
|
|
@media only screen and (max-height: 480px) {
|
|
.column {
|
|
min-width:170px;
|
|
height: 180px;
|
|
}
|
|
}
|
|
|
|
.columnfade {
|
|
animation:fading 0.2s}@keyframes fading{0%{opacity:0}100%{opacity:1}}
|
|
}
|
|
|
|
img {
|
|
border-radius: 5px 5px 0 0;
|
|
margin:5px;
|
|
}
|
|
|
|
button {
|
|
padding:5px 10px 3px 10px;
|
|
margin:10px 0px;
|
|
}
|
|
/* Empty container that will replace the original container */
|
|
#empty-container {
|
|
display: inline-block;
|
|
float:left;
|
|
width: 20%;
|
|
min-width: 300px;
|
|
padding: 28px;
|
|
height: 220px; /* Should be removed. Only for demonstration */
|
|
margin: 1.8%;
|
|
text-align: center;
|
|
}
|
|
|
|
|
|
#container-1 {
|
|
background-repeat: no-repeat;
|
|
background-size: 80px;
|
|
background-position: 50% 65%;
|
|
background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPGc+CiAgICAgIDxwYXRoIGQ9Im0xMC41LDU4LjloNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjNjMC0yLjMtMS44LTQuMS00LjEtNC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMiAxLjksNC4xIDQuMSw0LjF6bTQuMS00NC4zaDM2LjF2MzYuMWgtMzYuMXYtMzYuMXoiIGZpbGw9IiMwMDAwMDAiLz4KICAgICAgPHBhdGggZD0ibTEyMi42LDEwLjVjMC0yLjMtMS44LTQuMS00LjEtNC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjN6bS04LjIsNDAuMmgtMzYuMXYtMzYuMWgzNi4xdjM2LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im0xMC41LDEyMi42aDQ0LjNjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi00NC4zYzAtMi4zLTEuOC00LjEtNC4xLTQuMWgtNDQuM2MtMi4zLDAtNC4xLDEuOC00LjEsNC4xdjQ0LjNjMCwyLjIgMS45LDQuMSA0LjEsNC4xem00LjEtNDQuM2gzNi4xdjM2LjFoLTM2LjF2LTM2LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im0xMTguNSw3MC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjNjMC0yLjItMS45LTQuMS00LjEtNC4xem0tNC4xLDQ0LjNoLTM2LjF2LTM2LjFoMzYuMXYzNi4xeiIgZmlsbD0iIzAwMDAwMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==)
|
|
}
|
|
|
|
#container-2 {
|
|
background-repeat: no-repeat;
|
|
background-size: 80px;
|
|
background-position: 50% 65%;
|
|
background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTExOC41LDEwLjVoLTEwOGMtMi4zLDAtNC4xLDEuOC00LjEsNC4xdjUxLjcgMjEuMWMwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDkuOXYxOC44aC0yMi45Yy0yLjMsMC00LjEsMS44LTQuMSw0LjFzMS44LDQuMSA0LjEsNC4xaDU0YzIuMywwIDQuMS0xLjggNC4xLTQuMXMtMS44LTQuMS00LjEtNC4xaC0yMi45di0xOC44aDQ5LjljMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0yMS4xLTUxLjdjMC0yLjMtMS44LTQuMS00LjEtNC4xem0tNC4xLDcyLjhoLTk5Ljh2LTEzaDk5Ljh2MTN6bTAtMjEuMWgtOTkuOHYtNDMuNWg5OS44djQzLjV6IiBmaWxsPSIjMDAwMDAwIi8+CiAgPC9nPgo8L3N2Zz4K)
|
|
}
|
|
#container-3 {
|
|
background-repeat: no-repeat;
|
|
background-size: 80px;
|
|
background-position: 50% 65%;
|
|
background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTk2LjYsMjYuOGgtODYuMWMtMi4yLDAtNC4xLDEuOC00LjEsNC4xdjY3LjJjMCwyLjIgMS44LDQuMSA0LjEsNC4xaDg2LjFjMi4yLDAgNC4xLTEuOCA0LjEtNC4xdi0xOS40bDE0LjksMTQuOWMwLjgsMC44IDEuOCwxLjIgMi45LDEuMiAwLjUsMCAxLjEtMC4xIDEuNi0wLjMgMS41LTAuNiAyLjUtMi4xIDIuNS0zLjh2LTUyLjVjMC0xLjYtMS0zLjEtMi41LTMuOC0xLjUtMC42LTMuMy0wLjMtNC40LDAuOWwtMTQuOSwxNC45di0xOS4zYy0wLjEtMi4zLTEuOS00LjEtNC4yLTQuMXptLTQuMSwzMy4zdjguOCAyNS4yaC03OHYtNTkuMmg3OHYyNS4yem0yMS45LTEydjMyLjlsLTEzLjctMTMuN3YtNS40bDEzLjctMTMuOHoiIGZpbGw9IiMwMDAwMDAiLz4KICA8L2c+Cjwvc3ZnPgo=)
|
|
}
|
|
#container-4 {
|
|
background-repeat: no-repeat;
|
|
background-size: 80px;
|
|
background-position: 50% 65%;
|
|
background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPGc+CiAgICAgIDxwYXRoIGQ9Im0xOC43LDEyMi41aDkxLjZjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0xMDcuOWMwLTIuMy0xLjgtNC4xLTQuMS00LjFoLTY4LjdjLTAuMywwLTAuNywwLTEsMC4xLTAuMSwwLTAuMiwwLjEtMC4yLDAuMS0wLjMsMC4xLTAuNSwwLjItMC44LDAuMy0wLjEsMC4xLTAuMiwwLjEtMC4zLDAuMi0wLjMsMC4yLTAuNiwwLjQtMC44LDAuN2wtMjIuOSwyN2MtMC4zLDAuMy0wLjUsMC43LTAuNywxLjEtMC4xLDAuMS0wLjEsMC4zLTAuMSwwLjQtMC4xLDAuMy0wLjEsMC42LTAuMiwwLjkgMCwwLjEgMCwwLjEgMCwwLjJ2ODAuOWMtMS4wNjU4MWUtMTQsMi40IDEuOSw0LjIgNC4xLDQuMnptMTguOC0xMDAuOHYxMS44aC0xMGwxMC0xMS44em0tMTQuNywxOS45aDE4LjhjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0yMi45aDYwLjV2OTkuN2gtODMuNHYtNzIuN3oiIGZpbGw9IiMwMDAwMDAiLz4KICAgICAgPHBhdGggZD0ibTk0LDUwLjVoLTU5Yy0yLjMsMC00LjEsMS44LTQuMSw0LjEgMCwyLjMgMS44LDQuMSA0LjEsNC4xaDU5YzIuMywwIDQuMS0xLjggNC4xLTQuMSAwLTIuMy0xLjgtNC4xLTQuMS00LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im05NCw3MC4zaC01OWMtMi4zLDAtNC4xLDEuOC00LjEsNC4xIDAsMi4zIDEuOCw0LjEgNC4xLDQuMWg1OWMyLjMsMCA0LjEtMS44IDQuMS00LjEgMC0yLjItMS44LTQuMS00LjEtNC4xeiIgZmlsbD0iIzAwMDAwMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==)
|
|
}
|
|
|
|
|
|
|
|
#container-5 {
|
|
background-repeat: no-repeat;
|
|
background-size: 80px;
|
|
background-position: 50% 65%;
|
|
background-image: url(data:image/png;base64,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)
|
|
|
|
}
|
|
.float{
|
|
position:fixed;
|
|
width:60px;
|
|
height:60px;
|
|
bottom:80px;
|
|
right:50px;
|
|
background-color:#C23;
|
|
color:#FFF;
|
|
border-radius:50px;
|
|
text-align:center;
|
|
box-shadow: 2px 2px 3px #999;
|
|
z-index:10;
|
|
}
|
|
.float2{
|
|
position:fixed;
|
|
width:60px;
|
|
height:60px;
|
|
bottom:80px;
|
|
right:132px;
|
|
background-color:#15B;
|
|
color:#FFF;
|
|
border-radius:50px;
|
|
text-align:center;
|
|
box-shadow: 2px 2px 3px #999;
|
|
z-index:10;
|
|
}
|
|
.float3{
|
|
position:fixed;
|
|
width:60px;
|
|
height:60px;
|
|
bottom:80px;
|
|
right:52px;
|
|
background-color:#0C2;
|
|
color:#FFF;
|
|
border-radius:50px;
|
|
text-align:center;
|
|
box-shadow: 2px 2px 3px #999;
|
|
z-index:10;
|
|
}
|
|
|
|
|
|
.my-float{
|
|
margin-top:7px;
|
|
}
|
|
|
|
#container-6 {
|
|
background-repeat: no-repeat;
|
|
background-size: 80px;
|
|
background-position: 50% 65%;
|
|
background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTExOC4yLDMzLjVjLTAuMiwwLTI1LjItMC42LTUwLjctMjUuOS0wLjgtMC44LTEuOC0xLjItMi45LTEuMmgtMC40Yy0xLjEsMC0yLjEsMC40LTIuOSwxLjItMjUuMywyNS4zLTUwLjMsMjUuOS01MC41LDI1LjktMi4yLDAtNCwxLjgtNCw0LjF2MjYuNGMwLDAuNSAwLjEsMSAwLjMsMS41IDAuNywxLjggMTgsNDQuNSA1Niw1Ni40IDAuNCwwLjEgMC44LDAuMiAxLjIsMC4yIDAuMSwwIDAuMywwIDAuNCwwIDAuNCwwIDAuOC0wLjEgMS4yLTAuMiAzOC0xMS45IDU1LjMtNTQuNiA1Ni01Ni40IDAuMi0wLjUgMC4zLTEgMC4zLTEuNXYtMjYuNGMwLTIuMi0xLjgtNC00LTQuMXptLTQuMSwyOS43Yy0yLjMsNS4zLTE4LjQsNDAuMi00OS42LDUwLjYtMzEuMi0xMC40LTQ3LjMtNDUuMy00OS42LTUwLjd2LTIxLjhjOC40LTEuMSAyOC41LTUuNyA0OS42LTI1LjQgMjEuMSwxOS43IDQxLjIsMjQuMyA0OS42LDI1LjR2MjEuOXoiIGZpbGw9IiMwMDAwMDAiLz4KICA8L2c+Cjwvc3ZnPgo=)
|
|
}
|
|
.container-inner {
|
|
display: none;
|
|
}
|
|
|
|
img {
|
|
max-width: 100%;
|
|
}
|
|
|
|
video {
|
|
flex: 1 1 auto;
|
|
background-color: black;
|
|
}
|
|
|
|
.close {
|
|
position: absolute;
|
|
right: 20px;
|
|
top: 20px;
|
|
cursor: pointer;
|
|
display: none;
|
|
}
|
|
|
|
.in-animation {
|
|
animation: inlightbox 0.8s forwards;
|
|
position: fixed !important;
|
|
margin: 0 !important;
|
|
}
|
|
|
|
.out-animation {
|
|
animation: outlightbox 0.8s forwards;
|
|
}
|
|
|
|
@keyframes inlightbox
|
|
{
|
|
50% {
|
|
width: 100%;
|
|
left: 0;
|
|
height: 220px;
|
|
}
|
|
100% {
|
|
height: 100%;
|
|
width: 100%;
|
|
top: 0;
|
|
left: 0;
|
|
}
|
|
}
|
|
|
|
</style>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
|
|
</head>
|
|
<body id="main">
|
|
<script language="javascript" type="text/javascript" src="./webrtc.js"></script>
|
|
|
|
<div id="header">
|
|
<h2>
|
|
<a href="./" style="text-decoration:none;color:white;;">OBS.Ninja</a>  
|
|
<div id="head1" style="display:inline-block">
|
|
<input id="StreamID" name="StreamID" size=30 placeholder="Join by Room Name here"></input>
|
|
<button style="padding:1px;" onclick="play(document.getElementById('StreamID').value)">GO</button>
|
|
</div>
|
|
<div id="head3" style="display:inline-block" class='advanced'>
|
|
<font style="font-size:60%">   Copy this URL into an OBS "Browser Source" =>   </font><a id="reshare" data-share="" onclick="var range=document.createRange(); range.selectNodeContents(document.getElementById('reshare')); var selec = window.getSelection(); selec.removeAllRanges();selec.addRange(range);document.execCommand('copy');" onmouseover="this.style.cursor='pointer'"></a>
|
|
</div>
|
|
|
|
<div id="head2" class="advanced" style="display:inline-block;text-decoration:none;font-size:60%;color:white;">
|
|
You are joining room: <div id="roomid" style="display:inline-block"></div>
|
|
</div>
|
|
|
|
</h2>
|
|
<hr />
|
|
</div>
|
|
|
|
<div id="mutebutton" onclick="toggleMute()" class='advanced float3' style="cursor:pointer" alt="Toggle the mic">
|
|
<i style="font-size:48px;color:white" id="mutetoggle" class="fa fa-microphone my-float"></i>
|
|
</div>
|
|
<div id="helpbutton" class='advanced float2' style="cursor:pointer" alt="How to Use This with OBS">
|
|
<i style="font-size:48px;color:white;" class="fa fa-question-circle my-float"></i>
|
|
</div>
|
|
|
|
<div id="mainmenu" class="row">
|
|
<div id="container-1" class="column columnfade" onclick="alert('coming soon');" style="background-color:#ddd;">
|
|
<h2>Add Group Video Chat to OBS</h2>
|
|
(Under Re-Development: coming soon)
|
|
<div class="container-inner">
|
|
</div>
|
|
<div class="outer close">
|
|
<div class="inner">
|
|
<label>Back</label>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="container-3" class="column columnfade" onclick="previewWebcam()" style="background-color:#ddd;">
|
|
<h2>Add your Camera to OBS</h2>
|
|
<div class="container-inner"><br />
|
|
<p>Select the audio/video source below and when you're ready just click START SHARING WEBCAM</p><br />
|
|
<button onclick="publishWebcam()" class="gowebcam">CLICK HERE WHEN READY</button><br />
|
|
<p><input id="videoname3" placeholder="Give this video source a name (optional)" size=35 maxlength=50 style="padding:5px;" /></br ><br /></p>
|
|
<p><video id="previewWebcam" muted controls autoplay playsinline style="max-width:640px; max-width:83vw; max-height:35vh"></video></p>
|
|
<br />
|
|
<p>Video source: <select id="videoSource"></select></p><br/>
|
|
<p>Audio source: <select id="audioSource"></select></p>
|
|
</div>
|
|
<div class="outer close">
|
|
<div class="inner">
|
|
<label>Back</label>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="container-2" class="column columnfade" style="background-color:#ddd;">
|
|
<h2>Remote Screenshare into OBS</h2>
|
|
<div class="container-inner">
|
|
<p><b>note</b>: Do not forget to click "Share audio" in Chrome.<br />(Firefox does not support audio sharing.)</p>
|
|
<p><img src="share.jpg" style="max-height:55vh"/></p>
|
|
<button onclick="publishScreen()" >SELECT SCREEN TO SHARE</button>
|
|
<p><input id="videoname2" placeholder="Give this video source a name (optional)" size=35 maxlength=70 style="padding:5px;" /></br ><br /></p>
|
|
</div>
|
|
<div class="outer close">
|
|
<div class="inner">
|
|
<label>Back</label>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
<p><div id="info" class="fullcolumn columnfade">
|
|
<center>
|
|
<div class="infoblob" align="left">
|
|
|
|
<h2>What is OBS.Ninja</h2><br />
|
|
<li>100% <b>free</b>; no downloads; no personal data collection; no sign-in</li>
|
|
<li>Bring video from your smartphone, laptop, computer, or from your friends directly into your OBS video stream</li>
|
|
<li>We use cutting edge Peer-to-Peer forwarding technology that offers privacy and ultra-low latency</li>
|
|
<br />
|
|
<li>Youtube video <a href="https://www.youtube.com/watch?v=6R_sQKxFAhg">Demoing it here</a></li>
|
|
<li>Code is open-sourced: <a href="https://github.com/steveseguin/obsninja">https://github.com/steveseguin/obsninja</a></li>
|
|
<li>You can also check out <a href="https://stageten.tv">StageTEN.tv</a> for a more feature-rich paid-solution</li>
|
|
<br />
|
|
<i>Known issues:</i><br />
|
|
|
|
<li>** MacOS users need to use OBS v23. v24/v25 have a bug in it</li>
|
|
|
|
<br /><br />
|
|
<i><h3>Send feature requests and support to steve@seguin.email, or check out the <a href="https://www.reddit.com/r/OBSNinja/">sub-reddit</a></i></h3>
|
|
|
|
</div>
|
|
</center>
|
|
</p></div>
|
|
<form method="post" onsubmit="setFormSubmitting()" style="display:none;">
|
|
<input type="submit" />
|
|
</form>
|
|
|
|
<script>
|
|
|
|
/////////////
|
|
var VIS = vis;
|
|
var formSubmitting = true;
|
|
var setFormSubmitting = function() { formSubmitting = true; };
|
|
window.onload = function() {
|
|
window.addEventListener("beforeunload", function (e) {
|
|
if (formSubmitting) {
|
|
return undefined;
|
|
}
|
|
|
|
var confirmationMessage = 'Leaving the page now will terminate your stream ';
|
|
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
|
|
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
|
|
});
|
|
};
|
|
|
|
var lastTouchEnd = 0;
|
|
document.addEventListener('touchend', function (event) {
|
|
var now = (new Date()).getTime();
|
|
if (now - lastTouchEnd <= 300) {
|
|
event.preventDefault();
|
|
}
|
|
lastTouchEnd = now;
|
|
}, false);
|
|
|
|
/////////////
|
|
var session = Ooblex.Media;
|
|
var micvolume = 100;
|
|
session.connect();
|
|
session.volume = micvolume;
|
|
|
|
function toggleMute(){
|
|
var msg = {};
|
|
if (micvolume==0){
|
|
micvolume = 100;
|
|
document.getElementById("mutetoggle").className="fa fa-microphone my-float";
|
|
document.getElementById("mutebutton").className="float3";
|
|
} else{
|
|
micvolume=0;
|
|
document.getElementById("mutetoggle").className="fa fa-microphone-slash my-float";
|
|
document.getElementById("mutebutton").className="float";
|
|
}
|
|
msg.volume = micvolume;
|
|
session.volume = micvolume;
|
|
session.sendMessage(msg);
|
|
}
|
|
|
|
function changeTitle(aTitle="Untitled"){
|
|
console.log("changing title; if connected at least");
|
|
session.changeTitle(aTitle);
|
|
}
|
|
|
|
var activatedStream = false;
|
|
function publishScreen(){
|
|
if( activatedStream == true){return;}
|
|
activatedStream = true;
|
|
|
|
var title = document.getElementById("videoname2").value;
|
|
|
|
formSubmitting = false;
|
|
session.publishScreen(title);
|
|
console.log("streamID is: "+session.streamID);
|
|
|
|
document.getElementById("mutebutton").className="float3";
|
|
document.getElementById("helpbutton").className="float2";
|
|
|
|
document.getElementById("head1").className = 'advanced';
|
|
document.getElementById("head2").className = 'advanced';
|
|
document.getElementById("head3").className = '';
|
|
|
|
}
|
|
function publishWebcam(){
|
|
if( activatedStream == true){return;}
|
|
activatedStream = true;
|
|
|
|
var title = document.getElementById("videoname3").value;
|
|
var ele = document.getElementById("previewWebcam");
|
|
ele.parentNode.removeChild(ele);
|
|
activatedPreview=true
|
|
var audioSelect = document.querySelector('select#audioSource');
|
|
var videoSelect = document.querySelector('select#videoSource');
|
|
|
|
var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
|
|
|
|
|
if (iOS){
|
|
var width1 = 640;
|
|
var height1 = 360;
|
|
if (urlParams.has('width')){
|
|
var width1 = urlParams.get('width');
|
|
}
|
|
if (urlParams.has('height')){
|
|
var height1 = urlParams.get('height');
|
|
}
|
|
var constraints = {
|
|
audio: {
|
|
deviceId: {exact: audioSelect.value}
|
|
},
|
|
video: {
|
|
width: {min: width1},
|
|
height: {min: height1},
|
|
deviceId: {exact: videoSelect.value}
|
|
}
|
|
};
|
|
|
|
} else {
|
|
var width1 = 360;
|
|
var height1 = 360;
|
|
if (urlParams.has('width')){
|
|
var width1 = urlParams.get('width');
|
|
}
|
|
if (urlParams.has('height')){
|
|
var height1 = urlParams.get('height');
|
|
}
|
|
|
|
var constraints = {
|
|
audio: {
|
|
deviceId: {exact: audioSelect.value}
|
|
},
|
|
video: {
|
|
height: {min: height1, max:2160},
|
|
width: {min: width1, max:3840},
|
|
deviceId: {exact: videoSelect.value}
|
|
}
|
|
};
|
|
};
|
|
formSubmitting = false;
|
|
session.publishWebcam(constraints, title);
|
|
console.log("streamID is: "+session.streamID);
|
|
document.getElementById("head1").className = 'advanced';
|
|
document.getElementById("head2").className = 'advanced';
|
|
document.getElementById("head3").className = '';
|
|
|
|
document.getElementById("mutebutton").className="float3";
|
|
document.getElementById("helpbutton").className="float2";
|
|
|
|
|
|
}
|
|
|
|
|
|
function gotDevices(deviceInfos) { // https://github.com/webrtc/samples/blob/gh-pages/src/content/devices/input-output/js/main.js#L19
|
|
const audioInputSelect = document.querySelector('select#audioSource');
|
|
const videoSelect = document.querySelector('select#videoSource');
|
|
const selectors = [audioInputSelect, videoSelect];
|
|
// TODO: Add in the option to select the OUTPUT and Disable Mic/Cam
|
|
|
|
// Handles being called several times to update labels. Preserve values.
|
|
const values = selectors.map(select => select.value);
|
|
selectors.forEach(select => {
|
|
while (select.firstChild) {
|
|
select.removeChild(select.firstChild);
|
|
}
|
|
});
|
|
for (let i = 0; i !== deviceInfos.length; ++i) {
|
|
const deviceInfo = deviceInfos[i];
|
|
const option = document.createElement('option');
|
|
option.value = deviceInfo.deviceId;
|
|
if (deviceInfo.kind === 'audioinput') {
|
|
option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
|
|
audioInputSelect.appendChild(option);
|
|
} else if (deviceInfo.kind === 'videoinput') {
|
|
option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
|
|
videoSelect.appendChild(option);
|
|
} else {
|
|
console.log('Some other kind of source/device: ', deviceInfo);
|
|
}
|
|
}
|
|
selectors.forEach((select, selectorIndex) => {
|
|
if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
|
|
select.value = values[selectorIndex];
|
|
}
|
|
});
|
|
}
|
|
|
|
function handleError(error) {
|
|
console.log('Error: ', error);
|
|
}
|
|
|
|
var activatedPreview = false;
|
|
function previewWebcam(){
|
|
if( activatedPreview == true){console.log("activeated preview return");return;}
|
|
activatedPreview=true;
|
|
var audioSelect = document.querySelector('select#audioSource');
|
|
var videoSelect = document.querySelector('select#videoSource');
|
|
|
|
var constraints = {audio:true, video:true };
|
|
|
|
navigator.mediaDevices.getUserMedia(constraints).then(function(){
|
|
navigator.mediaDevices.enumerateDevices().then(gotDevices).then(function(){
|
|
|
|
var audioSelect = document.querySelector('select#audioSource');
|
|
var videoSelect = document.querySelector('select#videoSource');
|
|
|
|
audioSelect.onchange = function(){activatedPreview=false;previewWebcam();};
|
|
videoSelect.onchange = function(){activatedPreview=false;previewWebcam();};
|
|
|
|
var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
|
|
|
|
|
if (iOS){
|
|
|
|
var width = 640;
|
|
var height = 360;
|
|
if (urlParams.has('width')){
|
|
var width = urlParams.get('width');
|
|
}
|
|
if (urlParams.has('height')){
|
|
var height = urlParams.get('height');
|
|
}
|
|
var constraints = {
|
|
audio: {
|
|
deviceId: {exact: audioSelect.value}
|
|
},
|
|
video: {
|
|
width: {ideal: width},
|
|
height: {ideal: height},
|
|
deviceId: {exact: videoSelect.value}
|
|
}
|
|
};
|
|
|
|
} else {
|
|
var width1 = 360;
|
|
var height1 = 360;
|
|
if (urlParams.has('width')){
|
|
var width1 = urlParams.get('width');
|
|
}
|
|
if (urlParams.has('height')){
|
|
var height1 = urlParams.get('height');
|
|
}
|
|
|
|
var constraints = {
|
|
audio: {
|
|
deviceId: {exact: audioSelect.value}
|
|
},
|
|
video: {
|
|
height: {min: height1, max:2160},
|
|
width: {min: width1, max:3840},
|
|
deviceId: {exact: videoSelect.value}
|
|
}
|
|
};
|
|
};
|
|
|
|
navigator.mediaDevices.getUserMedia(constraints).then(function(stream){
|
|
document.getElementById('previewWebcam').srcObject=stream;
|
|
}).catch(function(e){
|
|
console.log(e);
|
|
// alert("Something went wrong. Do you have a webcam installed?");
|
|
});
|
|
});
|
|
}).catch(handleError);
|
|
|
|
}
|
|
|
|
|
|
function checkOBS(){
|
|
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
|
|
console.log("enumerateDevices() not supported.");
|
|
return;
|
|
}
|
|
|
|
navigator.mediaDevices.enumerateDevices().then(function(devices) {
|
|
var matchFound = false;
|
|
devices.forEach(function(device) {
|
|
if (device.label.startsWith("OBS-Camera")){
|
|
alert("An OBS Virtual Camera was detected; Success!");
|
|
console.log(device.kind + ": " + device.label +
|
|
" id = " + device.deviceId);
|
|
matchFound = true;
|
|
|
|
}
|
|
console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
|
|
});
|
|
if (matchFound == false){
|
|
alert("No OBS Virtual Camera was found");
|
|
}
|
|
}).catch(function(err) {
|
|
console.log(err.name + ": " + err.message);
|
|
});
|
|
}
|
|
|
|
function play(streamName){
|
|
console.log("play stream");
|
|
session.watchStream(streamName);
|
|
}
|
|
function browse(){
|
|
console.log("browse streams");
|
|
session.listStreams().then(function(response){
|
|
document.getElementById("browserlist").innerHTML='No Active Broadcasts';
|
|
response.forEach(streamID => {
|
|
document.getElementById("browserlist").innerHTML="<a href='../?streamid="+streamID[1]+"'>"+streamID[2]+"</a> - "+streamID[0]+" seeders<br />";
|
|
});
|
|
},function(error){return {}});
|
|
}
|
|
|
|
function browsegraph(){
|
|
console.log("graph streams");
|
|
session.graphStreams().then(function(response){
|
|
// create an array with nodes
|
|
var nodes = [];
|
|
var edges = [];
|
|
for (var key in response){
|
|
if (response[key]==null){
|
|
edges.push({from:key, to:response[key]});
|
|
nodes.push({id:key,label:"PUBLISHER"});
|
|
continue;
|
|
} else if (key.length<=16){
|
|
edges.push({from:key, to:response[key]});
|
|
nodes.push({id:key,label:"SUPER SEEDER"});
|
|
continue;
|
|
}
|
|
nodes.push({id:key,label:"VIEWER"});
|
|
edges.push({from:key, to:response[key]});
|
|
};
|
|
// create a network
|
|
var container = document.getElementById('browsergraph');
|
|
|
|
// provide the data in the vis format
|
|
var data = {
|
|
nodes: nodes,
|
|
edges: edges
|
|
};
|
|
var options = {};
|
|
|
|
// initialize your network!
|
|
var network = new VIS.Network(container, data, options);
|
|
|
|
},function(error){return {}});
|
|
}
|
|
|
|
var urlParams = new URLSearchParams(window.location.search);
|
|
if (urlParams.has('streamid')){
|
|
|
|
document.getElementById("container-3").className = 'column columnfade';
|
|
document.getElementById("container-2").className = 'column columnfade';
|
|
document.getElementById("container-1").className = 'column columnfade';
|
|
document.getElementById("container-5").className = 'advanced';
|
|
//document.getElementById("header").className = 'advanced';
|
|
document.getElementById("info").className = 'advanced';
|
|
document.getElementById("header").className = 'advanced';
|
|
document.getElementById("head1").className = 'advanced';
|
|
document.getElementById("head2").className = 'advanced';
|
|
document.getElementById("head3").className = 'advanced';
|
|
document.getElementById("roomid").innerHTML = urlParams.get('streamid');
|
|
|
|
|
|
|
|
console.log("auto playing");
|
|
|
|
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1){
|
|
alert("Safari requires us to ask for an audio permission to use peer-to-peer technology. You will need to accept it in a moment if asked to view this live video");
|
|
navigator.mediaDevices.getUserMedia({audio: true}).then(function(){
|
|
play(urlParams.get('streamid'));
|
|
document.getElementById("mainmenu").style.display="none";
|
|
}).catch(function(){
|
|
play(urlParams.get('streamid'));
|
|
document.getElementById("mainmenu").style.display="none";
|
|
});
|
|
} else {
|
|
play(urlParams.get('streamid'));
|
|
//document.getElementById("mainmenu").style.display="none";
|
|
}
|
|
}
|
|
|
|
document.addEventListener("dragstart", e => {
|
|
var url = e.target.href || e.target.data;
|
|
if (!url || !url.startsWith('http')) return;
|
|
var streamId = url.split('=')[1];
|
|
url += '&layer-name=OBS.Ninja';
|
|
if (streamId) url += ': ' + streamId;
|
|
var video = document.getElementById('videosource');
|
|
url += '&layer-width=' + video.videoWidth;
|
|
url += '&layer-height=' + video.videoHeight;
|
|
e.dataTransfer.setData("text/uri-list", encodeURI(url));
|
|
});
|
|
|
|
var vis = (function(){
|
|
var stateKey, eventKey, keys = {
|
|
hidden: "visibilitychange",
|
|
webkitHidden: "webkitvisibilitychange",
|
|
mozHidden: "mozvisibilitychange",
|
|
msHidden: "msvisibilitychange"
|
|
};
|
|
for (stateKey in keys) {
|
|
if (stateKey in document) {
|
|
eventKey = keys[stateKey];
|
|
break;
|
|
}
|
|
}
|
|
return function(c) {
|
|
if (c) {
|
|
document.addEventListener(eventKey, c);
|
|
//document.addEventListener("blur", c);
|
|
//document.addEventListener("focus", c);
|
|
}
|
|
return !document[stateKey];
|
|
}
|
|
})();
|
|
|
|
function poker(){
|
|
try{
|
|
Notification.requestPermission().then(function(result) {
|
|
if (result === 'denied') {
|
|
console.log('Permission wasn\'t granted. Allow a retry.');
|
|
return;
|
|
}
|
|
if (result === 'default') {
|
|
console.log('The permission request was dismissed.');
|
|
return;
|
|
}
|
|
});
|
|
} catch (error) {
|
|
// Safari doesn't return a promise for requestPermissions and it
|
|
// throws a TypeError. It takes a callback as the first argument
|
|
// instead.
|
|
if (error instanceof TypeError) {
|
|
Notification.requestPermission(() => {
|
|
console.log("permissions was approved");
|
|
});
|
|
} else {
|
|
console.log("permission was denied");
|
|
throw error;
|
|
}
|
|
}
|
|
vis(function(){
|
|
if (!vis()){
|
|
alert("DONT MINIMIZE OR CHANGE TABS");
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
|
|
</script>
|
|
<script>
|
|
|
|
/* We need to create dynamic keyframes to show the animation from full-screen to normal. So we create a stylesheet in which we can insert CSS keyframe rules */
|
|
$("body").append('<style id="lightbox-animations" type="text/css"></style>');
|
|
|
|
/* Click on the container */
|
|
$(".column").on('click', function() {
|
|
/* The position of the container will be set to fixed, so set the top & left properties of the container */
|
|
|
|
var bounding_box = $(this).get(0).getBoundingClientRect();
|
|
$(this).css({ top: bounding_box.top + 'px', left: bounding_box.left -20+ 'px' });
|
|
|
|
/* Set container to fixed position. Add animation */
|
|
$(this).addClass('in-animation');
|
|
|
|
/* An empty container has to be added in place of the lightbox container so that the elements below don't come up
|
|
Dimensions of this empty container is the same as the original container */
|
|
$("#empty-container").remove();
|
|
$('<div id="empty-container" class="column"></div>').insertAfter(this);
|
|
|
|
/* To animate the container from full-screen to normal, we need dynamic keyframes */
|
|
var styles = '';
|
|
styles = '@keyframes outlightbox {';
|
|
styles += '0% {';
|
|
styles += 'height: 100%;';
|
|
styles += 'width: 100%;';
|
|
styles += 'top: 0px;';
|
|
styles += 'left: 0px;';
|
|
styles += '}';
|
|
styles += '50% {';
|
|
styles += 'height: 220px;';
|
|
styles += 'top: ' + bounding_box.y + 'px;';
|
|
styles += '}';
|
|
styles += '100% {';
|
|
styles += 'height: 220px;';
|
|
styles += 'width: '+bounding_box.width+'px;';
|
|
styles += 'top: ' + bounding_box.y + 'px;';
|
|
styles += 'left: ' + bounding_box.x + 'px;';
|
|
styles += '}';
|
|
styles += '}';
|
|
|
|
/* Add keyframe to CSS */
|
|
$("#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');
|
|
|
|
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');
|
|
|
|
e.stopPropagation();
|
|
});
|
|
|
|
/* On animationend : from normal to full screen & full screen to normal */
|
|
$(".column").on('animationend', function(e) {
|
|
/* On animation end from normal to full-screen */
|
|
if(e.originalEvent.animationName == 'inlightbox') {
|
|
$(this).children(".close").show();
|
|
$(this).children(".container-inner").show();
|
|
}
|
|
/* 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 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);
|
|
}
|
|
});
|
|
</script>
|
|
<div class='credits'>Icons made by <a href="https://www.flaticon.com/authors/lucy-g" title="Lucy G">Lucy G</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
|
|
</body>
|
|
|
|
|
|
</html>
|