54 lines
1.2 KiB
TypeScript
54 lines
1.2 KiB
TypeScript
"use client"
|
|
|
|
let speechSynth: SpeechSynthesis | null = null
|
|
let voices: SpeechSynthesisVoice[] = []
|
|
|
|
export function initSpeech(): void {
|
|
if (typeof window === "undefined") return
|
|
speechSynth = window.speechSynthesis
|
|
|
|
const loadVoices = () => {
|
|
voices = speechSynth!.getVoices().filter(
|
|
(v) => v.lang.startsWith("es") && v.lang.includes("ES") || v.lang.includes("MX")
|
|
)
|
|
}
|
|
|
|
loadVoices()
|
|
speechSynth.onvoiceschanged = loadVoices
|
|
}
|
|
|
|
export function speak(text: string, rate = 0.85): Promise<void> {
|
|
return new Promise((resolve) => {
|
|
if (!speechSynth) {
|
|
initSpeech()
|
|
}
|
|
if (!speechSynth || typeof window === "undefined") {
|
|
resolve()
|
|
return
|
|
}
|
|
|
|
window.speechSynthesis.cancel()
|
|
|
|
const utterance = new SpeechSynthesisUtterance(text)
|
|
utterance.lang = "es-ES"
|
|
utterance.rate = rate
|
|
utterance.pitch = 1.1
|
|
|
|
const spanishVoice = voices.length > 0 ? voices[0] : null
|
|
if (spanishVoice) {
|
|
utterance.voice = spanishVoice
|
|
}
|
|
|
|
utterance.onend = () => resolve()
|
|
utterance.onerror = () => resolve()
|
|
|
|
speechSynth.speak(utterance)
|
|
})
|
|
}
|
|
|
|
export function stopSpeaking(): void {
|
|
if (typeof window !== "undefined") {
|
|
window.speechSynthesis.cancel()
|
|
}
|
|
}
|