iPhone : verrou d'écran (anti-veille), rafraîchissement de la liste, diarisation rééquilibrée

- Wake Lock pendant l'enregistrement : empêche le téléphone de se mettre en
  veille (qui suspendait micro/WebSocket) ; repris au retour au premier plan
- La liste des réunions se rafraîchit au retour sur l'onglet/fenêtre et toutes
  les 20 s : une réunion faite sur l'iPhone apparaît sur le PC sans recharger
- Diarisation : seuil par défaut rééquilibré (0.40) — avait été rendu trop
  conservateur, ne séparait plus deux personnes ; règle NEW_SPEAKER assouplie

https://claude.ai/code/session_01YHMp3EKzr4s6o8w1ygxuUe
This commit is contained in:
Claude committed 2026-06-13 16:03:39 +00:00
1 parent 6f4d15f133
commit 872b71dd76
3 files changed
+31 -4

No files matched your search

+27
View File
@@ -16,6 +16,7 @@ const state = {
silentWarned: false,
sourceNode: null,
paused: false,
wakeLock: null,
};
// couleurs des étiquettes de locuteurs (classes .speaker-0 à .speaker-7)
@@ -137,6 +138,7 @@ async function startRecording() {
state.heardSound = false;
state.silentWarned = false;
state.timerInterval = setInterval(updateTimer, 500);
acquireWakeLock(); // garde l'écran allumé (téléphone)
$('record-btn').textContent = '■ Arrêter';
$('record-btn').classList.add('recording');
$('pause-btn').classList.remove('hidden', 'paused');
@@ -186,6 +188,7 @@ function flushPcm() {
function stopRecording(abrupt = false) {
state.recording = false;
clearInterval(state.timerInterval);
releaseWakeLock();
if (state.sourceNode) state.sourceNode.disconnect();
if (state.workletNode) state.workletNode.disconnect();
if (state.mediaStream) state.mediaStream.getTracks().forEach((t) => t.stop());
@@ -366,6 +369,30 @@ async function copyTranscript() {
// --------------------------------------------------------------------- init
// Verrou d'écran : empêche le téléphone de se mettre en veille pendant
// l'enregistrement (sinon micro/WebSocket suspendus). iOS 16.4+, Android.
async function acquireWakeLock() {
try {
if ('wakeLock' in navigator) {
state.wakeLock = await navigator.wakeLock.request('screen');
}
} catch (e) { /* refusé / non supporté : tant pis */ }
}
function releaseWakeLock() {
try { state.wakeLock && state.wakeLock.release(); } catch (e) {}
state.wakeLock = null;
}
// iOS relâche le verrou quand l'onglet repasse au premier plan : on le reprend
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
if (state.recording) acquireWakeLock();
else loadMeetings(); // rafraîchit la liste en revenant sur l'onglet
}
});
window.addEventListener('focus', () => { if (!state.recording) loadMeetings(); });
// rafraîchit régulièrement la liste (réunions faites depuis un autre appareil)
setInterval(() => { if (!state.recording) loadMeetings(); }, 20000);
$('record-btn').onclick = () => (state.recording ? stopRecording() : startRecording());
$('pause-btn').onclick = togglePause;
$('logout-btn').onclick = async () => { await fetch('/api/logout', { method: 'POST' }); location.href = '/login'; };