From 84cd04a4cfc5039f43d8dc68202769bf55c00ca2 Mon Sep 17 00:00:00 2001 From: Hatmos Date: Sun, 9 Aug 2026 02:29:37 +0200 Subject: [PATCH] fix: ajout de protection anti-mauvais chargement de voix --- client/js/guideVoice.js | 69 ++++++++++++++++++++++++++++++++++---- client/js/main.js | 3 +- server/guideInstruction.js | 2 +- server/socketHandler.js | 4 +-- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/client/js/guideVoice.js b/client/js/guideVoice.js index 71efef5..5ae469e 100644 --- a/client/js/guideVoice.js +++ b/client/js/guideVoice.js @@ -1,12 +1,69 @@ /* guideVoice.js - vocalise les instructions recue du serveur via la synthese vocal du navigateur + Vocalise les instructions recues du serveur via la synthese vocale du navigateur */ -export function speakInstruction(texte) { - speechSynthesis.cancel(); - const enonce = new SpeechSynthesisUtterance(texte); - enonce.lang = "fr-FR"; - speechSynthesis.speak(enonce); +let currentUtterance = null; +let voixChoisie = null; +let voixPretes = false; +let texteEnAttente = null; + +const NOM_VOIX_PREFERE = "French (France)+female1"; + +function resoudreVoix() { + if (voixPretes) return; // deja fait, evite le travail en double + + const voix = speechSynthesis.getVoices(); + if (voix.length === 0) return; // toujours pas chargees + + voixChoisie = + voix.find(v => v.name === NOM_VOIX_PREFERE) || + voix.find(v => v.lang.startsWith("fr")) || + voix[0]; + + voixPretes = true; + console.log("Voix sélectionnée:", voixChoisie?.name); + + if (texteEnAttente) { + const texte = texteEnAttente; + texteEnAttente = null; + jouer(texte); + } +} + +// Piste 1 : l'event, au cas ou il se declenche sur d'autres navigateurs +speechSynthesis.onvoiceschanged = resoudreVoix; + +// Piste 2 : sondage en secours, car onvoiceschanged n'est pas fiable sur Firefox/LibreWolf +const intervalleSondage = setInterval(() => { + resoudreVoix(); + if (voixPretes) clearInterval(intervalleSondage); +}, 200); + +resoudreVoix(); // au cas ou les voix sont deja dispo au chargement du module + +function jouer(texte) { + if (speechSynthesis.speaking) { + speechSynthesis.cancel(); + } + + currentUtterance = new SpeechSynthesisUtterance(texte); + currentUtterance.voice = voixChoisie; + currentUtterance.lang = "fr-FR"; + currentUtterance.onstart = () => console.log("Lecture démarrée"); + currentUtterance.onend = () => console.log("Lecture terminée"); + currentUtterance.onerror = (e) => console.error("Erreur synthèse:", e.error, e); + + speechSynthesis.speak(currentUtterance); +} + +export function speakInstruction(texte) { + if (!voixPretes) { + console.log("Voix pas encore prêtes, mise en attente:", texte); + texteEnAttente = texte; + return; + } + + jouer(texte); } diff --git a/client/js/main.js b/client/js/main.js index 70d7c7f..2e91bff 100644 --- a/client/js/main.js +++ b/client/js/main.js @@ -9,7 +9,7 @@ import { roleState } from "./role.js"; import { render, drawBlind } from "./canvas.js"; import { setupMovement } from "./movement.js"; import { showGameOver, showVictory, updateTimerDisplay } from "./ui.js"; -import { speakInstruction} from "guideVoice.js"; +import { speakInstruction} from "./guideVoice.js"; setupMovement(); @@ -51,5 +51,6 @@ socket.on("timer", (timeLeft) => { }); socket.on("instruction", (data) => { + console.log("Payload recu", data); speakInstruction(data.texte); }) diff --git a/server/guideInstruction.js b/server/guideInstruction.js index 8b7713d..3fa377b 100644 --- a/server/guideInstruction.js +++ b/server/guideInstruction.js @@ -8,7 +8,7 @@ const INSTRUCTION_GUIDE = "instruction"; const INSTRUCTION_INTERVAL_MS = 5000; -function startInstructionLoop(wSS, socket, partnerSocket, pairState, getInstructionTexte) { +function startInstructionLoop(wSS, socket, partnerSocket, pairState, getInstructionText) { const interval = setInterval(() => { if (pairState.gameOver) { clearInterval(interval); diff --git a/server/socketHandler.js b/server/socketHandler.js index 7fad694..3b73f8c 100644 --- a/server/socketHandler.js +++ b/server/socketHandler.js @@ -8,7 +8,7 @@ const gameState = require("./gameState"); const { GAME_DURATION } = require("./config"); const { handleDoorReached } = require("./doorLogic"); const { startTimer } = require("./timer"); -const { startInstruction } = require("./guideInstruction"); +const { startInstructionLoop } = require("./guideInstruction"); function registerSocketHandlers(wSS, socket) { console.log(`Un client s'est connecté : ${socket.id}`); @@ -39,7 +39,7 @@ function registerSocketHandlers(wSS, socket) { partner.emit("status", "Partie prête !"); startTimer(socket, partner, pairState); - startInstructionLoop(io, socket , partner, pairState, () => { + startInstructionLoop(wSS, socket , partner, pairState, () => { return "Descendre de quatre cases, aller a droite de une case, descendre de 1 case"; }); }