mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-11 13:48:38 +00:00
336 lines
8.9 KiB
HTML
336 lines
8.9 KiB
HTML
<html>
|
|
<head><style>
|
|
html {
|
|
border:0;
|
|
margin:0;
|
|
outline:0;
|
|
|
|
}
|
|
|
|
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: #141926;
|
|
background-color: -webkit-linear-gradient(to top, #181925, #141826, #0F2027); /* Chrome 10-25, Safari 5.1-6 */
|
|
background-color: linear-gradient(to top, #181825, #141926, #0F2027); /* 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;
|
|
}
|
|
|
|
button{
|
|
padding:10px;
|
|
font-size: 20px;
|
|
margin: auto auto;
|
|
}
|
|
#header{
|
|
height:80px;
|
|
width:100%;
|
|
background-color: #101520;
|
|
}
|
|
.inputfield{
|
|
font-size: 20px;
|
|
align-self:center;
|
|
height:30px;
|
|
width:780px;
|
|
margin: auto auto;
|
|
padding:20px
|
|
}
|
|
|
|
.formcss{
|
|
font-size: 20px;
|
|
align-self:center;
|
|
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;
|
|
}
|
|
</style></head>
|
|
<body >
|
|
|
|
<div id="header" style="-webkit-app-region: drag;color:white;font-size:2em">OBS.Ninja</div>
|
|
<div class="formcss" >
|
|
|
|
<input type="checkbox" class="check" id="prefervp9" name="prefervp9" value="false" onclick="modURL(this);">
|
|
<label for="prefervp9">Force VP9 Codec</label>
|
|
|
|
<input type="checkbox" class="check" id="showcursor" name="showcursor" value="false" onclick="modURL(this);">
|
|
<label for="showcursor">Show Mouse Cursor</label>
|
|
|
|
<input type="checkbox" class="check" id="highbitrate" name="highbitrate" value="false" onclick="modURL(this);">
|
|
<label for="highbitrate">High Video Bitrate</label>
|
|
|
|
<input type="checkbox" class="check" id="stereo" name="stereo" value="false" onclick="modURL(this);">
|
|
<label for="stereo">Pro Audio Mode</label>
|
|
|
|
<input type="checkbox" class="check" id="buffer" name="buffer" value="false" onclick="modURL(this);">
|
|
<label for="buffer">Lip-sync Fix</label>
|
|
|
|
<br><br><br>
|
|
<div class="formcss"><center>
|
|
<input type="text" id="changeText" class="inputfield" value="http://obs.ninja/?view=" onchange="modURL" onkeyup="enterPressed(event, gohere);" />
|
|
<button onclick="gohere();" id="gobutton">GO</button>
|
|
<br><br>
|
|
<label for="audioOutput">Audio output destination: </label><select id="audioOutput" style="max-width:400px"></select>
|
|
|
|
</center></div>
|
|
</div>
|
|
|
|
|
|
<script>
|
|
/*
|
|
* Copyright (c) 2020 Steve Seguin. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by the APGLv3 open-source license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. Alternative licencing options can be made available on request.
|
|
*
|
|
*/
|
|
|
|
var audioOutputSelect = document.querySelector('select#audioOutput');
|
|
audioOutputSelect.disabled = !('sinkId' in HTMLMediaElement.prototype);
|
|
audioOutputSelect.onclick = getPermssions;
|
|
audioOutputSelect.onchange = updateOutputTarget;
|
|
var listed = false;
|
|
|
|
function updateOutputTarget(e){
|
|
console.log("change audio: "+audioOutputSelect.value);
|
|
var url = document.getElementById('changeText').value;
|
|
url=updateURLParameter(url, "sink", audioOutputSelect.value);
|
|
document.getElementById('changeText').value = url;
|
|
}
|
|
|
|
function getPermssions(e=null){
|
|
if (listed==true){
|
|
return;
|
|
}
|
|
if (e!==null){
|
|
e.currentTarget.blur();
|
|
}
|
|
navigator.mediaDevices.getUserMedia({audio: true,video: false}).then((stream)=>{
|
|
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(console.error); // list all devices
|
|
stream.getTracks().forEach(track => {
|
|
track.stop();
|
|
});
|
|
listed=true;
|
|
audioOutputSelect.focus();
|
|
|
|
}).catch(function(){alert("Failed to list available output devices\n\nPlease ensure you allowed the microphone permissions.");});
|
|
}
|
|
|
|
function gotDevices(deviceInfos) {
|
|
for (let i = 0; i !== deviceInfos.length; ++i) {
|
|
const deviceInfo = deviceInfos[i];
|
|
const option = document.createElement('option');
|
|
option.value = deviceInfo.deviceId;
|
|
if (deviceInfo.kind === 'audiooutput'){
|
|
option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
|
|
audioOutputSelect.appendChild(option);
|
|
} else {
|
|
console.log('Some other kind of source/device: ', deviceInfo);
|
|
}
|
|
}
|
|
listed=true;
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
(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);
|
|
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.
|
|
}
|
|
|
|
function updateURLParameter(url, param, paramVal){
|
|
var TheAnchor = null;
|
|
var newAdditionalURL = "";
|
|
var tempArray = url.split("?");
|
|
var baseURL = tempArray[0];
|
|
var additionalURL = tempArray[1];
|
|
var temp = "";
|
|
|
|
if (additionalURL){
|
|
var tmpAnchor = additionalURL.split("#");
|
|
var TheParams = tmpAnchor[0];
|
|
TheAnchor = tmpAnchor[1];
|
|
if (TheAnchor){additionalURL = TheParams;}
|
|
|
|
tempArray = additionalURL.split("&");
|
|
|
|
for (var i=0; i<tempArray.length; i++){
|
|
if(tempArray[i].split('=')[0] != param){
|
|
newAdditionalURL += temp + tempArray[i];
|
|
temp = "&";
|
|
}
|
|
}
|
|
} else {
|
|
var tmpAnchor = baseURL.split("#");
|
|
var TheParams = tmpAnchor[0];
|
|
TheAnchor = tmpAnchor[1];
|
|
|
|
if(TheParams){baseURL = TheParams;}
|
|
}
|
|
|
|
if (paramVal===false){
|
|
temp="";
|
|
if(TheAnchor){temp += "#" + TheAnchor;}
|
|
var rows_txt = temp
|
|
} else if (paramVal===""){
|
|
if(TheAnchor){paramVal += "#" + TheAnchor;}
|
|
var rows_txt = temp + "" + param;
|
|
} else {
|
|
if(TheAnchor){paramVal += "#" + TheAnchor;}
|
|
var rows_txt = temp + "" + param + "=" + paramVal;
|
|
}
|
|
return baseURL + "?" + newAdditionalURL + rows_txt;
|
|
}
|
|
|
|
if (urlParams.has('name')){
|
|
var name = urlParams.get('name');
|
|
if (name!="OBSNinja"){
|
|
document.getElementById('changeText').value = "https://obs.ninja/?view="+name;
|
|
}
|
|
}
|
|
|
|
function modURL(ele=false){
|
|
var url = document.getElementById('changeText').value;
|
|
console.log(url);
|
|
if ((url.split("view").length>0) || (url.split("room").length>0)){
|
|
if (!document.getElementById("showcursor").checked){
|
|
url=updateURLParameter(url, "nocursor", "");
|
|
} else {
|
|
url=updateURLParameter(url, "nocursor", false);
|
|
}
|
|
|
|
if (ele!=false){
|
|
if (ele.id =="prefervp9"){
|
|
if (document.getElementById("prefervp9").checked){
|
|
url=updateURLParameter(url, "codec", "vp9");
|
|
} else {
|
|
url=updateURLParameter(url, "codec", false);
|
|
}
|
|
}
|
|
|
|
if (ele.id =="highbitrate"){
|
|
if (document.getElementById("highbitrate").checked){
|
|
url=updateURLParameter(url, "bitrate", "10000");
|
|
} else {
|
|
url=updateURLParameter(url, "bitrate", false);
|
|
}
|
|
}
|
|
|
|
if (ele.id =="stereo"){
|
|
if (document.getElementById("stereo").checked){
|
|
url=updateURLParameter(url, "stereo", "");
|
|
alert('Audio bitrate increased to 256kbps.\n\nPlease note: the Video Publisher must also have the stereo flag enabled for stereo to work.');
|
|
} else {
|
|
url=updateURLParameter(url, "stereo", false);
|
|
}
|
|
}
|
|
|
|
if (ele.id =="buffer"){
|
|
if (document.getElementById("buffer").checked){
|
|
url=updateURLParameter(url, "buffer", "");
|
|
} else {
|
|
url=updateURLParameter(url, "buffer", false);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
document.getElementById('changeText').value = url;
|
|
console.log(url);
|
|
return url;
|
|
}
|
|
function gohere(){
|
|
var url = modURL(true);
|
|
window.location = url;
|
|
};
|
|
getPermssions();
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|