Files
status-indicators/atem_state.js
T

42 lines
1.7 KiB
JavaScript
Raw Normal View History

// Read-only snapshot of the ATEM switcher's audio (Fairlight) and camera control (CCU) state,
// printed as one JSON line. Uses the atem-connection library inside Companion's ATEM module,
// run with Companion's own node. Nothing is sent that changes the switcher.
//
// node atem_state.js <switcher ip> <path to atem-connection> [seconds to collect CCU values]
const [ip, lib, secs] = process.argv.slice(2)
const { Atem } = require(lib)
const ccu = {}
const atem = new Atem({ disableMultithreaded: true })
atem.on('receivedCommands', (cmds) => {
for (const c of cmds) {
if (c.constructor && c.constructor.rawName === 'CCdP') {
const p = c.properties
const v = p.numberData && p.numberData.length ? p.numberData
: p.boolData && p.boolData.length ? p.boolData
: p.bigintData && p.bigintData.length ? p.bigintData.map(Number) : p.stringData
ccu[`${c.source}/${c.category}/${c.parameter}`] = v
}
}
})
const done = (out, code) => {
process.stdout.write(JSON.stringify(out) + '\n')
atem.disconnect().finally(() => process.exit(code))
setTimeout(() => process.exit(code), 2000)
}
setTimeout(() => done({ error: 'no connection to the switcher' }, 2), 15000)
atem.on('connected', () => {
setTimeout(() => {
const inputs = {}
const fl = (atem.state.fairlight && atem.state.fairlight.inputs) || {}
for (const [id, input] of Object.entries(fl)) {
if (!input) continue
for (const [sid, src] of Object.entries(input.sources || {})) {
if (!src || !src.properties) continue
inputs[`${id}/${sid}`] = { mixOption: src.properties.mixOption, faderGain: src.properties.faderGain }
}
}
done({ model: atem.state.info && atem.state.info.productIdentifier, fairlight: inputs, ccu }, 0)
}, (Number(secs) || 3) * 1000)
})
atem.connect(ip)