fix for obs remote

&remote=xxx should work again
scroll added to remote pop up; lots of scenes supported now
This commit is contained in:
Steve Seguin 2022-07-27 15:27:00 -04:00 committed by GitHub
parent a5c34cbbda
commit 10fa7e0a2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 137 additions and 32 deletions

View File

@ -2,7 +2,7 @@
<link rel="stylesheet" href="./main.css?ver=40" />
<style>
.container {
max-width: 80%;
max-width: min(80%,875px);
width: fit-content;
margin: 0 auto;
}
@ -13,6 +13,18 @@
padding: 10px;
}
a {
color: #00538c;
}
a:link {
color: #00538c;
}
a:visited {
color: #00538c;
}
.card {
margin: 10px;
box-shadow: 0 4px 8px 0 rgb(0 0 0 / 10%);
@ -85,31 +97,45 @@
<div id="info">
<h1>Web-based Media Conversion Tools</h1>
<div class="card">
<h2>WebM to MP4 (fixed 1280x720 resolution) <span class='warning'>(very slow!)</span></h2>
<h2>WebM (or MKV/FLV) to MP4 (fixed 1280x720 resolution) <span class='warning'>(very slow!)</span></h2>
<div>
<small>The same as: fmpeg -i input.webm -vf scale=1280:720 output.mp4</small>
<input type="file" id="uploader" title="Convert WebM to MP4">
<small>The same as: <i>fmpeg -i input.webm -vf scale="1280:720" output.mp4</i></small>
<input type="file" accept=".mkv, .flv, .webm" id="uploader" title="Convert WebM to MP4">
</div>
</div>
<div class="card">
<h2>WebM to MP4 files (no transcoding, attempts to force high resolutions)</h2>
<h2>WebM to MP4 files (no transcoding, *attempts* to force high resolutions)</h2>
<div>
<small>The same as: <i>ffmpeg.exe -i concat:"<a href='cap.webm' target="_blank">cap.webm</a>|input.webm" -safe 0 -c copy -avoid_negative_ts 1 -strict experimental output.mp4</i></small>
<input type="file" id="uploader3" accept=".webm" title="Convert WebM to MP4">
</div>
</div>
<div class="card">
<h2>WebM to Audio-only files (opus or wav)</h2>
<div>
<input type="file" id="uploader4" accept=".webm" title="Convert WebM to OPUS">
<small>The same as: <i>fmpeg -i input.webm -vn -acodec copy output.wav</i></small>
<input type="file" id="uploader4" accept=".webm" title="Convert WebM to OPUS (or WAV)">
</div>
</div>
<div class="card">
<h2>MKV (or FLV) to MP4 (no transcoding)</h2>
<h2>MKV (or FLV/WebM) to MP4 (no transcoding)</h2>
<div>
<small>The same as: fmpeg -i INPUTFILE -vcodec copy -acodec copy output.mp4</small>
<small>The same as: <i>fmpeg -i INPUTFILE -vcodec copy -acodec copy output.mp4</i></small>
<input type="file" id="uploader2" accept=".mkv, .flv, .webm" title="Convert MKV (or FLV) to MP4">
</div>
</div>
<div class="card">
<h2>Having problems?</h2>
<div>
For larger files, over 2-gigabytes in size, the browser may not be able to properly process the video in memory.
</div>
<div>
Please consider using FFmpeg <a href='https://ffmpeg.org/download.html' target="_blank">[get it free here]</a> to run these processes from the command-line instead. The corresponding commands are provided above, where you need to replace input.webm with your own file.
</div>
<div>
Other users who find FFmpeg too challenging have had luck using the graphical <a href="https://handbrake.fr/" target="_blank">Handbrake</a> application instead.
</div>
</div>
<div id="processing">
<span id="message"></span>
<video id="player" controls style="display:none"></video>
@ -126,6 +152,13 @@
<script src="./thirdparty/ffmpeg.min.js"></script>
<script>
window.onerror = function backupErr(errorMsg, url=false, lineNumber=false) {
console.error(errorMsg);
alert("An error occured.\n\nIf your file is larger than 2-GB, you may need to run the FFmpeg commands locally or use Handbrake instead.");
return false;
};
function download(data, filename) {
const blob = new Blob([data.buffer]);
const url = window.URL.createObjectURL(blob);
@ -146,6 +179,11 @@
const transcode = async ({ target: { files } }) => {
const { name } = files[0];
console.log(files[0]);
if (files[0].size>2147483648){
alert("Warning: The largest file size currently supported is 2-GB.\n\nFor larger files, please instead consider using the FFmpeg commands locally or use Handbrake. ");
return;
}
document.getElementById('uploader').style.display = "none";
document.getElementById('uploader2').style.display = "none";
document.getElementById('uploader3').style.display = "none";
@ -163,6 +201,10 @@
const transmux = async ({ target: { files } }) => {
const { name } = files[0];
if (files[0].size>2147483648){
alert("Warning: The largest file size currently supported is 2-GB.\n\nFor larger files, please instead consider using the FFmpeg commands locally or use Handbrake. ");
return;
}
document.getElementById('uploader').style.display = "none";
document.getElementById('uploader2').style.display = "none";
document.getElementById('uploader3').style.display = "none";
@ -181,6 +223,10 @@
const force1080 = async ({ target: { files } }) => {
const { name } = files[0];
if (files[0].size>2147483648){
alert("Warning: The largest file size currently supported is 2-GB.\n\nFor larger files, please instead consider using the FFmpeg commands locally or use Handbrake. ");
return;
}
const sourceBuffer = await fetch("./media/cap.webm").then(r => r.arrayBuffer());
document.getElementById('uploader').style.display = "none";
document.getElementById('uploader2').style.display = "none";
@ -202,6 +248,10 @@
const convertToAudioOnly = async ({ target: { files } }) => {
const { name } = files[0];
if (files[0].size>2147483648){
alert("Warning: The largest file size currently supported is 2-GB.\n\nFor larger files, please instead consider using the FFmpeg commands locally or use Handbrake. ");
return;
}
document.getElementById('message').innerText = "Transcoding file... this will take a while";
document.getElementById('processing').style.display = 'flex';
await ffmpeg.load();

View File

@ -82,7 +82,7 @@
<link itemprop="url" href="./media/vdoNinja_logo_full.png" />
</span>
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=37"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=486"></script>
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=487"></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">
@ -1936,7 +1936,7 @@
</div>
</div>
<div id="remoteOBSControl" class="customModelPopup" style="display:none; user-select: none;">
<div id="remoteOBSControl" class="customModelPopup" style="display:none;">
<div class="promptModalInner">
<span class='modalClose' onclick="toggleOBSControls();">×</span>
<span></span>
@ -2136,7 +2136,7 @@
var session = WebRTC.Media; // session is a required global variable if configuring manually. Run before loading main.js but after webrtc.js.
session.version = "22.1b";
session.version = "22.3🇺🇦";
session.streamID = session.generateStreamID(); // randomly generates a streamID for this session. You can set your own programmatically if needed
session.defaultPassword = "someEncryptionKey123"; // Change this password if self-deploying for added security/privacy
@ -2208,11 +2208,11 @@
// session.defaultBackgroundImages = ["./media/bg_sample1.webp", "./media/bg_sample2.webp"]; // for &effects=5 (virtual backgrounds)
</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=377"></script>
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=381"></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=389"></script>
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=390"></script>
</body>
</html>

71
lib.js
View File

@ -1262,8 +1262,6 @@ function toggleOBSControls(){
} else {
getById("modalBackdrop").innerHTML = ''; // Delete modal
getById("modalBackdrop").remove();
zindex = 25;
getById('remoteOBSControl').style.zIndex = 25;
var modalTemplate = `<div id="modalBackdrop" style="z-index:24"></div>`;
document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end
document.getElementById("modalBackdrop").addEventListener("click", toggleOBSControls);
@ -1551,10 +1549,10 @@ function manageSceneState(data, UUID){ // incoming obs details
if (session.pcs[UUID].obsState.virtualcam){
controlButton.classList.add("pressed");
controlButton.dataset.obsAction = "stopVirtualcam";
controlButton.innerText = "💻 stop virtual cam";
controlButton.innerText = "💻 stop virtualcam";
} else {
controlButton.dataset.obsAction = "startVirtualcam";
controlButton.innerText = "💻 start virtual cam";
controlButton.innerText = "💻 start virtualcam";
}
if (control<5){
@ -1654,6 +1652,7 @@ function processOBSCommand(msg){
if (msg.UUID && msg.obsCommand.action){
var data = {}
data.rejected = "obsCommand";
//data.debug = msg.remote;
session.sendRequest(data, msg.UUID); // this skips the server
}
warnlog("Denied access; remote does not match");
@ -1663,6 +1662,7 @@ function processOBSCommand(msg){
if (msg.UUID && msg.obsCommand.action){
var data = {}
data.rejected = "obsCommand";
//data.debug = "no remote code provided";
session.sendRequest(data, msg.UUID); // this skips the server
}
return false;
@ -5364,12 +5364,47 @@ async function tapToFocus(x,y, force=false){
sharpnessToolActive = false;
}
session.remoteZoom = function(zoom){
try {
var track0 = session.streamSrc.getVideoTracks();
track0 = track0[0];
if (track0.getCapabilities){
var capabilities = track0.getCapabilities();
if (!capabilities.zoom){
warnlog("No zoom supported on this device");
return;
}
if (session.zoom==false){
session.zoom = capabilities.zoom.min;
}
session.zoom+=zoom;
if (session.zoom>capabilities.zoom.max){
session.zoom = capabilities.zoom.max;
} else if (session.zoom<capabilities.zoom.min){
session.zoom = capabilities.zoom.min;
}
//updateCameraConstraints("zoom", session.zoom); // TODO: I should align the remote zoom and focus with the local one.
track0.applyConstraints({advanced: [ {zoom: session.zoom} ]});
}
} catch(e){
errorlog(e);
}
};
session.remoteFocus = async function(focusDistance){
try {
var track0 = session.streamSrc.getVideoTracks();
track0 = track0[0];
if (track0.getCapabilities){
var capabilities = track0.getCapabilities();
if (!capabilities.focusDistance){
warnlog("No Focus supported on this device");
return;
} else if (!("min" in capabilities.focusDistance)){
return;
}
if (session.focusDistance==false){
session.focusDistance = capabilities.focusDistance.min;
}
@ -5769,6 +5804,7 @@ async function makeImages(startup=false){
var width = 480;
var height = 270;
var timeout = 100; // the answer to everything.
var quality = 0.66;
if (session.webPquality===0){
width = 1920;
@ -5779,21 +5815,21 @@ async function makeImages(startup=false){
height = 720;
timeout = 33;
} else if (session.webPquality===2){
width = 640;
height = 360;
width = 960;
height = 540;
timeout = 33;
} else if (session.webPquality===3){
width = 480;
height = 270;
width = 640;
height = 360;
timeout = 33;
} else if (session.webPquality===4){
width = 480;
height = 270;
timeout = 67;
timeout = 33;
} else if (session.webPquality===5){
width = 480;
height = 270;
timeout = 100;
timeout = 67;
} else if (session.webPquality===6){
width = 480;
height = 270;
@ -5810,6 +5846,7 @@ async function makeImages(startup=false){
session.webPcanvas.width = width;
session.webPcanvas.height = height;
session.webPcanvas.timeout = timeout;
session.webPcanvas.quality = quality;
session.webPcanvasCtx = session.webPcanvas.getContext('2d', {alpha: false, desynchronized: true});
session.webPcanvasCtx.fillStyle = "black";
session.webPcanvasCtx.fillRect(0, 0, width, height);
@ -5859,7 +5896,7 @@ async function makeImages(startup=false){
if (!session.pcs[i].sendChannel.bufferedAmount){
if (!arrayBuffer){
session.webPcanvasCtx.drawImage(session.videoElement, 0, 0, session.webPcanvas.width, session.webPcanvas.height);
arrayBuffer = dataURItoArraybuffer(session.webPcanvas.toDataURL("image/"+session.webp, 0.6));
arrayBuffer = dataURItoArraybuffer(session.webPcanvas.toDataURL("image/"+session.webp, session.webPcanvas.quality));
}
session.pcs[i].sendChannel.send(arrayBuffer);
}
@ -8186,16 +8223,16 @@ function updateLocalStats(){
if (stat.type == "transport"){
if ("bytesSent" in stat) {
if ("_bytesSent" in session.pcs[UUID].stats){
if (session.pcs[UUID].stats._timestamp){
if (session.pcs[UUID].stats._timestamp3){
if (stat.timestamp){
session.pcs[UUID].stats.total_sending_bitrate_kbps = parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSent)/(stat.timestamp - session.pcs[UUID].stats._timestamp));
session.pcs[UUID].stats.total_sending_bitrate_kbps = parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSent)/(stat.timestamp - session.pcs[UUID].stats._timestamp3));
}
}
}
session.pcs[UUID].stats._bytesSent = stat.bytesSent;
}
if ("timestamp" in stat) {
session.pcs[UUID].stats._timestamp = stat.timestamp;
session.pcs[UUID].stats._timestamp3 = stat.timestamp;
}
} else if (stat.type == "outbound-rtp") {
if (stat.kind == "video") {
@ -8211,9 +8248,9 @@ function updateLocalStats(){
lastFramesEncoded = session.pcs[UUID].stats._framesEncoded;
lastTimestamp = session.pcs[UUID].stats._timestamp;
} catch(e){}
session.pcs[UUID].stats._FPS = parseInt(10*(stat.framesEncoded - lastFramesEncoded)/(stat.timestamp/1000 - lastTimestamp))/10;
session.pcs[UUID].stats._FPS = parseInt(10*(stat.framesEncoded - lastFramesEncoded)/(stat.timestamp - lastTimestamp))/10;
session.pcs[UUID].stats._framesEncoded = stat.framesEncoded;
session.pcs[UUID].stats._timestamp = stat.timestamp/1000;
session.pcs[UUID].stats._timestamp = stat.timestamp;
session.pcs[UUID].stats.resolution = stat.frameWidth + " x " + stat.frameHeight + " @ " + session.pcs[UUID].stats._FPS;
} else {
session.pcs[UUID].stats.resolution = stat.frameWidth + " x " + stat.frameHeight;
@ -8253,8 +8290,8 @@ function updateLocalStats(){
if ("bytesSent" in stat) {
if ("_bytesSentVideo" in session.pcs[UUID].stats){
if (session.pcs[UUID].stats._timestamp1){
session.pcs[UUID].stats.video_bitrate_kbps = parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSentVideo)/(stat.timestamp - session.pcs[UUID].stats._timestamp1));
if (stat.timestamp){
session.pcs[UUID].stats.video_bitrate_kbps = parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSentVideo)/(stat.timestamp - session.pcs[UUID].stats._timestamp1));
}
}
}

View File

@ -3531,6 +3531,12 @@ input:checked + .slider:before {
-ms-transform: translateX(16px);
transform: translateX(16px);
}
#remoteOBSControl {
user-select: none;
z-index: 25;
max-height: calc(100vh - 116px);
overflow-y: auto;
}
#remoteOBSControl button {
margin:5px;

14
main.js
View File

@ -882,8 +882,19 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
}
if (urlParams.has('fakeuser')) {
log("ICE FILTER ENABLED");
session.fakeUser = true;
session.dataMode = true;
session.autostart = true;
}
if (urlParams.has('datamode') || urlParams.has('dataonly')) { // this disables all media in/out.
session.dataMode = true;
}
if (session.dataMode){
session.cleanOutput=true;
session.videoDevice = 0;
session.audioDevice = 0;
@ -892,7 +903,6 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.noaudio = [];
session.noiframe = [];
//session.webcamonly = true;
session.dataMode = true;
}
@ -2736,6 +2746,8 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
session.icefilter = urlParams.get('icefilter');
}
//if (!(ChromeVersion>=57)){
// getById("effectSelector").disabled=true;
// getById("effectSelector3").disabled=true;

File diff suppressed because one or more lines are too long