Download index.html from tx3bas/speech: direct link, hf CLI and curl.
- Browser
- Download file 5.34 kB
-
https://huggingface.co/spaces/tx3bas/speech/resolve/main/index.html
- Command line
-
hf download hf://spaces/tx3bas/speech/index.html
-
curl -L -o index.html https://huggingface.co/spaces/tx3bas/speech/resolve/main/index.html
5.34 kB
| <html lang="es"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width"> | |
| <title>Text to Speech Descargar Audio</title> | |
| <style> | |
| textarea { | |
| width: 100%; | |
| height: 150px; | |
| } | |
| button { | |
| padding: 10px; | |
| margin: 10px 5px; | |
| cursor: pointer; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h3>Text to Speech - Google Español</h3> | |
| <textarea id="lines" placeholder="Ingresa el texto aquí...">Hola, soy Juan. ¿Tú quién eres? No te conozco.</textarea><br> | |
| <button id="speak">Hablar y Grabar</button> | |
| <button id="pause">Pausar</button> | |
| <button id="resume">Reanudar</button> | |
| <button id="cancel">Cancelar</button> | |
| <a id="download" style="display:none;">Descargar Audio</a> | |
| <script> | |
| // Verifica si el navegador soporta las APIs necesarias | |
| if (!window.speechSynthesis || !window.MediaRecorder || !navigator.mediaDevices.getDisplayMedia) { | |
| alert("Tu navegador no soporta las APIs necesarias para esta función."); | |
| } | |
| let voices = []; | |
| let mediaRecorder; | |
| let chunks = []; | |
| let tts = new SpeechSynthesisUtterance(); | |
| let fragments = []; | |
| let currentFragment = 0; | |
| // Cargar voces y seleccionar "Google español" si está disponible | |
| window.speechSynthesis.onvoiceschanged = () => { | |
| voices = window.speechSynthesis.getVoices(); | |
| let selectedVoice = voices.find(voice => voice.lang === "es-ES" && voice.name.includes("Google")); | |
| if (selectedVoice) { | |
| tts.voice = selectedVoice; | |
| tts.volume = .8; | |
| tts.rate = 1.1; | |
| tts.pitch = 1; | |
| } else { | |
| alert("La voz 'Google español' no está disponible en este navegador."); | |
| } | |
| }; | |
| // Función para dividir el texto en fragmentos (párrafos) | |
| function dividirTexto(texto) { | |
| return texto.match(/[^.!?]+[.!?]+/g) || [texto]; | |
| } | |
| // Función para reproducir el siguiente fragmento | |
| function reproducirSiguienteFragmento() { | |
| if (currentFragment < fragments.length) { | |
| tts.text = fragments[currentFragment].trim(); | |
| window.speechSynthesis.speak(tts); | |
| currentFragment++; | |
| } else { | |
| // Cuando termine de reproducir todos los fragmentos, detener la grabación | |
| mediaRecorder.stop(); | |
| } | |
| } | |
| async function speakAndRecord(text) { | |
| // Solicitar permisos para capturar el audio | |
| let stream; | |
| try { | |
| stream = await navigator.mediaDevices.getDisplayMedia({ audio: true}); | |
| } catch (err) { | |
| console.error("Error al capturar el audio:", err); | |
| alert("No se pudo capturar el audio. Asegúrate de conceder los permisos necesarios."); | |
| return; | |
| } | |
| // Eliminar las pistas de video | |
| const videoTracks = stream.getVideoTracks(); | |
| videoTracks.forEach(track => { | |
| track.stop(); | |
| stream.removeTrack(track); | |
| }); | |
| // Crear MediaRecorder para capturar el audio | |
| mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' }); | |
| chunks = []; | |
| mediaRecorder.ondataavailable = (e) => { | |
| if (e.data.size > 0) { | |
| chunks.push(e.data); | |
| } | |
| }; | |
| mediaRecorder.onstop = () => { | |
| const audioBlob = new Blob(chunks, { type: 'audio/webm' }); | |
| const audioUrl = URL.createObjectURL(audioBlob); | |
| const downloadButton = document.getElementById("download"); | |
| downloadButton.style.display = "inline"; | |
| downloadButton.href = audioUrl; | |
| downloadButton.download = 'tts_audio.webm'; | |
| downloadButton.textContent = 'Descargar Audio'; | |
| }; | |
| // Iniciar la grabación | |
| mediaRecorder.start(); | |
| // Dividir el texto en fragmentos | |
| fragments = dividirTexto(text); | |
| currentFragment = 0; | |
| // Reproducir el primer fragmento | |
| reproducirSiguienteFragmento(); | |
| } | |
| // Cuando termine de hablar un fragmento, pasar al siguiente | |
| tts.onend = () => { | |
| reproducirSiguienteFragmento(); | |
| }; | |
| // Manejo de eventos de los botones | |
| document.getElementById("speak").addEventListener("click", () => { | |
| const text = document.getElementById("lines").value; | |
| speakAndRecord(text); | |
| }); | |
| document.getElementById("pause").addEventListener("click", () => { | |
| window.speechSynthesis.pause(); | |
| }); | |
| document.getElementById("resume").addEventListener("click", () => { | |
| window.speechSynthesis.resume(); | |
| }); | |
| document.getElementById("cancel").addEventListener("click", () => { | |
| window.speechSynthesis.cancel(); | |
| if (mediaRecorder && mediaRecorder.state !== "inactive") { | |
| mediaRecorder.stop(); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |