transition and style wired up and prune inputs

This commit is contained in:
2023-02-08 15:10:56 -06:00
parent f605125f74
commit 56cc1b0cf8
3 changed files with 162 additions and 107 deletions
+119 -83
View File
@@ -1,3 +1,5 @@
const { TransitionStyle, TransitionSelection } = require('atem-connection/dist/enums');
exports.config = {
defaultName: 'ATEM',
connectionType: 'atem',
@@ -26,10 +28,12 @@ exports.ready = function ready(_device) {
// TODO: this is a little hacky but it works? gotta be better way to get initial update going
const interval = setInterval(() => {
device.update('inputs', device.data.video.mixEffects);
device.update('fadeToBlack', device.data.video.mixEffects);
device.update(`transitionPosition`, device.data.video.mixEffects);
device.update('downstreamKeyers', device.data.video.downstreamKeyers);
device.update('inputs', device.data);
device.update('fadeToBlack', device.data);
device.update(`transitionPosition`, device.data);
device.update('downstreamKeyers', device.data);
device.update('upstreamKeyers', device.data);
device.update('transitionProperties', device.data);
}, 1000);
setTimeout(() => {
clearInterval(interval);
@@ -38,86 +42,131 @@ exports.ready = function ready(_device) {
exports.update = function update(device, _document, updateType, data) {
const document = _document;
switch (updateType) {
case 'downstreamKeyers':
for (let i = 0; i < data.length; i++) {
const dsk = data[i];
if (dsk.isAuto) {
document.getElementById(`dsk-${i}-auto`).classList.add('atem-red');
} else {
document.getElementById(`dsk-${i}-auto`).classList.remove('atem-red');
}
if (dsk.onAir) {
document.getElementById(`dsk-${i}-onair`).classList.add('atem-red');
} else {
document.getElementById(`dsk-${i}-onair`).classList.remove('atem-red');
}
if (dsk.properties.tie) {
document.getElementById(`dsk-${i}-tie`).classList.add('atem-yellow');
} else {
document.getElementById(`dsk-${i}-tie`).classList.remove('atem-yellow');
}
if (dsk.remainingFrames === dsk.properties.rate) {
document.getElementById(`dsk-${i}-rate`).textContent = '1:00';
} else {
// TODO: format in 0:00 format
document.getElementById(`dsk-${i}-rate`).textContent = `00${dsk.remainingFrames}`.slice(-2);
}
if (updateType.includes('transitionPosition')) {
for (let i = 0; i < data.video.mixEffects.length; i++) {
const mixEffect = data.video.mixEffects[i];
const tbarId = `me-${i}-tbar-progress`;
if (document.getElementById(tbarId)) {
document.getElementById(tbarId).value = mixEffect.transitionPosition.handlePosition;
}
break;
case 'transitionPosition':
for (let i = 0; i < data.length; i++) {
const tbarId = `me-${i}-tbar-pos`;
if (document.getElementById(tbarId)) {
document.getElementById(tbarId).value = data[i].transitionPosition.handlePosition;
}
// TODO: format in 0:00 format
document.getElementById(`me-${i}-transition-rate`).textContent =
`00${mixEffect.transitionPosition.remainingFrames}`.slice(-2);
}
} else if (updateType.includes('downstreamKeyers')) {
for (let i = 0; i < data.video.downstreamKeyers.length; i++) {
const dsk = data.video.downstreamKeyers[i];
if (dsk.isAuto) {
document.getElementById(`dsk-${i}-auto`).classList.add('atem-red');
} else {
document.getElementById(`dsk-${i}-auto`).classList.remove('atem-red');
}
break;
case 'fadeToBlack':
for (let i = 0; i < data.length; i++) {
const fadeToBlack = data[i].fadeToBlack;
const ftbRateId = `me-${i}-ftb-rate`;
const ftbId = `me-${i}-ftb`;
if (fadeToBlack.remainingFrames === fadeToBlack.rate) {
document.getElementById(ftbRateId).textContent = '1:00';
} else {
// TODO: format in 0:00 format
document.getElementById(ftbRateId).textContent = `00${fadeToBlack.remainingFrames}`.slice(-2);
}
if (fadeToBlack.inTransition || fadeToBlack.isFullyBlack) {
document.getElementById(ftbId).classList.add('atem-red');
} else {
document.getElementById(ftbId).classList.remove('atem-red');
}
if (dsk.onAir) {
document.getElementById(`dsk-${i}-onair`).classList.add('atem-red');
} else {
document.getElementById(`dsk-${i}-onair`).classList.remove('atem-red');
}
break;
case 'inputs':
for (let i = 0; i < data.length; i++) {
const programInputs = device.connection.listVisibleInputs('program', i);
const previewInputs = device.connection.listVisibleInputs('preview', i);
Object.entries(device.data.inputs).forEach(([inputId, input]) => {
if (programInputs.includes(Number(inputId))) {
if (dsk.properties.tie) {
document.getElementById(`dsk-${i}-tie`).classList.add('atem-yellow');
} else {
document.getElementById(`dsk-${i}-tie`).classList.remove('atem-yellow');
}
document.getElementById(`dsk-${i}-rate`).textContent = `00${dsk.remainingFrames}`.slice(-2);
}
} else if (updateType.includes('fadeToBlack')) {
for (let i = 0; i < data.video.mixEffects.length; i++) {
const fadeToBlack = data.video.mixEffects[i].fadeToBlack;
const ftbRateId = `me-${i}-ftb-rate`;
const ftbId = `me-${i}-ftb`;
// TODO: format in 0:00 format
document.getElementById(ftbRateId).textContent = `00${fadeToBlack.remainingFrames}`.slice(-2);
if (fadeToBlack.inTransition || fadeToBlack.isFullyBlack) {
document.getElementById(ftbId).classList.add('atem-red');
} else {
document.getElementById(ftbId).classList.remove('atem-red');
}
}
} else if (
updateType.includes('programInput') ||
updateType.includes('previewInput') ||
updateType.includes('inputs')
) {
for (let i = 0; i < data.video.mixEffects.length; i++) {
const mixEffect = data.video.mixEffects[0];
Object.keys(device.data.inputs)
.map((key) => Number(key))
.forEach((inputId) => {
if (mixEffect.programInput === inputId) {
document.getElementById(`me-${i}-program-input-${inputId}`).classList.add('atem-red');
} else {
document.getElementById(`me-${i}-program-input-${inputId}`).classList.remove('atem-red');
}
if (previewInputs.includes(Number(inputId))) {
if (mixEffect.previewInput === inputId) {
document.getElementById(`me-${i}-preview-input-${inputId}`).classList.add('atem-green');
} else {
document.getElementById(`me-${i}-preview-input-${inputId}`).classList.remove('atem-green');
}
});
}
break;
default:
break;
}
} else if (updateType.includes('transitionProperties')) {
for (let i = 0; i < data.video.mixEffects.length; i++) {
const transitionProperties = data.video.mixEffects[i].transitionProperties;
Object.keys(TransitionStyle)
.filter((key) => !isNaN(Number(key)))
.map((key) => Number(key))
.forEach((style) => {
if (style === transitionProperties.style) {
document.getElementById(`me-${i}-transition-style-${style}`).classList.add('atem-yellow');
} else {
document.getElementById(`me-${i}-transition-style-${style}`).classList.remove('atem-yellow');
}
if (style === transitionProperties.nextStyle) {
document.getElementById(`me-${i}-transition-style-${style}`).classList.add('atem-yellow');
} else {
document.getElementById(`me-${i}-transition-style-${style}`).classList.remove('atem-yellow');
}
});
Object.keys(TransitionSelection)
.filter((key) => !isNaN(Number(key)))
.map((key) => Number(key))
.forEach((selection) => {
if (transitionProperties.selection.includes(selection)) {
document.getElementById(`me-${i}-transition-selection-${selection}`).classList.add('atem-yellow');
} else {
document.getElementById(`me-${i}-transition-selection-${selection}`).classList.remove('atem-yellow');
}
if (transitionProperties.nextSelection.includes(selection)) {
document.getElementById(`me-${i}-transition-selection-${selection}`).classList.add('atem-yellow');
} else {
document.getElementById(`me-${i}-transition-selection-${selection}`).classList.remove('atem-yellow');
}
});
}
} else if (updateType.includes('upstreamKeyers')) {
for (let i = 0; i < data.video.mixEffects.length; i++) {
const upstreamKeyers = data.video.mixEffects[i].upstreamKeyers;
upstreamKeyers.forEach((upstreamKeyer) => {
if (upstreamKeyer.onAir) {
document.getElementById(`me-${i}-key-${upstreamKeyer.upstreamKeyerId + 1}-onair`).classList.add('atem-red');
} else {
document
.getElementById(`me-${i}-key-${upstreamKeyer.upstreamKeyerId + 1}-onair`)
.classList.remove('atem-red');
}
});
}
} else {
console.log('unhandled update');
console.log(updateType);
console.log(device.data);
}
};
@@ -127,19 +176,6 @@ exports.data = function data(_device, msg) {
device.data = msg.state;
msg.pathToChange.forEach((path) => {
if (path.includes('transitionPosition')) {
device.update(`transitionPosition`, device.data.video.mixEffects);
} else if (path.includes('downstreamKeyers')) {
device.update('downstreamKeyers', device.data.video.downstreamKeyers);
} else if (path.includes('fadeToBlack')) {
device.update('fadeToBlack', device.data.video.mixEffects);
} else if (path.includes('programInput')) {
device.update('inputs', device.data.video.mixEffects);
} else if (path.includes('previewInput')) {
device.update('inputs', device.data.video.mixEffects);
} else {
console.log(path);
console.log(device.data);
}
device.update(path, device.data);
});
};
+4
View File
@@ -94,3 +94,7 @@ h3 {
padding: 2px;
text-align: center;
}
.hide {
display: none;
}
+39 -24
View File
@@ -9,20 +9,34 @@
<div class="program">
<h3 class="atem-gray">Program</h3>
<div class="source-wrapper">
<% Object.entries(data.inputs).forEach(([inputId, state])=>{ %>
<div id="me-<%= meIndex %>-program-input-<%= inputId %>" class="atem-input">
<div class="source-label"><%= state.shortName %></div>
</div>
<% Object.values(data.inputs).sort((a,b)=>a.internalPortType<b.internalPortType).forEach((input)=>{ %>
<% if ([0,1,2,3,4].includes(input.internalPortType)) { %>
<div id="me-<%= meIndex %>-program-input-<%= input.inputId %>" class="atem-input">
<div class="source-label"><%= input.shortName %></div>
</div>
<% } else {%>
<div id="me-<%= meIndex %>-program-input-<%= input.inputId %>" class="atem-input hide">
<div class="source-label"><%= input.shortName %></div>
</div>
<% }%>
<% }) %>
</div>
</div>
<div class="preview">
<h3 class="atem-gray">Preview</h3>
<div class="source-wrapper">
<% Object.entries(data.inputs).forEach(([inputId, state])=>{ %>
<div id="me-<%= meIndex %>-preview-input-<%= inputId %>" class="atem-input">
<div class="source-label"><%= state.shortName %></div>
</div>
<% Object.values(data.inputs).forEach((input)=>{ %>
<% if ([0,1,2,3,4].includes(input.internalPortType)) { %>
<div id="me-<%= meIndex %>-preview-input-<%= input.inputId %>" class="atem-input">
<div class="source-label"><%= input.shortName %></div>
</div>
<% } else {%>
<div id="me-<%= meIndex %>-preview-input-<%= input.inputId %>" class="atem-input hide">
<div class="source-label"><%= input.shortName %></div>
</div>
<% }%>
<% }) %>
</div>
</div>
@@ -58,19 +72,19 @@
</div>
<div class="source-wrapper empty">
<div id="me-<%= meIndex %>-bkgd" class="atem-input">
<div id="me-<%= meIndex %>-transition-selection-1" class="atem-input">
<div class="source-label">BKGD</div>
</div>
<div id="me-<%= meIndex %>-key-1" class="atem-input">
<div id="me-<%= meIndex %>-transition-selection-2" class="atem-input">
<div class="source-label">KEY 1</div>
</div>
<div id="me-<%= meIndex %>-key-2" class="atem-input">
<div id="me-<%= meIndex %>-transition-selection-4" class="atem-input">
<div class="source-label">KEY 2</div>
</div>
<div id="me-<%= meIndex %>-key-3" class="atem-input">
<div id="me-<%= meIndex %>-transition-selection-8" class="atem-input">
<div class="source-label">KEY 3</div>
</div>
<div id="me-<%= meIndex %>-key-4" class="atem-input">
<div id="me-<%= meIndex %>-transition-selection-16" class="atem-input">
<div class="source-label">KEY 4</div>
</div>
</div>
@@ -81,19 +95,19 @@
<h3>Transition Style</h3>
<div class="source-wrapper" style="flex-direction:column">
<div class="source-wrapper empty">
<div id="me-<%= meIndex %>-trans-0" class="atem-input">
<div id="me-<%= meIndex %>-transition-style-0" class="atem-input">
<div class="source-label">MIX</div>
</div>
<div id="me-<%= meIndex %>-trans-1" class="atem-input">
<div id="me-<%= meIndex %>-transition-style-1" class="atem-input">
<div class="source-label">DIP</div>
</div>
<div id="me-<%= meIndex %>-trans-2" class="atem-input">
<div id="me-<%= meIndex %>-transition-style-2" class="atem-input">
<div class="source-label">WIPE</div>
</div>
<div id="me-<%= meIndex %>-trans-4" class="atem-input">
<div id="me-<%= meIndex %>-transition-style-4" class="atem-input">
<div class="source-label">STING</div>
</div>
<div id="me-<%= meIndex %>-trans-3" class="atem-input">
<div id="me-<%= meIndex %>-transition-style-3" class="atem-input">
<div class="source-label">DVE</div>
</div>
</div>
@@ -117,7 +131,7 @@
</div>
<div class="transition-rate atem-input empty">
<div class="atem-gray" style="text-align: center">Rate</div>
<div id="me-<%= meIndex %>-transition-rate" class="transition-rate-label">1:00</div>
<div id="me-<%= meIndex %>-transition-rate" class="transition-rate-label">00</div>
</div>
</div>
</div>
@@ -127,7 +141,7 @@
<div class="source-wrapper">
<div class="ftb-rate atem-input empty">
<div class="atem-gray" style="text-align: center">Rate</div>
<div id="me-<%= meIndex %>-ftb-rate" class="ftb-rate-label">1:00</div>
<div id="me-<%= meIndex %>-ftb-rate" class="ftb-rate-label">00</div>
</div>
<div id="me-<%= meIndex %>-ftb" class="atem-input">
<div class="source-label">FTB</div>
@@ -135,8 +149,8 @@
</div>
</div>
<div class="source-wrapper">
<progress id="me-<%= meIndex %>-tbar-pos" max="10000" value="0" class="tbar-progress"></progress>
<div class="source-wrapper" style="width:100%">
<progress id="me-<%= meIndex %>-tbar-progress" max="10000" value="0" class="tbar-progress"></progress>
</div>
</div>
<% }) %>
@@ -153,11 +167,12 @@
</div>
<div class="dsk-rate atem-input empty">
<div class="atem-gray" style="text-align: center">Rate</div>
<div id="dsk-<%= dskIndex %>-rate" class="dsk-rate-label">1:00</div>
<div id="dsk-<%= dskIndex %>-rate" class="dsk-rate-label">00</div>
</div>
<div id="dsk-<%= dskIndex %>-onair" class="atem-input">
<div class="source-label" style="flex-direction: column;">
<div>ON</div> <div>AIR</div></div>
<div>ON</div> <div>AIR</div>
</div>
</div>
<div id="dsk-<%= dskIndex %>-auto" class="atem-input">
<div class="source-label">AUTO</div>