Add the reusable RMS core application (server, web UI, plugins, tests, tools) with generic defaults, GPL licensing, and maintainer context documentation so deployments can consume this repo as software source independent of station-specific overlays.
71 lines
2.2 KiB
JavaScript
71 lines
2.2 KiB
JavaScript
async function createPlugin(ctx) {
|
|
return {
|
|
async execute(action, input = {}) {
|
|
const backendCapability = String(ctx.getSetting("backendCapability", "tx.audio.backend") || "tx.audio.backend").trim() || "tx.audio.backend";
|
|
const mappedAction = mapAction(action);
|
|
if (!mappedAction) {
|
|
throw new Error(`Unknown action: ${action}`);
|
|
}
|
|
const result = await ctx.executeCapability(backendCapability, mappedAction, input, { skipTxSafety: true });
|
|
if (action === "audioStatus") {
|
|
return normalizeAudioStatus(result, input);
|
|
}
|
|
return result;
|
|
},
|
|
async health() {
|
|
return { ok: true };
|
|
}
|
|
};
|
|
}
|
|
|
|
function mapAction(action) {
|
|
switch (String(action || "")) {
|
|
case "audioConnect":
|
|
return "backendStart";
|
|
case "audioDisconnect":
|
|
return "backendStop";
|
|
case "audioStatus":
|
|
return "backendStatus";
|
|
case "audioRegisterClient":
|
|
return "backendRegisterClient";
|
|
case "audioUnregisterClient":
|
|
return "backendUnregisterClient";
|
|
case "audioWriteChunk":
|
|
return "backendWrite";
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function normalizeAudioStatus(result, input) {
|
|
const raw = result && typeof result === "object" ? result : {};
|
|
const userId = String((input && input.userId) || "");
|
|
const running = Boolean(raw.running);
|
|
const ownerUserId = raw.ownerUserId ? String(raw.ownerUserId) : null;
|
|
const enabled = raw.enabled !== false;
|
|
return {
|
|
enabled,
|
|
state: raw.state || (enabled ? (running ? "running" : "disconnected") : "disabled"),
|
|
running,
|
|
clients: Number.isFinite(Number(raw.clients)) ? Number(raw.clients) : 0,
|
|
ownerUserId,
|
|
ownerMatchesCaller: Boolean(ownerUserId && userId && ownerUserId === userId),
|
|
startedAt: raw.startedAt || null,
|
|
lastError: raw.lastError || null,
|
|
lastExit: raw.lastExit || null,
|
|
ffmpegPath: raw.ffmpegPath || null,
|
|
alsaDevice: raw.alsaDevice || null,
|
|
chunkMs: Number.isFinite(Number(raw.chunkMs)) ? Number(raw.chunkMs) : null,
|
|
wsPath: raw.wsPath || null,
|
|
backend: {
|
|
providerId: raw.providerId || null,
|
|
providerEnabled: raw.providerEnabled !== false,
|
|
state: raw.state || null
|
|
}
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
createPlugin
|
|
};
|