UNPKG

@darrellvs/node-wave-link-sdk

Version:
810 lines (799 loc) 22.3 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { WaveLinkController: () => WaveLinkController, WaveLinkInputController: () => WaveLinkInputController, WaveLinkOutputController: () => WaveLinkOutputController }); module.exports = __toCommonJS(src_exports); // src/Helpers/EventEmitterHelpers.ts var import_events = require("events"); var TypedEventEmitter = class { eventEmitter = new import_events.EventEmitter(); constructor() { } emit(event, ...args) { this.eventEmitter.emit(event, ...args); } on(event, listener) { this.eventEmitter.on(event, listener); } off(event, listener) { this.eventEmitter.off(event, listener); } removeAllListeners(event) { this.eventEmitter.removeAllListeners(event); } setMaxListeners(n) { this.eventEmitter.setMaxListeners(n); } }; // src/Base/BaseController.ts var BaseController = class extends TypedEventEmitter { constructor() { super(); } }; // src/Base/BaseWaveLinkController.ts var import_ws = require("ws"); // src/Utils/constants.ts var mixerIDSelectedOutputAndValueTransformer = ({ mixerID, value, selectedOutput }) => ({ mixerID, value, selectedOutput }); var identifierAndFilterIDTransformer = ({ identifier, filterID }) => ({ identifier, filterID }); var identifierAndFilterTransformer = ({ identifier, filter }) => ({ identifier, filter }); var identifierMixerIDAndValueTransformer = ({ identifier, mixerID, value }) => ({ identifier, mixerID, value }); var identifierFilterIDAndValueTransformer = ({ identifier, filterID, value }) => ({ identifier, filterID, value }); var WaveLinkEventMap = { outputMuteChanged: mixerIDSelectedOutputAndValueTransformer, outputVolumeChanged: mixerIDSelectedOutputAndValueTransformer, inputNameChanged: identifierMixerIDAndValueTransformer, inputMuteChanged: identifierMixerIDAndValueTransformer, inputVolumeChanged: identifierMixerIDAndValueTransformer, filterBypassStateChanged: identifierMixerIDAndValueTransformer, filterAdded: identifierAndFilterTransformer, filterRemoved: identifierAndFilterIDTransformer, filterChanged: identifierFilterIDAndValueTransformer }; var getWaveLinkEventData = (method, params, selectedOutput) => { if (WaveLinkEventMap[method]) { return WaveLinkEventMap[method]({ ...params, selectedOutput }); } return null; }; var waveLinkInternalEventsToBeRemoved = [ "websocketClose", "outputMuteChanged", "outputVolumeChanged", "selectedOutputChanged", "inputNameChanged", "inputMuteChanged", "inputVolumeChanged", "filterBypassStateChanged", "filterAdded", "filterRemoved", "filterChanged", "inputsChanged" ]; var waveLinkOutputEvents = [ "localVolumeChanged", "streamVolumeChanged", "volumeChanged", "localMuteChanged", "streamMuteChanged", "muteChanged", "selectedOutputChanged" ]; var waveLinkFilterEvents = [ "muteChanged", "mute", "unmute" ]; // src/Base/BaseWaveLinkController.ts var BaseWaveLinkController = class extends BaseController { constructor(rpc, host) { super(); this.rpc = rpc; this.host = host; } websocket; minPort = 1824; currentPort = this.minPort; isConnecting = false; lastId = 0; emittedIdsMap = /* @__PURE__ */ new Map(); selectedOutput; connect(isAutoTry = false) { return new Promise((resolve, reject) => { if (!this.currentPort || this.isConnecting) { reject("Already connecting"); return; } this.isConnecting = true; setTimeout(async () => { await this.tryToConnect(isAutoTry, () => resolve("Initialised")); }, 1e3); }); } getWaveLinkEmmiter() { return this; } async tryToConnect(isAutoTry = false, callback) { if (this.websocket) this.websocket.close(); this.websocket = new import_ws.WebSocket( `ws://${this.host}:${this.currentPort}` ); this.websocket.rpc = this.rpc; this.websocket.onopen = async () => { this.isConnecting = false; this.initRPC(); this.emit("websocketOpen"); const { selectedOutput } = await this.sendRPC( "getOutputs", { mixerID: "com.elgato.mix.local" } ); this.selectedOutput = selectedOutput; const { localMixer, streamMixer } = await this.sendRPC("getOutputConfig"); const inputs = await this.sendRPC( "getInputConfigs" ); this.emit("initialiseChannels", { inputs, outputs: { localMixer, streamMixer }, selectedOutput }); callback(); }; this.websocket.onclose = () => { this.isConnecting = false; this.emit("websocketClose"); setTimeout(async () => { try { await this.connect(true); } catch (err) { } }, 5e3); }; this.websocket.onerror = (evt) => { setTimeout(async () => { try { await this.connect(true); } catch (err) { } }, 5e3); }; this.websocket.onmessage = async (evt) => { if (typeof evt.data === "string") { const data = JSON.parse(evt.data); switch (data.method) { case "inputsChanged": const newInputs = await this.sendRPC( "getInputConfigs" ); this.emit("inputsChanged", newInputs); break; case "selectedOutputChanged": this.selectedOutput = data.params.value; this.emit("selectedOutputChanged", data.params.value); break; default: if (data.method === "realTimeChanges") return; const eventData = getWaveLinkEventData( data.method, data.params, this.selectedOutput ); if (eventData) { this.emit(data.method, eventData); } break; } if (data.id) { const callback2 = this.emittedIdsMap.get(data.id); if (callback2) { callback2(data.result); } } } }; } initRPC() { this.rpc.toStream = (msg) => { try { const { id } = JSON.parse(msg); this.lastId = id; this.websocket.send(msg); } catch (error) { console.log("ERROR:", error); } }; } async sendRPC(method, params = {}) { return new Promise((resolve) => { this.sendRPCProxy(method, params, resolve); }); } sendRPCProxy(method, params, callback) { const id = ++this.lastId; this.emittedIdsMap.set(id, callback); this.rpc.call(method, params, id); } }; // src/index.ts var import_simple_jsonrpc_js = __toESM(require("simple-jsonrpc-js")); // src/Base/WaveLinkFilterController.ts var WaveLinkFilterController = class extends BaseController { constructor(rpc, waveLinkEmitter, filter, channelIdentifier) { super(); this.rpc = rpc; this.#id = filter.filterID; this.#name = filter.name; this.#muted = !filter.isActive; this.#pluginID = filter.pluginID; this.#channelIdentifier = channelIdentifier; waveLinkEmitter.on("filterChanged", ({ identifier, filterID, value }) => { if (identifier === this.#channelIdentifier && filterID === this.#id) { this.#muted = !value; this.emit("muteChanged", this.#muted); this.emit(value ? "unmute" : "mute"); } }); } #id = ""; #name = ""; #muted = true; #pluginID = ""; #channelIdentifier = ""; get id() { return this.#id; } get name() { return this.#name; } get muted() { return this.#muted; } get pluginID() { return this.#pluginID; } set muted(shouldMute) { shouldMute ? this.mute() : this.unmute(); } mute() { this.rpc.call("setFilter", { filterID: this.id, identifier: this.#channelIdentifier, value: false }); } unmute() { this.rpc.call("setFilter", { filterID: this.id, identifier: this.#channelIdentifier, value: true }); } }; // src/Base/WaveLinkInputController.ts var WaveLinkInputController = class extends BaseController { #rpc; #waveLinkEmitter; #FILTERS = []; #name = ""; #bgColor = ""; #iconData = ""; #inputType = 0; #identifier = ""; #isAvailable = false; #localVolume = 0; #localMute = false; #streamVolume = 0; #streamMute = false; #localFiltersMuted = false; #streamFiltersMuted = false; constructor(rpc, waveLinkEmitter, input) { super(); input.filters?.forEach((filter) => { this.#FILTERS.push( new WaveLinkFilterController( rpc, waveLinkEmitter, filter, input.identifier ) ); }); this.#rpc = rpc; this.#identifier = input.identifier; this.#bgColor = input.bgColor; this.#iconData = input.iconData; this.#inputType = input.inputType; this.#isAvailable = input.isAvailable; this.#name = input.name; this.#waveLinkEmitter = waveLinkEmitter; this.#localMute = input.localMixer[0]; this.#localVolume = input.localMixer[1]; this.#streamMute = input.streamMixer[0]; this.#streamVolume = input.streamMixer[1]; this.#waveLinkEmitter.on( "filterBypassStateChanged", ({ identifier, mixerID, value }) => { if (identifier === this.#identifier) { if (mixerID === "com.elgato.mix.local") { this.#localFiltersMuted = value; this.emit("localFiltersMuteChanged", value); } else if (mixerID === "com.elgato.mix.stream") { this.#streamFiltersMuted = value; this.emit("streamFiltersMuteChanged", value); } } } ); this.#waveLinkEmitter.on( "inputVolumeChanged", ({ identifier, mixerID, value }) => { if (identifier === this.#identifier) { if (mixerID === "com.elgato.mix.local") { this.#localVolume = value; this.emit("localVolumeChanged", value); this.emit("volumeChanged", { localVolume: this.#localVolume, streamVolume: this.#streamVolume, localMute: this.#localMute, streamMute: this.#streamMute }); } else if (mixerID === "com.elgato.mix.stream") { this.#streamVolume = value; this.emit("streamVolumeChanged", value); this.emit("volumeChanged", { localVolume: this.#localVolume, streamVolume: this.#streamVolume, localMute: this.#localMute, streamMute: this.#streamMute }); } } } ); this.#waveLinkEmitter.on( "inputMuteChanged", ({ identifier, mixerID, value }) => { if (identifier === this.#identifier) { if (mixerID === "com.elgato.mix.local") { this.#localMute = value; this.emit("localMuteChanged", value); this.emit("muteChanged", { localMute: this.#localMute, streamMute: this.#streamMute, streamVolume: this.#streamVolume, localVolume: this.#localVolume }); } else if (mixerID === "com.elgato.mix.stream") { this.#streamMute = value; this.emit("streamMuteChanged", value); this.emit("muteChanged", { localMute: this.#localMute, streamMute: this.#streamMute, streamVolume: this.#streamVolume, localVolume: this.#localVolume }); } } } ); this.#waveLinkEmitter.on( "inputsChanged", (inputs) => { const newInput = inputs.find( (input2) => input2.identifier === this.#identifier ); if (!newInput) { return; } this.#name = newInput.name; this.#bgColor = newInput.bgColor; this.#iconData = newInput.iconData; this.#inputType = newInput.inputType; this.#isAvailable = newInput.isAvailable; } ); this.#waveLinkEmitter.on( "inputNameChanged", ({ identifier, value }) => { if (identifier === this.#identifier) { this.#name = value; this.emit("nameChanged", value); } } ); this.#waveLinkEmitter.on("websocketClose", () => { this.#FILTERS.forEach((filter) => { for (const filterEvent of waveLinkFilterEvents) { filter.removeAllListeners(filterEvent); } filter = null; }); this.#FILTERS = []; }); } getFilter({ name, filterID }) { return this.#FILTERS.find( (filter) => name && filter.name === name || filterID && filter.id === filterID ); } get identifier() { return this.#identifier; } get filters() { return this.#FILTERS; } get bgColor() { return this.#bgColor; } get iconData() { return this.#iconData; } get inputType() { return this.#inputType; } get isAvailable() { return this.#isAvailable; } get name() { return this.#name; } get localFiltersMute() { return this.#localFiltersMuted; } get streamFiltersMute() { return this.#streamFiltersMuted; } get localVolume() { return this.#localVolume; } get streamVolume() { return this.#streamVolume; } get localMute() { return this.#localMute; } get streamMute() { return this.#streamMute; } set localVolume(volume) { this.#rpc.call("setInputConfig", { identifier: this.#identifier, mixerID: "com.elgato.mix.local", property: "Volume", value: volume }); } set streamVolume(volume) { this.#rpc.call("setInputConfig", { identifier: this.#identifier, mixerID: "com.elgato.mix.stream", property: "Volume", value: volume }); } set localMute(isMuted) { this.#rpc.call("setInputConfig", { identifier: this.#identifier, mixerID: "com.elgato.mix.local", property: "Mute", value: isMuted }); } set streamMute(isMuted) { this.#rpc.call("setInputConfig", { identifier: this.#identifier, mixerID: "com.elgato.mix.stream", property: "Mute", value: isMuted }); } set localFiltersMute(isMuted) { this.#rpc.call("setFilterBypass", { identifier: this.#identifier, mixerID: "com.elgato.mix.local", value: isMuted }); } set streamFiltersMute(isMuted) { this.#rpc.call("setFilterBypass", { identifier: this.#identifier, mixerID: "com.elgato.mix.stream", value: isMuted }); } muteLocal() { this.localMute = true; } unmuteLocal() { this.localMute = false; } muteStream() { this.streamMute = true; } unmuteStream() { this.streamMute = false; } }; // src/Base/WaveLinkOutputController.ts var WaveLinkOutputController = class extends BaseController { #rpc; #waveLinkEmitter; #identifier = ""; #localVolume = 0; #localMute = false; #streamVolume = 0; #streamMute = false; constructor(rpc, waveLinkEmitter, identifier, localMixer, streamMixer) { super(); this.#rpc = rpc; this.#waveLinkEmitter = waveLinkEmitter; this.#identifier = identifier; this.#localMute = localMixer[0]; this.#localVolume = localMixer[1]; this.#streamMute = streamMixer[0]; this.#streamVolume = streamMixer[1]; this.#waveLinkEmitter.on( "outputVolumeChanged", async ({ selectedOutput, mixerID, value }) => { if (this.#identifier === selectedOutput) { if (mixerID === "com.elgato.mix.local") { this.#localVolume = value; this.emit("localVolumeChanged", value); this.emit("volumeChanged", { localVolume: this.#localVolume, streamVolume: this.#streamVolume, localMute: this.#localMute, streamMute: this.#streamMute }); } else if (mixerID === "com.elgato.mix.stream") { this.#streamVolume = value; this.emit("streamVolumeChanged", value); this.emit("volumeChanged", { localVolume: this.#localVolume, streamVolume: this.#streamVolume, localMute: this.#localMute, streamMute: this.#streamMute }); } } } ); this.#waveLinkEmitter.on( "outputMuteChanged", ({ selectedOutput, mixerID, value }) => { if (this.#identifier === selectedOutput) { if (mixerID === "com.elgato.mix.local") { this.#localMute = value; this.emit("localMuteChanged", value); this.emit("muteChanged", { localMute: this.#localMute, streamMute: this.#streamMute, streamVolume: this.#streamVolume, localVolume: this.#localVolume }); } else if (mixerID === "com.elgato.mix.stream") { this.#streamMute = value; this.emit("streamMuteChanged", value); this.emit("muteChanged", { localMute: this.#localMute, streamMute: this.#streamMute, streamVolume: this.#streamVolume, localVolume: this.#localVolume }); } } } ); this.#waveLinkEmitter.on("selectedOutputChanged", (selectedOutput) => { this.#identifier = selectedOutput; this.emit("selectedOutputChanged", selectedOutput); }); waveLinkEmitter.on("websocketClose", () => { for (const eventName of waveLinkOutputEvents) { this.removeAllListeners(eventName); } }); } get identifier() { return this.#identifier; } get localVolume() { return this.#localVolume; } get streamVolume() { return this.#streamVolume; } get localMute() { return this.#localMute; } get streamMute() { return this.#streamMute; } set localVolume(volume) { this.#rpc.call("setOutputConfig", { mixerID: "com.elgato.mix.local", property: "Output Level", value: volume }); } set streamVolume(volume) { this.#rpc.call("setOutputConfig", { mixerID: "com.elgato.mix.stream", property: "Output Level", value: volume }); } set localMute(isMuted) { this.#rpc.call("setOutputConfig", { mixerID: "com.elgato.mix.local", property: "Mute", value: isMuted }); } set streamMute(isMuted) { this.#rpc.call("setOutputConfig", { mixerID: "com.elgato.mix.stream", property: "Mute", value: isMuted }); } muteLocal() { this.localMute = true; } unmuteLocal() { this.localMute = false; } muteStream() { this.streamMute = true; } unmuteStream() { this.streamMute = false; } }; // src/index.ts var WaveLinkController = class extends BaseController { waveLinkController = null; INPUTS = []; OUTPUT; rpc = new import_simple_jsonrpc_js.default(); constructor(host = "127.0.0.1") { super(); this.waveLinkController = new BaseWaveLinkController(this.rpc, host); this.waveLinkController.setMaxListeners(16); this.waveLinkController.on( "initialiseChannels", ({ inputs, outputs, selectedOutput }) => { this.initialiseInputs(inputs); this.initialiseOutputs(outputs, selectedOutput); this.emit("ready"); } ); this.waveLinkController.on("websocketOpen", () => { this.attachCloseListener(); this.emit("websocketOpen"); }); } initialiseInputs(inputs) { inputs.forEach((input) => { this.INPUTS.push( new WaveLinkInputController( this.rpc, this.waveLinkController.getWaveLinkEmmiter(), input ) ); }); } initialiseOutputs(outputs, selectedOutput) { this.OUTPUT = new WaveLinkOutputController( this.rpc, this.waveLinkController.getWaveLinkEmmiter(), selectedOutput, [...outputs.localMixer, false], [...outputs.streamMixer, false] ); } attachCloseListener() { this.waveLinkController.on("websocketClose", () => { setTimeout(() => { waveLinkInternalEventsToBeRemoved.forEach((eventName) => { this.waveLinkController.removeAllListeners(eventName); }); this.INPUTS = []; this.OUTPUT = null; this.emit("websocketClose"); }, 100); }); } async connect() { await this.waveLinkController.connect(); } getOutput() { return this.OUTPUT; } getInputs() { return this.INPUTS; } getInput({ name, identifier }) { return this.INPUTS.find( (input) => input.identifier === identifier || input.name === name ); } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { WaveLinkController, WaveLinkInputController, WaveLinkOutputController }); //# sourceMappingURL=index.js.map