← back to Dear Bubbe Nextjs
components/SimpleTTS.tsx
85 lines
'use client'
import { useEffect } from 'react'
interface SimpleTTSProps {
text: string | null
onEnd?: () => void
}
export default function SimpleTTS({ text, onEnd }: SimpleTTSProps) {
useEffect(() => {
if (!text || typeof window === 'undefined') return
// Use browser's built-in speech synthesis
if (!('speechSynthesis' in window)) {
console.error('Speech synthesis not supported')
return
}
console.log('🔊 SPEAKING:', text.substring(0, 50))
// Cancel any ongoing speech
window.speechSynthesis.cancel()
// Create and configure utterance
const utterance = new SpeechSynthesisUtterance(text)
utterance.rate = 0.95 // Slightly slower
utterance.pitch = 1.1 // Slightly higher for Bubbe
utterance.volume = 1.0 // Full volume
utterance.lang = 'en-US'
// Get voices and try to use a female one
const setVoice = () => {
const voices = window.speechSynthesis.getVoices()
if (voices.length > 0) {
// Try to find a female voice
const femaleVoice = voices.find(v =>
v.name.toLowerCase().includes('female') ||
v.name.toLowerCase().includes('samantha') ||
v.name.toLowerCase().includes('victoria') ||
v.name.toLowerCase().includes('karen')
) || voices.find(v => v.lang === 'en-US') || voices[0]
if (femaleVoice) {
utterance.voice = femaleVoice
console.log('Using voice:', femaleVoice.name)
}
}
}
// Try to set voice immediately
setVoice()
// Also try when voices are loaded
window.speechSynthesis.onvoiceschanged = setVoice
// Event handlers
utterance.onstart = () => {
console.log('🎤 Speech started')
}
utterance.onend = () => {
console.log('✅ Speech finished')
if (onEnd) onEnd()
}
utterance.onerror = (event) => {
console.error('❌ Speech error:', event.error)
if (onEnd) onEnd()
}
// Small delay to ensure everything is ready
setTimeout(() => {
window.speechSynthesis.speak(utterance)
console.log('🗣️ Bubbe is kvetching!')
}, 100)
// Cleanup
return () => {
window.speechSynthesis.cancel()
}
}, [text, onEnd])
return null // This component doesn't render anything
}