fix(voce): riproduce la sintesi vocale sul display invece che sul controller
Il controller invia un comando 'speak' via WebSocket. Il server inoltra il messaggio solo ai client display, che eseguono speechSynthesis con preferenza per voce italiana.
This commit is contained in:
@@ -481,21 +481,29 @@ export default {
|
||||
},
|
||||
|
||||
speak() {
|
||||
const msg = new SpeechSynthesisUtterance()
|
||||
let text = ''
|
||||
if (this.state.sp.punt.home + this.state.sp.punt.guest === 0) {
|
||||
msg.text = "zero a zero"
|
||||
text = "zero a zero"
|
||||
} else if (this.state.sp.punt.home === this.state.sp.punt.guest) {
|
||||
msg.text = this.state.sp.punt.home + " pari"
|
||||
text = this.state.sp.punt.home + " pari"
|
||||
} else {
|
||||
if (this.state.sp.servHome) {
|
||||
msg.text = this.state.sp.punt.home + " a " + this.state.sp.punt.guest
|
||||
text = this.state.sp.punt.home + " a " + this.state.sp.punt.guest
|
||||
} else {
|
||||
msg.text = this.state.sp.punt.guest + " a " + this.state.sp.punt.home
|
||||
text = this.state.sp.punt.guest + " a " + this.state.sp.punt.home
|
||||
}
|
||||
}
|
||||
const voices = window.speechSynthesis.getVoices()
|
||||
msg.voice = voices.find(v => v.name === 'Google italiano')
|
||||
window.speechSynthesis.speak(msg)
|
||||
if (!this.wsConnected || !this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||||
this.showErrorFeedback('Non connesso al server')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
this.ws.send(JSON.stringify({ type: 'speak', text }))
|
||||
} catch (err) {
|
||||
console.error('[Controller] Failed to send speak command:', err)
|
||||
this.showErrorFeedback('Errore invio comando voce')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,6 +266,8 @@ export default {
|
||||
|
||||
if (msg.type === 'state') {
|
||||
this.state = msg.state
|
||||
} else if (msg.type === 'speak') {
|
||||
this.speakOnDisplay(msg.text)
|
||||
} else if (msg.type === 'error') {
|
||||
console.error('[Display] Server error:', msg.message)
|
||||
}
|
||||
@@ -314,6 +316,27 @@ export default {
|
||||
this.reconnectTimeout = null
|
||||
this.connectWebSocket()
|
||||
}, delay)
|
||||
},
|
||||
speakOnDisplay(text) {
|
||||
if (typeof text !== 'string' || !text.trim()) {
|
||||
return
|
||||
}
|
||||
if (!('speechSynthesis' in window)) {
|
||||
console.warn('[Display] speechSynthesis not supported')
|
||||
return
|
||||
}
|
||||
|
||||
const utterance = new SpeechSynthesisUtterance(text.trim())
|
||||
const voices = window.speechSynthesis.getVoices()
|
||||
const preferredVoice = voices.find((v) => v.name === 'Google italiano')
|
||||
|| voices.find((v) => v.lang && v.lang.toLowerCase().startsWith('it'))
|
||||
if (preferredVoice) {
|
||||
utterance.voice = preferredVoice
|
||||
}
|
||||
utterance.lang = 'it-IT'
|
||||
|
||||
window.speechSynthesis.cancel()
|
||||
window.speechSynthesis.speak(utterance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ export function setupWebSocketHandler(wss) {
|
||||
if (msg.type === 'action') {
|
||||
return handleAction(ws, msg)
|
||||
}
|
||||
|
||||
if (msg.type === 'speak') {
|
||||
return handleSpeak(ws, msg)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error processing message:', err, 'data:', data)
|
||||
// Invia l'errore solo se la connessione e ancora aperta.
|
||||
@@ -98,6 +102,30 @@ export function setupWebSocketHandler(wss) {
|
||||
broadcastState()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestisce una richiesta di sintesi vocale proveniente dal controller.
|
||||
* Il messaggio viene inoltrato solo ai client registrati come display.
|
||||
*/
|
||||
function handleSpeak(ws, msg) {
|
||||
const client = clients.get(ws)
|
||||
if (!client || client.role !== 'controller') {
|
||||
sendError(ws, 'Only controllers can request speech')
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof msg.text !== 'string' || msg.text.trim() === '') {
|
||||
sendError(ws, 'Invalid speak payload')
|
||||
return
|
||||
}
|
||||
|
||||
const speakMsg = JSON.stringify({ type: 'speak', text: msg.text.trim() })
|
||||
clients.forEach((meta, clientWs) => {
|
||||
if (meta.role === 'display' && clientWs.readyState === 1) {
|
||||
clientWs.send(speakMsg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Invia un messaggio di errore al client
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user