This commit is contained in:
legop3
2026-03-20 02:03:25 -04:00
parent cc6e1fde56
commit ab9d388392
+42 -19
View File
@@ -351,6 +351,10 @@ function cleanupUploadFile(worker) {
function stopContentWriter(worker) { function stopContentWriter(worker) {
if (!worker) return; if (!worker) return;
if (worker.micWhipRestartTimer) {
clearTimeout(worker.micWhipRestartTimer);
worker.micWhipRestartTimer = null;
}
if (worker.micIdleTimer) { if (worker.micIdleTimer) {
clearTimeout(worker.micIdleTimer); clearTimeout(worker.micIdleTimer);
worker.micIdleTimer = null; worker.micIdleTimer = null;
@@ -516,37 +520,55 @@ function startMicWhipRelay(roverId, ownerSocketId = null) {
return; return;
} }
worker.contentKind = 'mic_whip';
worker.activeOwnerSocketId = ownerSocketId;
worker.micWhipPathId = resolveMicPathId(roverId);
if (worker.micWhipRestartTimer) {
clearTimeout(worker.micWhipRestartTimer);
worker.micWhipRestartTimer = null;
}
stopContentWriter(worker); stopContentWriter(worker);
cleanupUploadFile(worker); worker.contentKind = 'mic_whip';
worker.activeOwnerSocketId = ownerSocketId;
worker.micWhipPathId = resolveMicPathId(roverId);
setState(roverId, { state: 'starting', source: 'mic-whip', error: null, startedAt: Date.now() });
const launch = () => {
const current = workers.get(roverId);
if (!current || current.stopping) return;
if (current.contentKind !== 'mic_whip' || current.activeOwnerSocketId !== ownerSocketId) return;
const inputUrl = resolveMicReadUrl(roverId); const inputUrl = resolveMicReadUrl(roverId);
const proc = spawnProcess(roverId, 'mic-whip-reader', buildWhipRelayReaderArgs(inputUrl), { const proc = spawnProcess(roverId, 'mic-whip-reader', buildWhipRelayReaderArgs(inputUrl), {
captureStdout: true, captureStdout: true,
}); });
worker.contentProc = proc; current.contentProc = proc;
worker.contentKind = 'mic_whip'; const seq = ++current.writerSeq;
worker.activeOwnerSocketId = ownerSocketId; attachWriterPipe(current, proc);
worker.micWhipPathId = resolveMicPathId(roverId);
const seq = ++worker.writerSeq;
attachWriterPipe(worker, proc);
setState(roverId, { state: 'playing', source: 'mic-whip', error: null, startedAt: Date.now() }); setState(roverId, { state: 'playing', source: 'mic-whip', error: null, startedAt: Date.now() });
proc.on('exit', (code, signal) => { proc.on('exit', (code, signal) => {
const current = workers.get(roverId); const next = workers.get(roverId);
if (!current || current.stopping) return; if (!next || next.stopping) return;
if (current.writerSeq !== seq || current.contentProc !== proc) return; if (next.writerSeq !== seq || next.contentProc !== proc) return;
current.contentProc = null; next.contentProc = null;
current.contentKind = null; if (next.contentKind !== 'mic_whip' || next.activeOwnerSocketId !== ownerSocketId) return;
current.activeOwnerSocketId = null; if (signal === 'SIGTERM') return;
current.micWhipPathId = null;
if (code != null && code !== 0 && signal !== 'SIGTERM') {
setState(roverId, { setState(roverId, {
state: 'error', state: 'starting',
source: 'mic-whip', source: 'mic-whip',
error: `mic whip reader exited code=${code} signal=${signal || 'none'}`, error: code != null && code !== 0 ? `relay reconnecting (last code=${code})` : null,
startedAt: Date.now(),
}); });
} next.micWhipRestartTimer = setTimeout(() => {
startSilenceWriter(roverId); next.micWhipRestartTimer = null;
launch();
}, 300);
}); });
};
launch();
} }
function decodeMicChunk(payload = {}) { function decodeMicChunk(payload = {}) {
@@ -636,6 +658,7 @@ function ensureWorker(roverId) {
activeUploadPath: null, activeUploadPath: null,
micWriter: null, micWriter: null,
micWhipPathId: null, micWhipPathId: null,
micWhipRestartTimer: null,
micLastChunkAt: 0, micLastChunkAt: 0,
micIdleTimer: null, micIdleTimer: null,
micBackpressured: false, micBackpressured: false,