mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-17 18:10:47 -04:00
service live configslop
This commit is contained in:
@@ -7,7 +7,7 @@ function registerAudioForwardHooks(deps) {
|
||||
roverManager,
|
||||
turnService,
|
||||
logger,
|
||||
serviceEnabled,
|
||||
isServiceEnabled,
|
||||
workers,
|
||||
whipOwners,
|
||||
ensureWorker,
|
||||
@@ -57,7 +57,7 @@ function registerAudioForwardHooks(deps) {
|
||||
stopWorker(roverId);
|
||||
return;
|
||||
}
|
||||
if (action === 'upsert' && serviceEnabled && !workers.has(roverId)) {
|
||||
if (action === 'upsert' && isServiceEnabled() && !workers.has(roverId)) {
|
||||
// A rover coming online should not create ffmpeg publishers by itself.
|
||||
// The audio worker is intentionally lazy because uploads, mic forwarding,
|
||||
// and automatic sounds are the moments that actually need a media pipe;
|
||||
|
||||
@@ -5,7 +5,7 @@ const path = require('path');
|
||||
const EventEmitter = require('events');
|
||||
const io = require('../../globals/io');
|
||||
const logger = require('../../globals/logger').child('audioForwardService');
|
||||
const { loadConfig } = require('../../configuration');
|
||||
const { loadConfig, registerConfigurationHandler } = require('../../configuration');
|
||||
const { resolveRuntimePath } = require('../../helpers/dataPaths');
|
||||
const roverManager = require('../roverManager');
|
||||
const turnService = require('../turnService');
|
||||
@@ -17,18 +17,7 @@ const { registerAudioForwardHooks } = require('./hooks');
|
||||
const { registerChargeCompleteSound } = require('./chargeCompleteSound');
|
||||
|
||||
const audioForwardEvents = new EventEmitter();
|
||||
const config = loadConfig();
|
||||
const audioForwardConfig = config.audioForward || {};
|
||||
const mediaConfig = config.media || {};
|
||||
// Configuration defaults always provide this boolean. Treat only an explicit
|
||||
// true as enabled so no credential, path, or historical fallback can opt the
|
||||
// service in on the operator's behalf.
|
||||
const serviceEnabled = Boolean(audioForwardConfig.enabled);
|
||||
const ffmpegBin = audioForwardConfig.ffmpegBin || 'ffmpeg';
|
||||
const streamSuffix =
|
||||
typeof audioForwardConfig.streamSuffix === 'string' && audioForwardConfig.streamSuffix.trim()
|
||||
? audioForwardConfig.streamSuffix.trim()
|
||||
: '-fwd';
|
||||
let serviceEnabled = false;
|
||||
/*
|
||||
FIFOs and uploaded clips are disposable, but they are deliberately created
|
||||
and managed by this application. A fixed path below SERVER_DATA_DIR keeps the
|
||||
@@ -37,9 +26,6 @@ const streamSuffix =
|
||||
*/
|
||||
const runtimeDir = resolveRuntimePath('audio-forward');
|
||||
const uploadsDir = path.join(runtimeDir, 'uploads');
|
||||
const maxUploadBytes = Number.isFinite(audioForwardConfig.maxUploadBytes)
|
||||
? Math.max(256 * 1024, Math.floor(audioForwardConfig.maxUploadBytes))
|
||||
: 8 * 1024 * 1024;
|
||||
|
||||
const states = new Map(); // roverId -> { state, source, error, startedAt, updatedAt }
|
||||
const workers = new Map(); // roverId -> worker
|
||||
@@ -70,51 +56,67 @@ function getAudioForwardState() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
const audioForwardPolicy = createAudioForwardPolicy({
|
||||
isVerified,
|
||||
isMuted,
|
||||
roverManager,
|
||||
turnService,
|
||||
streamSuffix,
|
||||
mediaConfig,
|
||||
});
|
||||
const {
|
||||
ensureAudioForwardPermission,
|
||||
resolveForwardUrl,
|
||||
resolveForwardPathId,
|
||||
buildWhipUrl,
|
||||
} = audioForwardPolicy;
|
||||
let operations;
|
||||
|
||||
const workerEngine = createAudioForwardWorkerEngine({
|
||||
logger,
|
||||
io,
|
||||
roverManager,
|
||||
turnService,
|
||||
videoSessions,
|
||||
serviceEnabled,
|
||||
ffmpegBin,
|
||||
runtimeDir,
|
||||
uploadsDir,
|
||||
maxUploadBytes,
|
||||
workers,
|
||||
whipOwners,
|
||||
setState,
|
||||
resolveForwardUrl,
|
||||
resolveForwardPathId,
|
||||
});
|
||||
function replaceAudioForwardRuntime(fullConfig) {
|
||||
operations?.stopAllWorkers('configuration-change');
|
||||
const audioForwardConfig = fullConfig.audioForward || {};
|
||||
const mediaConfig = fullConfig.media || {};
|
||||
serviceEnabled = Boolean(audioForwardConfig.enabled);
|
||||
const streamSuffix = typeof audioForwardConfig.streamSuffix === 'string' && audioForwardConfig.streamSuffix.trim()
|
||||
? audioForwardConfig.streamSuffix.trim()
|
||||
: '-fwd';
|
||||
const policy = createAudioForwardPolicy({
|
||||
isVerified,
|
||||
isMuted,
|
||||
roverManager,
|
||||
turnService,
|
||||
streamSuffix,
|
||||
mediaConfig,
|
||||
});
|
||||
const maxUploadBytes = Number.isFinite(audioForwardConfig.maxUploadBytes)
|
||||
? Math.max(256 * 1024, Math.floor(audioForwardConfig.maxUploadBytes))
|
||||
: 8 * 1024 * 1024;
|
||||
operations = {
|
||||
...policy,
|
||||
...createAudioForwardWorkerEngine({
|
||||
logger,
|
||||
io,
|
||||
roverManager,
|
||||
turnService,
|
||||
videoSessions,
|
||||
serviceEnabled,
|
||||
ffmpegBin: audioForwardConfig.ffmpegBin || 'ffmpeg',
|
||||
runtimeDir,
|
||||
uploadsDir,
|
||||
maxUploadBytes,
|
||||
workers,
|
||||
whipOwners,
|
||||
setState,
|
||||
resolveForwardUrl: policy.resolveForwardUrl,
|
||||
resolveForwardPathId: policy.resolveForwardPathId,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
const {
|
||||
ensureWorker,
|
||||
stopWorker,
|
||||
stopAllWorkers,
|
||||
playUploadedAudio,
|
||||
playServerAudioFile,
|
||||
stopPlayback,
|
||||
revokeWhipSessionForRover,
|
||||
stopWhipForRover,
|
||||
stopOwnedAudioIfUnauthorized,
|
||||
startSilenceWriter,
|
||||
} = workerEngine;
|
||||
replaceAudioForwardRuntime(loadConfig());
|
||||
|
||||
// Stable delegates keep the one-time socket/event registrations below pointed
|
||||
// at the newest policy and worker engine after either audio or media changes.
|
||||
const delegate = (name) => (...args) => operations[name](...args);
|
||||
const ensureWorker = delegate('ensureWorker');
|
||||
const stopWorker = delegate('stopWorker');
|
||||
const stopAllWorkers = delegate('stopAllWorkers');
|
||||
const playUploadedAudio = delegate('playUploadedAudio');
|
||||
const playServerAudioFile = delegate('playServerAudioFile');
|
||||
const stopPlayback = delegate('stopPlayback');
|
||||
const revokeWhipSessionForRover = delegate('revokeWhipSessionForRover');
|
||||
const stopWhipForRover = delegate('stopWhipForRover');
|
||||
const stopOwnedAudioIfUnauthorized = delegate('stopOwnedAudioIfUnauthorized');
|
||||
const startSilenceWriter = delegate('startSilenceWriter');
|
||||
const ensureAudioForwardPermission = delegate('ensureAudioForwardPermission');
|
||||
const resolveForwardPathId = delegate('resolveForwardPathId');
|
||||
const buildWhipUrl = delegate('buildWhipUrl');
|
||||
|
||||
function installShutdownHooks() {
|
||||
const shutdown = (signal) => {
|
||||
@@ -136,7 +138,7 @@ registerAudioForwardHooks({
|
||||
roverManager,
|
||||
turnService,
|
||||
logger,
|
||||
serviceEnabled,
|
||||
isServiceEnabled: () => serviceEnabled,
|
||||
workers,
|
||||
whipOwners,
|
||||
ensureWorker,
|
||||
@@ -161,6 +163,13 @@ registerChargeCompleteSound({
|
||||
playServerAudioFile,
|
||||
});
|
||||
|
||||
registerConfigurationHandler('audioForward', (_section, _previous, nextConfig) => {
|
||||
replaceAudioForwardRuntime(nextConfig);
|
||||
});
|
||||
registerConfigurationHandler('media', (_section, _previous, nextConfig) => {
|
||||
replaceAudioForwardRuntime(nextConfig);
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
getAudioForwardState,
|
||||
audioForwardEvents,
|
||||
|
||||
Reference in New Issue
Block a user