Skip to content

Commit

Permalink
add stable vmm version
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexFreik committed Nov 28, 2024
1 parent 5aeadf4 commit d85c863
Show file tree
Hide file tree
Showing 17 changed files with 9,942 additions and 0 deletions.
2,572 changes: 2,572 additions & 0 deletions vmix-master-stable/Sortable.min.js

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions vmix-master-stable/box.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function updateBoxNums() {
let cnt = 1;
Array.from(document.getElementsByClassName('box')).forEach((box) => {
box.querySelector('.badge').innerHTML = String(cnt++);
});
}

function closeBox(e) {
const box = e.currentTarget.parentElement.parentElement;
box.parentNode.removeChild(box);
updateBoxNums();
updateUrlParams();
}

function createBox(name, host, num) {
const box = document.createElement('div');
box.className = 'box m-1 h-[200px] w-[350px]';
box.innerHTML = `
<div class="flex gap-1 items-center my-1">
<span class="box-number badge badge-neutral cursor-grab w-7">${num}</span>
<input type="text" placeholder="Name" value="${name}" class="name-input input input-bordered input-xs w-24">
<input type="text" placeholder="Host" value="${host}" class="host-input input input-xs input-bordered flex-1 min-w-5">
<button class="close-btn btn btn-xs btn-error btn-outline w-[24px] p-0">
<svg class="fill-current w-4 h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>
</button>
</div>
<div class="container relative max-w-full h-[150px] overflow-y-scroll rounded-lg border border-secondary bg-base-200 px-1">
<div class="vmixInfo text-sm m-1 wrap"></div>
</div>
`;

box.querySelector('.name-input').onblur = updateUrlParams;
box.querySelector('.host-input').onblur = updateUrlParams;
box.querySelector('.close-btn').onclick = closeBox;

return box;
}
99 changes: 99 additions & 0 deletions vmix-master-stable/custom-functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
function customExecution(request) {
const include = parseNumbers(document.getElementById('include').value);
getBoxes()
.filter((box) => include.includes(getBoxNumber(box)))
.forEach((box) => execute(getApiUrl(getBoxHost(box), request)));
}

function renderCustomFunctions() {
const input = {
name: 'input',
type: 'text',
placeholder: 'Input',
value: '',
width: 'w-14',
};
const volume = {
name: 'volume',
type: 'number',
placeholder: '0-100',
value: '100',
width: 'w-16',
min: '0',
max: '100',
};
const ms = {
name: 'ms',
type: 'text',
placeholder: 'ms',
value: '3000',
width: 'w-14',
};

const buttons = [
{ func: 'StartExternal', inputs: [] },
{ func: 'StopExternal', inputs: [] },
{ func: 'FadeToBlack', inputs: [] },
{ func: 'SetVolumeFade', inputs: [volume, ms, input] },
{ func: 'Fade', inputs: [input] },
{ func: 'Stinger1', inputs: [input] },
{ func: 'AudioOn', inputs: [input] },
{ func: 'AudioOff', inputs: [input] },
];

let innerHTML = '';
buttons.forEach((b) => {
innerHTML += `
<div class="m-1 w-fit rounded-box bg-neutral p-3">
<div class="mx-auto w-fit">
${
b.inputs.length === 0
? '&nbsp;'
: b.inputs
.map(
(input) => `
<input
type="${input.type}"
placeholder="${input.placeholder}"
name: "${input.name}"
class="${input.name}-param input input-xs input-bordered ${input.width}"
value="${input.value}"
min="${input.min}"
max="${input.max}" />`,
)
.join('')
}
</div>
<div class="mx-auto w-fit">
<button class="function-btn btn btn-outline btn-secondary btn-sm mt-1">${b.func}</button>
</div>
</div>`;
});

document.querySelector('.custom-functions-container').innerHTML += innerHTML;

const executeBtn = document.getElementById('execute-btn');
executeBtn.onclick = () => customExecution(document.getElementById('rawRequest').value);

document.querySelectorAll('.function-btn').forEach((btn) => {
btn.onclick = () => {
const container = btn.parentElement.parentElement;
const inputParam = container.querySelector('.input-param');
const valueParam = container.querySelector('.value-param');
const volumeParam = container.querySelector('.volume-param');
const msParam = container.querySelector('.ms-param');

let request = 'Function=' + btn.innerHTML;
if (inputParam?.value) {
request += '&Input=' + inputParam.value;
}
if (valueParam?.value) {
request += '&Value=' + valueParam.value;
}
if (volumeParam?.value && msParam?.value) {
request += '&Value=' + volumeParam.value + ',' + msParam.value;
}
customExecution(request);
};
});
}
56 changes: 56 additions & 0 deletions vmix-master-stable/duration-timer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
' Checking time left of active running video and display this as an title.
' and do some stuff at certain time remaining

dim position as string = ""
dim duration as string = ""
dim activeinput as string = ""
dim Timeleft as double = 0
dim triggertime as integer = 10 '10 seconds before end
dim triggerduration as integer = 2000 'fade duration, could be different than trigger

