logo

Live Production Software Forums


Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
Pothala  
#1 Posted : Thursday, February 27, 2025 5:52:22 AM(UTC)
Pothala

Rank: Newbie

Groups: Registered
Joined: 11/23/2019(UTC)
Posts: 5
Spain
Location: Jerez de la Frontera

Thanks: 1 times
Was thanked: 1 time(s) in 1 post(s)
I usually work with VMix projects that have several inputs with Multiwindows, (2 or 3 Windows),
with which I had the need to change the fonts shown in each layer with a certain speed.

In this forum I asked if with UTC you could make drop-down elements that take project inputs from the API,
and when selecting a certain input, it will be applied to a certain layer of the Multi-Window composition called MVWX in the project.

But they commented that UTC list selectors can only execute changes to text fields in titles.

Out of desperation of needing a solution, I expressed my problem to ChatGPT, and they gave me a solution, which after much debugging,
has given this result.

I share and explain to you.

The script for the MVW.HMTL file is as follows:



<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Selector Dinámico de Fuentes - vMix</title>

<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- Font Awesome Icons -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">

<style>
body {
background-color: #f8f9fa;
font-family: Arial, sans-serif;
}
.container {
margin-top: 50px;
}
.card {
border-radius: 15px;
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
}
.card-header {
background-color: #007bff;
color: white;
text-align: center;
}
.form-label {
font-weight: bold;
}
select {
border-radius: 8px;
}
.btn-update {
background-color: #28a745;
color: white;
}
.btn-update:hover {
background-color: #218838;
}
.icon {
font-size: 1.5rem;
}
/* Estilo para la caja azul de los títulos MVW */
.mvw-title-box {
background-color: #007bff; /* Color azul */
color: white; /* Texto blanco */
padding: 10px;
border-radius: 8px;
margin-bottom: 15px;
text-align: center;
font-weight: bold;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
}
</style>
</head>

<body>
<div class="container">
<div class="card">
<div class="card-header">
<h3><i class="fas fa-video icon"></i> Selector Dinámico de Fuentes MVW</h3>
</div>
<div class="card-body">
<form>
<!-- Contenedor dinámico para las entradas MVW -->
<div id="mvw-entries"></div>

<!-- Botón para actualizar manualmente las fuentes -->
<button type="button" class="btn btn-update w-100 mt-3" onclick="loadSources()">
Actualizar Fuentes
</button>
</form>
</div>
</div>
</div>

<!-- Bootstrap JS and dependencies -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js"></script>

<script>
const vMixAPI = "http://192.168.1.5:8088/api/";
let selectedSources = {};

async function loadSources() {
try {
console.log("Cargando fuentes desde vMix...");
let response = await fetch(vMixAPI);
let text = await response.text();
let parser = new DOMParser();
let xmlDoc = parser.parseFromString(text, "text/xml");

let inputs = xmlDoc.getElementsByTagName("input");
let mvwEntries = {};

Array.from(inputs).forEach(input => {
let title = input.getAttribute("title");
if (title && title.startsWith("MVW")) {
let mvwIndex = title.replace("MVW", "");
let mvwEntry = { layers: ["", "", ""] };

let overlayAttr = input.getElementsByTagName("overlay");
for (let j = 0; j < overlayAttr.length; j++) {
let layerIndex = overlayAttr[j].getAttribute("index");
let key = overlayAttr[j].getAttribute("key");
mvwEntry.layers[layerIndex] = key;
}
mvwEntries[mvwIndex] = mvwEntry;
}
});

selectedSources = mvwEntries;

let mvwContainer = document.getElementById("mvw-entries");
mvwContainer.innerHTML = "";

Object.keys(mvwEntries).forEach(mvwIndex => {
let entry = mvwEntries[mvwIndex];

let mvwDiv = document.createElement("div");
mvwDiv.classList.add("mb-4");

mvwDiv.innerHTML = `<div class="mvw-title-box">Entrada MVW${mvwIndex}</div>`;

["layer1", "layer2", "layer3"].forEach((layer, layerIndex) => {
let label = document.createElement("label");
label.classList.add("form-label");
label.setAttribute("for", `${layer}-${mvwIndex}`);
label.innerText = `Ventana ${layerIndex + 1}:`;

let select = document.createElement("select");
select.classList.add("form-select");
select.id = `${layer}-${mvwIndex}`;
select.onchange = () => updateLayer(mvwIndex, layerIndex);

for (let i = 0; i < inputs.length; i++) {
let option = document.createElement("option");
let name = inputs[i].getAttribute("title");
let key = inputs[i].getAttribute("key");

option.value = key;
option.textContent = name;
select.appendChild(option);
}

select.value = entry.layers[layerIndex] || "";
mvwDiv.appendChild(label);
mvwDiv.appendChild(select);
});

mvwContainer.appendChild(mvwDiv);
});

} catch (error) {
console.error("Error al cargar fuentes:", error);
alert("Error al conectarse con vMix.");
}
}

async function updateLayer(mvwIndex, layerIndex) {
let selectedKey = document.getElementById(`layer${layerIndex + 1}-${mvwIndex}`).value;
if (!selectedKey) return;

try {
let url = `${vMixAPI}?Function=SetMultiViewOverlay&Input=MVW${mvwIndex}&Value=${layerIndex + 1},${selectedKey}`;
console.log(`Cambiando Capa ${layerIndex + 1} de MVW${mvwIndex} a ${selectedKey}`);
await fetch(url);

selectedSources[mvwIndex].layers[layerIndex] = selectedKey;

} catch (error) {
console.error("Error al actualizar Multiview:", error);
}
}

window.onload = () => {
loadSources();
setInterval(loadSources, 10000);
};
</script>
</body>
</html>


This script connects to the API, and takes the names of all the project entries in VMix, detects if there is any entry in the project that has a MultiWindow (The entry name must start with MVW),

It updates in 7 seconds with Vmix, and the input we choose in each selector will be applied to the corresponding MultiWindow (MVW) layer we want.

I hope it helps you, and if someone can modify it to give it more functions, or debug it, welcome.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.