sync with alpha; bug fixes; whip/whep sorta working

This commit is contained in:
steveseguin 2023-03-19 21:47:16 -04:00
parent 2b0db54eb9
commit 43e577d25e
7 changed files with 2214 additions and 544 deletions

View File

@ -56,7 +56,7 @@
<meta property="twitter:image" content="./media/vdoNinja_logo_full.png" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<link rel="stylesheet" href="./main.css?ver=271" />
<link rel="stylesheet" href="./main.css?ver=272" />
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.js"></script>
<style id="lightbox-animations" type="text/css"></style>
<!-- <link rel="manifest" href="manifest.json" /> -->
@ -83,7 +83,7 @@
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=45"></script>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=581"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=587"></script>
<input id="zoomSlider" type="range" style="display: none;" />
<span id="electronDragZone" style="pointer-events: none; z-index:-10; position:absolute;top:0;left:0;width:100%;height:2%;-webkit-app-region: drag;min-height:20px;"></span>
<div id="header">
@ -228,28 +228,34 @@
</div>
</div>
</div>
<span
id="reportbutton"
title="Submit any error logs"
onclick="submitDebugLog();"
style="cursor: pointer; visibility: hidden; display:none;z-index:3;"
>
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 55px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-bug" aria-hidden="true"></i>
</span>
<span
id="helpbutton"
title="Show Help Info"
onclick="warnUser('For support, please browse https://reddit.com/r/vdoninja or join the live chat on Discord at https://discord.vdo.ninja.\n\nThe Docs also contains many help guides and advanced settings, located at https://docs.vdo.ninja.\n\nTo access the video stats menu, hold CTRL (command) and Left-Click on a video. Most video issues can be fixed by using Wired Internet instead of Wi-Fi.')"
style="cursor: pointer; display:none;"
alt="How to Use This with OBS"
>
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 33px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-question-circle" aria-hidden="true"></i>
</span>
<span title="Language Options" onclick="toggle(document.getElementById('languages'));" aria-label="language options" aria-pressed="false" id="translateButton">
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 10px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-language" aria-hidden="true"></i>
</span>
<span title="Add to Calendar" onclick="toggle(document.getElementById('calendar'));" id="calendarButton">
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 33px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-calendar" aria-hidden="true"></i>
<span id="miniTaskBar" style="float: right; bottom: 0px;right:0; position:fixed; display:flex;">
<div id="closedList_connectUsers" class="hidden" onclick="getById('connectUsers').classList.remove('hidden');getById('closedList_connectUsers').classList.add('hidden');">
<i class="las la-theater-masks"></i>
</div>
<span
id="reportbutton"
title="Submit any error logs"
onclick="submitDebugLog();"
style="cursor: pointer; display:none;z-index:3;"
class="hidden"
>
<i style="cursor: pointer; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-bug" aria-hidden="true"></i>
</span>
<span
id="helpbutton"
title="Show Help Info"
onclick="warnUser('For support, please browse https://reddit.com/r/vdoninja or join the live chat on Discord at https://discord.vdo.ninja.\n\nThe Docs also contains many help guides and advanced settings, located at https://docs.vdo.ninja.\n\nTo access the video stats menu, hold CTRL (command) and Left-Click on a video. Most video issues can be fixed by using Wired Internet instead of Wi-Fi.')"
style="cursor: pointer; display:none;"
alt="How to Use This with OBS"
>
<i style="cursor: pointer; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-question-circle" aria-hidden="true"></i>
</span>
<span title="Language Options" onclick="toggle(document.getElementById('languages'));" aria-label="language options" aria-pressed="false" id="translateButton">
<i style="cursor: pointer;color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-language" aria-hidden="true"></i>
</span>
<span title="Add to Calendar" onclick="toggle(document.getElementById('calendar'));" id="calendarButton">
<i style="cursor: pointer; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-calendar" aria-hidden="true"></i>
</span>
</span>
<div id="mainmenu" class="row" style="opacity: 0;">
@ -327,14 +333,15 @@
<b>
<span data-translate="default-codec-select" title="Which video codec would you want used by default?" >Preferred Video Codec: </span>
<select style="font-size:1.1em" id="codecGroupFlag" type="checkbox" title="For large group rooms, this option can reduce the load on remote guests substantially" >
<option value="default" selected>Default</option>
<option value="vp9">VP9</option>
<option value="h264">H264</option>
<option value="vp8">VP8</option>
<option value="av1">AV1</option>
</select >
<option value="default" selected>Default</option>
<option value="vp9">VP9</option>
<option value="h264">H264</option>
<option value="vp8">VP8</option>
<option value="av1">AV1</option>
</select >
</b>
</th>
</th>
</tr>
</table>
@ -2233,11 +2240,12 @@
<div id="connectUsers">
<div style="margin-bottom:5px"><u ><span data-translate="invisible-guests">Not Visible</span></u>
<span title="Hide this window" id='hideusers' style="cursor:pointer;font-size:1.2em; float: right;" onclick="session.showList=false;getById('connectUsers').style.display = 'none';"><i class="las la-times"></i></span></div>
<span title="Hide this window" id='hideusers' style="cursor:pointer;font-size:1.2em; float: right;" onclick="getById('connectUsers').classList.add('hidden');getById('closedList_connectUsers').classList.remove('hidden');"><i class="las la-times"></i></span></div>
<span style="height:5px;display:block;"></span>
<div id="userList">
</div>
</div>
<div id="signalMeterTemplate" class="signal-meter hidden" data-cpu="0" data-level="0">
<i class="las la-signal"></i>
<i class="las la-fire-alt"></i>
@ -2338,7 +2346,11 @@
</u>
</div>
<span class="hidden" id="hangupTemplate">
<span style='font-size:500%;text-align:center;margin:auto;'><a href="." title="Go to the homepage">👋</a></span>
<span style='font-size:500%;text-align:center;margin:auto;'>👋</span>
</span>
<span class="hidden" id="hangupTemplateMobileFullscreen">
<span style='font-size:500%;text-align:center;margin:auto;'>👋<br ><a onclick="history.go(0);" title="Reload the page" data-translate="reload-page">Reload Page</a>
</span>
</span>
<div id="meshcastMenu" class="hidden">
Meshcast publishing region: <select name="edgelist" id="edgelist" onchange="selectMeshcast(this);" title="Select a location that is closest to both you and your audience."></select>
@ -2468,11 +2480,11 @@
// session.hidehome = true; // If used, 'hide home' will make the landing page inaccessible, along with hiding a few go-home elements.
// session.record = false; // uncomment to block users from being able to record via vdo.ninja's built in recording function
</script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=673"></script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=696"></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=552"></script>
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=569"></script>
</body>
</html>

