export const useWhisper = () => { const isRecording = useState('whisper_isRecording', () => false) const isTranscribing = useState('whisper_isTranscribing', () => false) const transcription = useState('whisper_transcription', () => '') const error = useState('whisper_error', () => null) let mediaRecorder: MediaRecorder | null = null let audioChunks: Blob[] = [] const startRecording = async () => { try { error.value = null // Solicitar permisos de micrófono const stream = await navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, sampleRate: 16000 } }) // Crear MediaRecorder const mimeType = MediaRecorder.isTypeSupported('audio/webm') ? 'audio/webm' : 'audio/mp4' mediaRecorder = new MediaRecorder(stream, { mimeType }) audioChunks = [] mediaRecorder.ondataavailable = (event) => { if (event.data.size > 0) { audioChunks.push(event.data) } } mediaRecorder.onstop = async () => { // Detener todos los tracks del stream stream.getTracks().forEach(track => track.stop()) // Procesar la transcripción await processTranscription() } mediaRecorder.start() isRecording.value = true console.log('[Whisper] Grabación iniciada') } catch (err: any) { console.error('[Whisper] Error al iniciar grabación:', err) error.value = err.message || 'Error al acceder al micrófono' } } const stopRecording = () => { if (mediaRecorder && isRecording.value) { mediaRecorder.stop() isRecording.value = false console.log('[Whisper] Grabación detenida') } } const processTranscription = async () => { try { isTranscribing.value = true error.value = null // Crear blob del audio const audioBlob = new Blob(audioChunks, { type: 'audio/webm' }) console.log('[Whisper] Enviando audio para transcripción:', { size: audioBlob.size, type: audioBlob.type }) // Crear FormData const formData = new FormData() formData.append('file', audioBlob, 'recording.webm') formData.append('language', 'es') // Enviar al backend const response = await $fetch('/api/whisper/transcribe', { method: 'POST', body: formData }) if (response.success) { transcription.value = response.transcription console.log('[Whisper] Transcripción exitosa:', response.transcription) // Copiar al clipboard automáticamente if (navigator.clipboard) { await navigator.clipboard.writeText(response.transcription) console.log('[Whisper] Copiado al clipboard') } } } catch (err: any) { console.error('[Whisper] Error en transcripción:', err) error.value = err.message || 'Error al procesar la transcripción' } finally { isTranscribing.value = false audioChunks = [] } } const clearTranscription = () => { transcription.value = '' error.value = null } const copyToClipboard = async () => { if (transcription.value && navigator.clipboard) { try { await navigator.clipboard.writeText(transcription.value) return true } catch (err) { console.error('[Whisper] Error al copiar:', err) return false } } return false } return { isRecording: readonly(isRecording), isTranscribing: readonly(isTranscribing), transcription: readonly(transcription), error: readonly(error), startRecording, stopRecording, clearTranscription, copyToClipboard } }