La recherche auto de micro ne s'active plus qu'au démarrage

Un silence en cours de réunion (normal) déclenchait des bascules de micro
intempestives qui cassaient la capture. Désormais : recherche uniquement
tant qu'aucun son n'a jamais été capté ; dès qu'un micro a fait ses preuves,
on n'y touche plus (sauf changement manuel).

https://claude.ai/code/session_01YHMp3EKzr4s6o8w1ygxuUe
This commit is contained in:
Claude committed 2026-06-12 18:41:59 +00:00
1 parent 13be3030be
commit 8f1ebe5545
1 file changed
+29 -16
+29 -16
View File
@@ -12,6 +12,7 @@ const state = {
startedAt: null, startedAt: null,
currentMeetingId: null, currentMeetingId: null,
lastLoudAt: 0, lastLoudAt: 0,
heardSound: false, // un micro a déjà capté du son : on ne change plus
silentWarned: false, silentWarned: false,
sourceNode: null, sourceNode: null,
gainNode: null, gainNode: null,
@@ -166,6 +167,7 @@ async function startRecording() {
state.paused = false; state.paused = false;
state.startedAt = Date.now(); state.startedAt = Date.now();
state.lastLoudAt = Date.now(); state.lastLoudAt = Date.now();
state.heardSound = false;
state.silentWarned = false; state.silentWarned = false;
state.autoMicQueue = null; state.autoMicQueue = null;
state.timerInterval = setInterval(updateTimer, 500); state.timerInterval = setInterval(updateTimer, 500);
@@ -197,7 +199,10 @@ function updateVu(samples) {
if (v > peak) peak = v; if (v > peak) peak = v;
} }
$('vu-bar').style.width = Math.min(100, (peak / 32768) * 140) + '%'; $('vu-bar').style.width = Math.min(100, (peak / 32768) * 140) + '%';
if (peak > 1500) state.lastLoudAt = Date.now(); if (peak > 1500) {
state.lastLoudAt = Date.now();
state.heardSound = true;
}
autoGain(peak); autoGain(peak);
} }
@@ -304,22 +309,26 @@ function updateTimer() {
$('timer').textContent = $('timer').textContent =
String(Math.floor(s / 60)).padStart(2, '0') + ':' + String(s % 60).padStart(2, '0'); String(Math.floor(s / 60)).padStart(2, '0') + ':' + String(s % 60).padStart(2, '0');
// micro muet depuis 5 s : on essaie automatiquement les autres micros // Recherche automatique de micro : UNIQUEMENT tant qu'aucun son n'a
if (!state.recording || state.paused) return; // jamais été capté depuis le début (un silence en cours de réunion est
const silent = Date.now() - state.lastLoudAt > 5000; // normal et ne doit jamais déclencher un changement de micro).
if (silent) { if (!state.recording || state.paused || state.heardSound) {
if (state.silentWarned && state.heardSound) {
// le micro fonctionne : on le mémorise et on arrête la recherche
state.silentWarned = false;
state.autoMicQueue = null;
const id = state.mediaStream?.getAudioTracks()[0]?.getSettings().deviceId;
if (id) {
localStorage.setItem('liveflow-mic', id);
$('mic-select').value = id;
}
setStatus('rec', 'Enregistrement…');
}
return;
}
if (Date.now() - state.lastLoudAt > 5000) {
state.silentWarned = true; state.silentWarned = true;
autoNextMic(); autoNextMic();
} else if (state.silentWarned) {
// un micro qui capte du son a été trouvé : on le mémorise
state.silentWarned = false;
state.autoMicQueue = null;
const id = state.mediaStream?.getAudioTracks()[0]?.getSettings().deviceId;
if (id) {
localStorage.setItem('liveflow-mic', id);
$('mic-select').value = id;
}
setStatus('rec', 'Enregistrement…');
} }
} }
@@ -419,7 +428,11 @@ $('logout-btn').onclick = async () => { await fetch('/api/logout', { method: 'PO
$('mic-select').onchange = async () => { $('mic-select').onchange = async () => {
const id = $('mic-select').value; const id = $('mic-select').value;
localStorage.setItem('liveflow-mic', id); localStorage.setItem('liveflow-mic', id);
if (state.recording) await switchMic(id || undefined); // bascule à chaud if (state.recording) {
await switchMic(id || undefined); // bascule à chaud
state.heardSound = false; // le nouveau micro doit faire ses preuves
state.autoMicQueue = null;
}
}; };
listMics(); listMics();
$('copy-btn').onclick = copyTranscript; $('copy-btn').onclick = copyTranscript;