do while true

dim xml as string = API.XML()
dim x as new system.xml.xmldocument
x.loadxml(xml)

activeinput = (x.SelectSingleNode("//active").InnerText)
duration = (x.SelectSingleNode("//input[@number='"& activeinput &"']/@duration").Value)
position = (x.SelectSingleNode("//input[@number='"& activeinput &"']/@position").Value)

Timeleft= Double.Parse(duration)-Double.Parse(position)

Timeleft = Timeleft / 100

dim Timingleft as integer = CInt(Timeleft)
Timingleft = Timingleft / 10

dim Minutes as integer = Timingleft \ 60
dim Seconds as integer = Timingleft Mod 60

'used at debugging stage
' console.writeline(Timingleft)
' console.writeline(Seconds)

dim ThisTime as string
ThisTime = Minutes.ToString("00") + ":" + Seconds.ToString("00")


if Timingleft < 60
'put a response in a title and change color accordingly

API.Function("SetText",Input:="Text Middle Centre Outline.gtzip",SelectedIndex:="0" ,Value:=Timingleft) ' Value:=":", Value:=Seconds)

if Timingleft < 11
API.Function("SetTextColour",Input:="Text Middle Centre Outline.gtzip",Value:="red")
else
API.Function("SetTextColour",Input:="Text Middle Centre Outline.gtzip",Value:="orange")
end if
else
API.Function("SetText",Input:="Text Middle Centre Outline.gtzip",SelectedIndex:="0" ,Value:=ThisTime)
API.Function("SetTextColour",Input:="Text Middle Centre Outline.gtzip",Value:="green")
end if


sleep(300)
Loop
178 changes: 178 additions & 0 deletions vmix-master-stable/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<!doctype html>
<html lang="en" data-theme="night">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vMix Master</title>
<link rel="icon" type="image/png" href="./logo.svg" />
<link rel="stylesheet" href="./output.css" />
<script src="./Sortable.min.js" defer></script>
<script src="./tools.js" defer></script>
<script src="./box.js" defer></script>
<script src="./vmix-info.js" defer></script>
<script src="./vmix-web.js" defer></script>
<script src="./custom-functions.js" defer></script>
<script src="./script.js" defer></script>
</head>
<body class="bg-base-100 text-base-content">
<div class="navbar focus bg-base-100">
<div class="flex-1">
<a class="btn btn-ghost text-xl" href="/lsm/">vMix Master</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
<li><a href="/lsm/vmix-master/duration-timer.txt">Duration Timer</a></li>
<li><a href="/lsm/gallery/">Gallery</a></li>
<li><a href="/lsm/yad/">YAD</a></li>
<li><a href="https://github.com/AlexFreik/lsm/" target="_blank">GitHub</a></li>
</ul>
</div>
</div>

<div class="focus flex flex-col items-center">
<div class="flex w-full flex-wrap p-2">
<div class="flex min-w-full items-center justify-center">
<button id="add-box" class="btn btn-outline btn-secondary flex">Add Instance</button>
<button id="refresh-all" class="btn btn-outline btn-secondary mx-3 flex">Refresh All</button>
<label class="input input-bordered input-secondary flex items-center gap-2">
Refresh Rate (sec)
<input id="refresh-rate" class="url-param w-12" name="refreshRate" type="number" min="1" value="5" placeholder="sec" />
</label>
</div>
</div>
</div>

<div class="flex flex-col items-center">
<div class="flex w-full flex-wrap p-1" id="boxes"></div>
</div>

<div class="vmix-web divider focus">vMix Web</div>
<div class="vmix-web">
<div class="mx-auto mb-5 flex w-[500px] items-center gap-1 px-5">
<span class="text-md">Master:</span>
<input id="master" type="number" min="1" name="master" placeholder="e.g. 1" class="url-param input input-xs input-bordered w-16" />
<span class="text-md ms-3">Slaves:</span>
<input id="slaves" type="text" name="slaves" placeholder="e.g. 2 3" class="url-param input input-xs input-bordered flex-1" />
</div>

<div id="vmix-container" class="vmix-web pb-5">
<div
id="vmix-screens"
class="wrap mx-auto mt-3 grid h-[80px] w-[995px] grid-cols-[400px_90px_90px_400px] grid-rows-[25px_25px_20px] gap-1 text-center">
<div id="preview-title" class="col-span-1 row-span-2 mr-1 bg-warning text-lg font-semibold text-primary-content"></div>
<div class="col-span-1 row-span-1">
<button class="btn btn-neutral btn-sm h-[23px] min-h-0 w-[85px] px-1" onclick="transition('Stinger1')">Stinger 1</button>
</div>
<div class="col-span-1 row-span-1">
<button class="btn btn-neutral btn-sm h-[23px] min-h-0 w-[85px] px-1" onclick="transition('Fade')">Fade</button>
</div>
<div id="active-title" class="col-span-1 row-span-2 ml-1 bg-success text-lg font-semibold text-primary-content"></div>
<div class="col-span-1 row-span-1">
<button class="btn btn-neutral btn-sm h-[23px] min-h-0 w-[85px] px-1" onclick="transition('Cut')">Cut</button>
</div>
<div class="col-span-1 row-span-1">
<button class="ftb-btn btn btn-neutral btn-sm h-[23px] min-h-0 w-[85px] px-1" onclick="transition('FadeToBlack')">FTB</button>
</div>
<div id="preview-progress" class="col-span-1 row-span-1"></div>
<div class="col-span-1 row-span-1"></div>
<div class="col-span-1 row-span-1"></div>
<div id="active-progress" class="col-span-1 row-span-1"></div>
</div>

