Download script.js from bhagvat/tts: direct link, hf CLI and curl.
- Browser
- Download file 5.18 kB
-
https://huggingface.co/spaces/bhagvat/tts/resolve/main/script.js
- Command line
-
hf download hf://spaces/bhagvat/tts/script.js
-
curl -L -o script.js https://huggingface.co/spaces/bhagvat/tts/resolve/main/script.js
5.18 kB
| // Fetch data from JSON file and initialize | |
| fetch('BhagvatGlory.json') | |
| .then(response => response.json()) | |
| .then(jsonData => initializeApp(jsonData)) | |
| .catch(error => console.error('Error loading JSON:', error)); | |
| const skandaList = document.getElementById("skanda-list"); | |
| const chapterTitle = document.getElementById("chapter-title"); | |
| const slokeContainer = document.getElementById("sloke-container"); | |
| function initializeApp(data) { | |
| // Populate Skanda and Chapter List | |
| const skandaItem = document.createElement("li"); | |
| skandaItem.textContent = data.skandaTitle; | |
| const chapterList = document.createElement("ul"); | |
| data.chapters.forEach((chapter, chapterIndex) => { | |
| const chapterItem = document.createElement("li"); | |
| chapterItem.textContent = chapter.chapterTitle; | |
| chapterItem.onclick = () => displayChapter(chapter); | |
| chapterList.appendChild(chapterItem); | |
| }); | |
| skandaItem.appendChild(chapterList); | |
| skandaList.appendChild(skandaItem); | |
| } | |
| // Display Slokes | |
| function displayChapter(chapter) { | |
| chapterTitle.textContent = chapter.chapterTitle; | |
| slokeContainer.innerHTML = ""; | |
| const slokes = chapter.slokes | |
| .replace(/श्लोक\s*\d+:/g, "") // Remove "श्लोक-X" | |
| .trim() | |
| .split("\n"); // Split by newline | |
| slokes.forEach((sloke, index) => { | |
| const slokeItem = document.createElement("div"); | |
| slokeItem.className = "sloke-item"; | |
| const slokeText = document.createElement("p"); | |
| slokeText.textContent = sloke.trim(); | |
| const speakButton = document.createElement("button"); | |
| speakButton.textContent = "Speak"; | |
| speakButton.onclick = () => speakSloke(sloke.trim()); | |
| const downloadButton = document.createElement("button"); | |
| downloadButton.textContent = "Download"; | |
| downloadButton.onclick = () => downloadAudio(sloke.trim(), `sloke-${index + 1}.wav`); | |
| slokeItem.appendChild(slokeText); | |
| slokeItem.appendChild(speakButton); | |
| slokeItem.appendChild(downloadButton); | |
| slokeContainer.appendChild(slokeItem); | |
| }); | |
| } | |
| // Speak Sloke with Advanced Features | |
| function speakSloke(text) { | |
| // Normalize and preprocess the text | |
| const normalizedText = text | |
| .normalize("NFC") | |
| .replace(/ऽ/g, " "); // Replace avagraha with a space for better pronunciation | |
| // Split the text into meaningful phrases | |
| const phrases = normalizedText.split(/[।॥]/).filter(phrase => phrase.trim().length > 0); | |
| let phraseIndex = 0; | |
| function speakNextPhrase() { | |
| if (phraseIndex >= phrases.length) return; | |
| const currentPhrase = phrases[phraseIndex].trim(); | |
| const utterance = new SpeechSynthesisUtterance(currentPhrase); | |
| // Set voice and TTS parameters for a bold, heavy tone | |
| utterance.lang = "sa-IN"; | |
| utterance.pitch = 0.8; // Lower pitch for a deeper, heavier voice | |
| utterance.rate = 0.8; // Slower rate for gravitas and clarity | |
| utterance.volume = 1.0; // Full volume for boldness | |
| // Select the male Sanskrit voice | |
| const voices = speechSynthesis.getVoices(); | |
| utterance.voice = voices.find(voice => voice.lang === "sa-IN" && voice.name.includes("Male")); | |
| // Handle completion of the current phrase | |
| utterance.onend = () => { | |
| phraseIndex++; | |
| setTimeout(speakNextPhrase, 500); // Slightly longer pause for dramatic effect | |
| }; | |
| // Handle errors gracefully | |
| utterance.onerror = (error) => { | |
| console.error(`Error speaking phrase: ${currentPhrase}`, error); | |
| phraseIndex++; | |
| setTimeout(speakNextPhrase, 500); | |
| }; | |
| console.log(`Speaking phrase with bold voice: ${currentPhrase}`); // Debugging | |
| speechSynthesis.speak(utterance); | |
| } | |
| speakNextPhrase(); // Start speaking the sloke | |
| } | |
| // Speak Sloke | |
| // function speakSloke(text) { | |
| // alert(text) | |
| // const utterance = new SpeechSynthesisUtterance(text); | |
| // utterance.lang = "sa-IN"; | |
| // utterance.rate = 0.8; | |
| // utterance.pitch = 1.0; | |
| // const voices = speechSynthesis.getVoices(); | |
| // utterance.voice = voices.find(voice => voice.lang === "sa-IN" && voice.name.includes("Male")); | |
| // speechSynthesis.speak(utterance); | |
| // } | |
| // Download Audio | |
| function downloadAudio(text, filename) { | |
| const utterance = new SpeechSynthesisUtterance(text); | |
| utterance.lang = "sa-IN"; | |
| const audioChunks = []; | |
| const streamDestination = new MediaStreamAudioDestinationNode(new AudioContext()); | |
| const mediaRecorder = new MediaRecorder(streamDestination.stream); | |
| utterance.onstart = () => mediaRecorder.start(); | |
| utterance.onend = () => { | |
| mediaRecorder.stop(); | |
| const audioBlob = new Blob(audioChunks, { type: "audio/wav" }); | |
| const audioUrl = URL.createObjectURL(audioBlob); | |
| const link = document.createElement("a"); | |
| link.href = audioUrl; | |
| link.download = filename; | |
| link.click(); | |
| }; | |
| mediaRecorder.ondataavailable = event => audioChunks.push(event.data); | |
| speechSynthesis.speak(utterance); | |
| } | |