2024-05-20 23:04:47 +01:00
|
|
|
import { Hyperdeck, Commands } from 'hyperdeck-connection';
|
2024-04-30 22:17:21 +01:00
|
|
|
import WebSocket from 'ws';
|
2024-05-25 17:44:14 +01:00
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
2024-04-30 22:17:21 +01:00
|
|
|
|
2024-05-20 23:04:47 +01:00
|
|
|
interface WrappedHyperdeck {
|
|
|
|
ip: String,
|
|
|
|
port: number,
|
|
|
|
hyperdeck: Hyperdeck
|
|
|
|
}
|
|
|
|
|
|
|
|
const hyperdecks: Map<string, WrappedHyperdeck> = new Map()
|
|
|
|
|
|
|
|
enum WebSocketMessageType {
|
2024-05-22 01:20:03 +01:00
|
|
|
AddHyperdeck = "add_hyperdeck",
|
|
|
|
RemoveHyperdeck = "remove_hyperdeck"
|
2024-05-20 23:04:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type WebSocketMessage = {
|
|
|
|
type: WebSocketMessageType.AddHyperdeck,
|
|
|
|
id: string,
|
|
|
|
ip: string,
|
|
|
|
port: number
|
2024-05-22 01:20:03 +01:00
|
|
|
} | {
|
|
|
|
type: WebSocketMessageType.RemoveHyperdeck,
|
|
|
|
id: string
|
2024-05-20 23:04:47 +01:00
|
|
|
}
|
|
|
|
|
2024-04-30 22:17:21 +01:00
|
|
|
const wss = new WebSocket.Server({ port: 7867 });
|
|
|
|
|
2024-05-25 17:44:14 +01:00
|
|
|
const connected_clients: Map<string, WebSocket> = new Map();
|
|
|
|
|
|
|
|
wss.on('connection', (ws) => {
|
|
|
|
const clientId = uuidv4();
|
|
|
|
ws.on('message', (data) => {
|
2024-05-20 23:04:47 +01:00
|
|
|
try {
|
|
|
|
const message = JSON.parse(data.toString()) as Partial<WebSocketMessage>;
|
|
|
|
handle_message(message)
|
|
|
|
} catch (_err) {
|
|
|
|
return;
|
|
|
|
}
|
2024-04-30 22:17:21 +01:00
|
|
|
});
|
2024-05-25 17:44:14 +01:00
|
|
|
ws.on('close', () => {
|
|
|
|
connected_clients.delete(clientId)
|
|
|
|
})
|
2024-04-30 22:17:21 +01:00
|
|
|
|
|
|
|
ws.send(JSON.stringify({
|
|
|
|
event: "log",
|
|
|
|
message: "Hello"
|
|
|
|
}));
|
2024-05-25 17:44:14 +01:00
|
|
|
|
|
|
|
connected_clients.set(clientId, ws);
|
2024-04-30 22:17:21 +01:00
|
|
|
});
|
2024-05-20 23:04:47 +01:00
|
|
|
|
|
|
|
function exhaustiveMatch(_never: never) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
function handle_message(message: Partial<WebSocketMessage>) {
|
|
|
|
console.log(JSON.stringify(message));
|
|
|
|
if (message.type === undefined) return;
|
|
|
|
|
|
|
|
switch (message.type) {
|
|
|
|
case WebSocketMessageType.AddHyperdeck:
|
|
|
|
if (message.id === undefined) return;
|
|
|
|
if (message.ip === undefined) return;
|
|
|
|
if (message.port === undefined) return;
|
|
|
|
if (isNaN(message.port)) return;
|
|
|
|
if (message.port <= 0) return;
|
|
|
|
|
|
|
|
console.log("Adding hyperdeck");
|
|
|
|
|
|
|
|
const newHyperdeck = new Hyperdeck()
|
|
|
|
|
2024-05-22 01:20:03 +01:00
|
|
|
hyperdecks.set(message.id, {
|
|
|
|
ip: message.ip,
|
|
|
|
port: message.port,
|
|
|
|
hyperdeck: newHyperdeck
|
|
|
|
});
|
2024-05-20 23:04:47 +01:00
|
|
|
|
2024-05-25 17:44:14 +01:00
|
|
|
newHyperdeck.on('connected', (_info) => {
|
|
|
|
notifyClients({
|
|
|
|
event: "hyperdeck_connected",
|
|
|
|
id: message.id
|
|
|
|
})
|
2024-05-20 23:04:47 +01:00
|
|
|
|
2024-05-25 17:44:14 +01:00
|
|
|
setInterval(() => {
|
|
|
|
newHyperdeck.sendCommand(new Commands.TransportInfoCommand()).then((transportInfo) => {
|
|
|
|
notifyClients({
|
|
|
|
event: "record_state",
|
2024-06-01 15:48:35 +01:00
|
|
|
hyperdeck_id: message.id,
|
|
|
|
status: transportInfo.status,
|
2024-05-25 17:44:14 +01:00
|
|
|
})
|
2024-06-01 15:48:35 +01:00
|
|
|
}).catch((err) => {
|
2024-06-01 16:01:20 +01:00
|
|
|
console.log(JSON.stringify(err))
|
|
|
|
notifyClients({
|
|
|
|
event: "log",
|
|
|
|
message: JSON.stringify(err)
|
|
|
|
})
|
2024-06-01 15:48:35 +01:00
|
|
|
})
|
2024-05-31 00:28:41 +01:00
|
|
|
}, 1000)
|
|
|
|
|
2024-06-01 15:51:38 +01:00
|
|
|
setTimeout(() => {
|
|
|
|
newHyperdeck.sendCommand(new Commands.DeviceInfoCommand()).then((info) => {
|
2024-06-01 16:05:46 +01:00
|
|
|
notifyClients({
|
|
|
|
event: "log",
|
2024-06-01 16:12:46 +01:00
|
|
|
message: "DEVICE INFO " + JSON.stringify(info)
|
2024-06-01 16:05:46 +01:00
|
|
|
})
|
2024-06-01 16:23:49 +01:00
|
|
|
let slots = info.slots === null ? 0 : info.slots;
|
2024-06-01 16:10:01 +01:00
|
|
|
for (let index = 0; index < slots; index++) {
|
2024-06-01 15:51:38 +01:00
|
|
|
setInterval(() => {
|
|
|
|
newHyperdeck.sendCommand(new Commands.SlotInfoCommand(index)).then((slot) => {
|
2024-06-01 16:10:01 +01:00
|
|
|
notifyClients({
|
|
|
|
event: "log",
|
2024-06-01 16:12:46 +01:00
|
|
|
message: "SLOT " + JSON.stringify(slot)
|
2024-06-01 16:10:01 +01:00
|
|
|
})
|
2024-06-01 15:51:38 +01:00
|
|
|
notifyClients({
|
|
|
|
event: "record_time_remaining",
|
|
|
|
hyperdeck_id: message.id,
|
|
|
|
slot_id: slot.slotId,
|
|
|
|
remaining: slot.recordingTime
|
|
|
|
})
|
|
|
|
}).catch((err) => {
|
2024-06-01 16:01:20 +01:00
|
|
|
console.log(JSON.stringify(err))
|
|
|
|
notifyClients({
|
|
|
|
event: "log",
|
2024-06-01 16:12:46 +01:00
|
|
|
message: "ERR " + JSON.stringify(err)
|
2024-06-01 16:01:20 +01:00
|
|
|
})
|
2024-05-31 00:33:09 +01:00
|
|
|
})
|
2024-06-01 15:51:38 +01:00
|
|
|
}, 1000)
|
|
|
|
}
|
|
|
|
})
|
2024-06-01 16:04:02 +01:00
|
|
|
.catch((err) => {
|
|
|
|
console.log(JSON.stringify(err))
|
|
|
|
notifyClients({
|
|
|
|
event: "log",
|
2024-06-01 16:12:46 +01:00
|
|
|
message: "ERR " + JSON.stringify(err)
|
2024-06-01 16:04:02 +01:00
|
|
|
})
|
|
|
|
})
|
2024-06-01 15:51:38 +01:00
|
|
|
}, 1000)
|
2024-05-20 23:04:47 +01:00
|
|
|
})
|
|
|
|
|
2024-05-25 17:44:14 +01:00
|
|
|
newHyperdeck.on('notify.slot', function (slot) {
|
|
|
|
notifyClients({
|
|
|
|
event: "record_time_remaining",
|
2024-06-01 15:48:35 +01:00
|
|
|
hyperdeck_id: message.id,
|
|
|
|
slot_id: slot.slotId,
|
2024-05-25 17:44:14 +01:00
|
|
|
remaining: slot.recordingTime
|
|
|
|
})
|
2024-05-20 23:04:47 +01:00
|
|
|
})
|
|
|
|
newHyperdeck.on('notify.transport', function (state) {
|
2024-05-25 17:44:14 +01:00
|
|
|
notifyClients({
|
|
|
|
event: "record_state",
|
2024-06-01 15:48:35 +01:00
|
|
|
hyperdeck_id: message.id,
|
|
|
|
status: state.status
|
2024-05-25 17:44:14 +01:00
|
|
|
})
|
2024-05-20 23:04:47 +01:00
|
|
|
})
|
|
|
|
newHyperdeck.on('error', (err) => {
|
|
|
|
console.log('Hyperdeck error', JSON.stringify(err))
|
2024-06-01 16:01:20 +01:00
|
|
|
notifyClients({
|
|
|
|
event: "log",
|
|
|
|
message: JSON.stringify(err)
|
|
|
|
})
|
2024-05-20 23:04:47 +01:00
|
|
|
})
|
|
|
|
|
2024-05-25 17:44:14 +01:00
|
|
|
newHyperdeck.on('disconnected', () => {
|
|
|
|
notifyClients({
|
|
|
|
event: "hyperdeck_disconnected",
|
|
|
|
id: message.id
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2024-05-20 23:04:47 +01:00
|
|
|
newHyperdeck.connect(message.ip, message.port)
|
|
|
|
|
2024-05-22 01:20:03 +01:00
|
|
|
break;
|
|
|
|
case WebSocketMessageType.RemoveHyperdeck:
|
|
|
|
if (message.id === undefined) return;
|
|
|
|
|
|
|
|
console.log("Removing hyperdeck");
|
|
|
|
|
|
|
|
let hyperdeck = hyperdecks.get(message.id)
|
|
|
|
if (hyperdeck === undefined) return;
|
|
|
|
|
|
|
|
hyperdeck.hyperdeck.disconnect()
|
|
|
|
hyperdecks.delete(message.id)
|
|
|
|
|
2024-05-20 23:04:47 +01:00
|
|
|
break;
|
|
|
|
default:
|
2024-05-22 01:20:03 +01:00
|
|
|
exhaustiveMatch(message)
|
2024-05-20 23:04:47 +01:00
|
|
|
}
|
|
|
|
}
|
2024-05-25 17:44:14 +01:00
|
|
|
|
|
|
|
function notifyClients(message: object) {
|
|
|
|
connected_clients.forEach((client) => {
|
|
|
|
client.send(JSON.stringify(message))
|
|
|
|
})
|
|
|
|
}
|