<div id="vmix-inputs" class="mt-2"></div>

<div id="vmix-mixer" class="vmix-mixer mt-5"></div>
</div>
</div>

<div class="custom-functions divider focus mt-5">Custom Functions</div>
<div class="custom-functions px-5">
<div class="mx-auto my-1 flex w-fit items-center gap-1">
<span class="text-md">Include: </span>
<input id="include" type="text" name="include" placeholder="e.g. 1 2 3" class="url-param input input-xs input-bordered w-[300px]" />
</div>

<div class="flex flex-col items-center">
<div class="custom-functions-container flex w-fit flex-wrap p-1">
<div class="m-1 w-fit rounded-box bg-neutral p-3">
<div class="mx-auto w-fit">
<input
id="rawRequest"
type="text"
name="rawRequest"
placeholder="e.g. Function=Fade&Duration=1000&Input=5"
class="url-param input input-xs input-bordered w-[500px]" />
</div>
<div class="mx-auto w-fit">
<button id="execute-btn" class="btn btn-outline btn-secondary btn-sm mt-1">Raw Request</button>
</div>
</div>
</div>
</div>
</div>

<div
class="logs fixed bottom-1 right-1 mx-auto hidden h-[280px] w-[685px] w-[700px] overflow-y-scroll rounded-lg border border-secondary bg-base-300 p-1 opacity-80"></div>

<div class="fixed bottom-2 right-9 rounded bg-neutral px-3">
<label class="swap m-1">
<input id="show-logs" type="checkbox" class="show-toggle url-param" />
<div class="badge swap-on badge-secondary rounded py-3">logs</div>
<div class="badge swap-off badge-secondary badge-outline rounded py-3">logs</div>
</label>

<label class="swap m-1">
<input id="show-vmix-web" type="checkbox" class="show-toggle url-param" checked />
<div class="badge swap-on badge-secondary rounded py-3">vMix Web</div>
<div class="badge swap-off badge-secondary badge-outline rounded py-3">vMix Web</div>
</label>

<label class="swap m-1">
<input id="show-vmix-mixer" type="checkbox" class="show-toggle url-param" checked />
<div class="badge swap-on badge-secondary rounded py-3">mixer</div>
<div class="badge swap-off badge-secondary badge-outline rounded py-3">mixer</div>
</label>

<label class="swap m-1">
<input id="show-custom-functions" type="checkbox" class="show-toggle url-param" />
<div class="badge swap-on badge-secondary rounded py-3">custom</div>
<div class="badge swap-off badge-secondary badge-outline rounded py-3">custom</div>
</label>

<label class="swap m-1">
<input id="view-mode" type="checkbox" class="url-param" checked />
<div class="badge swap-on badge-secondary rounded py-3">control</div>
<div class="badge swap-off badge-secondary badge-outline rounded py-3">control</div>
</label>

<label class="swap m-1">
<input id="show-focus" type="checkbox" class="show-toggle url-param" checked />
<div class="badge swap-on badge-secondary badge-outline rounded py-3">focus</div>
<div class="badge swap-off badge-secondary rounded py-3">focus</div>
</label>
</div>

<div class="divider focus mt-5">Documentation</div>
<div class="prose focus mx-auto max-w-3xl px-5">
You can read official vMix API documentation here:
<a target="_blank" href="https://www.vmix.com/help25/index.htm?DeveloperAPI.html">vmix.com/help25/index.htm?DeveloperAPI.html</a>

<h3>How to Use</h3>
You won't be able to access the vMix API over HTTPS, so you'll need to download the source code from GitHub. You can either clone the repository
if you have Git installed, or click <b>Code</b><b>Download ZIP</b>. You then have two options:
<ul>
<li>You can host LSM locally if you have Node installed. You can follow the instructions in the <code>README.md</code> file on GitHub.</li>
<li>
Or you can open this page as a local file. Go to the <code>lsm/vmix-master/</code> folder and open the <code>index.html</code> file in the
Chrome browser.
</li>
</ul>
</div>

<footer class="footer footer-center focus mt-10 bg-base-300 p-4 text-base-content">
<aside>
<p>Copyright © 2024 - All right reserved by LSM</p>
</aside>
</footer>
</body>
</html>
Loading

0 comments on commit d85c863

Please sign in to comment.