2065
lib.js

File diff suppressed because it is too large Load Diff

View File

@ -3934,8 +3934,40 @@ a#reshare {
padding: 2.2px 1.5px 2px 2px;
margin: 0 0 0 5px;
}
.volume-control-userlist {
display:inline-block;
color:white;
border-radius: 2vh;
background-color:#262c3e;
padding: 2.2px 1.5px 2px 2px;
margin: 0 0 0 5px;
cursor: pointer;
border: 1px solid #9a9393;
}
.volume-control-userlist input[type=range][orient=vertical] {
display: block;
color: white;
border-radius: 2vh;
-webkit-appearance: slider-vertical;
background-color: #262c3e;
cursor: pointer;
width: 13px;
margin: 3px 0;
}
#closedList_connectUsers{
cursor: pointer;
color: #d9e4eb;
padding: 2px;
margin: 2px 2px 0 0;
font-size: 140%;
}
.screenshareNotActive{
opacity: 0.5;
box-shadow: inset 0 0 50px #290f07;
}
#help_directors_room{
cursor:pointer;
}
@ -4675,6 +4707,8 @@ input:checked + .slider:before {
content: "\f023"; }
.la-lock-open:before {
content: "\f3c1"; }
.la-theater-masks:before {
content: "\f630"; }
body.darktheme {
color: white;

111
main.js
View File

@ -47,14 +47,19 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
if (location.hostname === "rtc.ninja"){
try {
if (session.label === false) {
document.title = "";
}
document.title = "RTC.Ninja";
}
getById("qos").innerHTML = "";
getById("logoname").innerHTML = "";
getById("helpbutton").style.display = "none";
getById("helpbutton").style.opacity = 0;
getById("reportbutton").style.display = "none";
getById("reportbutton").style.opacity = 0;
getById("dropButton").classList.add("hidden");
getById("container-4").classList.add("hidden");
if (!(urlParams.has('screenshare') || urlParams.has('ss'))){
getById("container-2").classList.add("hidden");
}
//getById("mainmenu").style.opacity = 1;
getById("mainmenu").style.margin = "30px 0";
getById("translateButton").style.display = "none";
@ -63,15 +68,15 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
getById("info").style.opacity = 0;
getById("chatBody").innerHTML = "";
} catch (e) {}
} else if (session.label === false) {
document.title = location.hostname;
}
try {
if (ln_template===false){
changeLg("blank");
}
//getById("mainmenu").style.opacity = 1;
if (session.label === false) {
document.title = location.hostname;
}
getById("qos").innerHTML = '<i class="las la-plug"></i>'
getById("logoname").innerHTML = getById("qos").outerHTML;
getById("helpbutton").style.display = "none";
@ -276,6 +281,53 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
}
if (urlParams.has('whip') || urlParams.has('whipview')) {
session.whipView = urlParams.get('whip') || urlParams.get('whipview') || false;
if (session.whipView){
setTimeout(function(){whipClient();},1000);
}
}
if (urlParams.has('whippush')) { // 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('whippush')){
try {
session.whipOutput = decodeURIComponent(urlParams.get('whippush'));
} catch(e){
errorlog(e);
}
}
}
if (urlParams.has('whippushtoken')) { // 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('whippushtoken')){
try {
session.whipOutputToken = urlParams.get('whippushtoken');
} catch(e){
errorlog(e);
}
}
}
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
if (urlParams.get('whepplay')){
try {
session.whepInput = decodeURIComponent(urlParams.get('whepplay'));
if (session.whepInput){
setTimeout(function(){whepIn();},1000);
}
} catch(e){
errorlog(e);
}
}
}
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;
}
@ -400,9 +452,9 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.showList = true;
}
}
if (session.showList===true){
getById("hideusers").classList.add("hidden");
}
//if (session.showList===true){
// getById("hideusers").classList.add("hidden");
//}
if (urlParams.has('meshcast')) {
session.meshcast = urlParams.get('meshcast') || "any";
@ -496,6 +548,10 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
});
getById("rooms").classList.remove('hidden');
}
if (urlParams.has('leaveorientationflag')) {
session.removeOrientationFlag = false; // leave `a=extmap:3 urn:3gpp:video-orientation\r\n` alone
}
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.
@ -2536,18 +2592,32 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.screenshareContentHint = urlParams.get('screensharecontenthint') || urlParams.get('sscontenthint') || urlParams.get('screensharecontenttype') || urlParams.get('sscontent') || urlParams.get('sshint') || "detail";
}
if (urlParams.has('codec')) {
log("CODEC CHANGED");
session.codec = urlParams.get('codec') || false;
if (session.codec){
session.codec = session.codec.toLowerCase();
if (urlParams.has('codec') || urlParams.has('codecs') || urlParams.has('videocodec')) {
log("codecs CHANGED");
session.codecs = urlParams.get('codec') || urlParams.get('codecs') || urlParams.get('videocodec') || false;
if (session.codecs){
session.codecs = session.codecs.toLowerCase();
session.codecs = session.codecs.split(",");
if (session.codecs.length){
session.codec = session.codecs.shift();
if (!session.codec){
session.codec = false;
session.codecs = false;
}
if (!session.codecs.length){
session.codecs = false;
}
} else {
session.codecs = false;
}
}
} else if (OperaGx){
session.codec = "vp8";
warnlog("Defaulting to VP8 manually, as H264 with remote iOS devices is not supported");
}
if (urlParams.has('audiocodec')) {
log("CODEC CHANGED");
session.audioCodec = urlParams.get('audiocodec') || false;
@ -3596,12 +3666,17 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
}
if (urlParams.has('whip')) {
session.whip = urlParams.get('whip') || false;
if (session.whip){
setTimeout(function(){whipClient();},1000); // OBS v29 required?
if (urlParams.has('postapi') || urlParams.has('posturl')) {
session.postApi = urlParams.get('postapi') || urlParams.get('posturl') || false; // ie: &postapi=https%3A%2F%2Fwebhook.site%2Fb190f5bf-e4f8-454a-bd51-78b5807df9c1
if (session.postApi){
try {
session.postApi = decodeURI(session.postApi) || session.postApi ; // needs to be SSL enabled.
} catch(e){
console.error(e);
}
}
}
if (urlParams.has('queue')) {
session.queue = true;

View File

@ -2458,6 +2458,28 @@
}
}
if (e.data.action === "layout-index"){
if ("value" in e.data){
var idx = parseInt(e.data.value) || 0;
if (!idx){
var ele = document.getElementById("automix");
} else {
var ele = document.querySelectorAll("#containermenu .canvasContainer")[idx-1];
}
var layoutButtons = document.querySelectorAll(".pressed");
for (var i = 0;i<layoutButtons.length;i++){
layoutButtons[i].classList.remove("pressed");
}
if (ele){
ele.classList.add("pressed");
ele.classList.add("shake");
setTimeout(function(ele){ele.classList.remove("shake");},500,ele);
}
}
}
if (e.data.action && (e.data.action == "scene-connected")){
if (lastLayout && lastLayout.scene == e.data.value){
@ -2913,6 +2935,7 @@
container.classList.add("inline");
//container.classList.add("canvasContainer");
container.appendChild(canvas);
container.id = "automix"
document.getElementById("containermenu").appendChild(container);
ctx.beginPath();
ctx.rect(0, 0, 80, 45);

File diff suppressed because one or more lines are too long

441
whip.html Normal file
View File

@ -0,0 +1,441 @@
<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;">WHIP / WHEP simple sample setup</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 to a WHIP ingestion end-point</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="WHIP Publishing URL" " />
<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)" />
<div class="details">⚙️</div>
</div>
</div>
<div id="urlInput2" class="urlInput"title="Put the WHIP token you want to listen for">
<h3>Setup VDO.Ninja to be a WHIP-ingestion end-point</h3>
<div class="inputCombo" id="inputCombo2">
<label for="changeText">
<i class="las la-play"></i>
</label>
<input type="text" id="changeText2" class="inputfield changeText" placeholder="Ingest WHIP token" />
<button onclick="gohere2();" class="gobutton" id="gobutton2">GO</button>
</div>
</div>
<div id="urlInput3" class="urlInput"title="Put the link you want to play here">
<h3>Play a remote video stream available via WHEP</h3>
<div class="inputCombo" id="inputCombo3">
<label for="changeText">
<i class="las la-play"></i>
</label>
<input type="text" id="changeText3" class="inputfield changeText" placeholder="WHEP Play URL" />
<button onclick="gohere3();" class="gobutton" id="gobutton3">GO</button>
</div>
</div>
<div id="urlInput4" style="display:none;" class="urlInput" title="Put the link you want to load here">
<div class="inputCombo" id="inputCombo4">
<label for="changeText">
<i class="las la-broadcast-tower"></i>
</label>
<input type="text" id="changeText4" class="inputfield changeText" placeholder="WHEP Enabled Publishing Link" />
<button onclick="gohere4();" class="gobutton" id="gobutton4">GO</button>
</div>
</div>
<div id="history" title="History of past links used. You can clear this history using the button to the left">
<label for="lastUrls" onclick="resetHistory()">
<i class="las la-history"></i>
</label>
</div>
</div>
<script>
var domain = "./";
document.querySelector("#changeText1").value = localStorage.getItem('changeText1') || "";
document.querySelector("#changeText1a").value = localStorage.getItem('changeText1a') || "";
document.querySelector("#changeText2").value = localStorage.getItem('changeText2') || "";
document.querySelector("#changeText3").value = localStorage.getItem('changeText3') || "";
function gohere1(){
if (document.getElementById('changeText1').value && document.getElementById('changeText1a').value){
localStorage.setItem('changeText1', document.getElementById('changeText1').value);
localStorage.setItem('changeText1a', document.getElementById('changeText1a').value);
window.location = domain + "?whippush=" + encodeURIComponent(document.getElementById('changeText1').value) + "&whippushtoken=" + document.getElementById('changeText1a').value;
} else if (document.getElementById('changeText1').value){
localStorage.setItem('changeText1', document.getElementById('changeText1').value);
localStorage.setItem('changeText1a', "");
window.location = domain + "?wc&whippush=" + encodeURIComponent(document.getElementById('changeText1').value);
}
}
function gohere2(){
if (document.getElementById('changeText2').value){
localStorage.setItem('changeText2', document.getElementById('changeText1').value);
window.location = domain + "?hidemenu&whip=" + document.getElementById('changeText1').value;
}
}
function gohere3(){
if (document.getElementById('changeText3').value){
localStorage.setItem('changeText3', document.getElementById('changeText3').value);
window.location = domain + "?&hidemenu&whepplay=" + encodeURIComponent(document.getElementById('changeText3').value);
}
}
function gohere4(){
// nothing yet
}
function resetHistory(){
localStorage.clear();
document.querySelector("#changeText1").value = "";
document.querySelector("#changeText1a").value = "";
document.querySelector("#changeText2").value = "";
document.querySelector("#changeText3").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>