indic-tts / index.html
kshvchvr's picture
Update index.html
1537fee verified
Raw
History Blame Contribute Delete
9.19 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Indic TTS — Swadesh</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 16px;
padding: 32px;
max-width: 600px;
width: 100%;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
h1 {
text-align: center;
margin-bottom: 8px;
color: #333;
font-size: 1.6em;
}
.subtitle {
text-align: center;
color: #888;
margin-bottom: 24px;
font-size: 0.9em;
}
label {
display: block;
margin-bottom: 6px;
font-weight: 600;
color: #555;
font-size: 0.9em;
}
textarea {
width: 100%;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
resize: vertical;
min-height: 100px;
font-family: inherit;
transition: border-color 0.2s;
}
textarea:focus { outline: none; border-color: #667eea; }
select {
width: 100%;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
background: white;
cursor: pointer;
margin-bottom: 20px;
}
select:focus { outline: none; border-color: #667eea; }
.btn {
width: 100%;
padding: 14px;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: opacity 0.2s;
}
.btn:hover { opacity: 0.9; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.status {
margin-top: 16px;
padding: 12px;
border-radius: 8px;
text-align: center;
font-size: 0.9em;
display: none;
}
.status.loading { display: block; background: #fff3cd; color: #856404; }
.status.error { display: block; background: #f8d7da; color: #721c24; }
.status.success { display: block; background: #d4edda; color: #155724; }
audio {
width: 100%;
margin-top: 16px;
display: none;
}
.footer {
text-align: center;
margin-top: 20px;
color: #aaa;
font-size: 0.8em;
}
</style>
</head>
<body>
<div class="container">
<h1>Indic TTS — Swadesh</h1>
<p class="subtitle">21 Indian Languages — AI4Bharat Model</p>
<label for="text">Text</label>
<textarea id="text" placeholder="Type text here... / yahan text likhein..."></textarea>
<label for="lang">Language</label>
<select id="lang">
<option value="hi">Hindi</option>
<option value="bn">Bengali</option>
<option value="ta">Tamil</option>
<option value="te">Telugu</option>
<option value="mr">Marathi</option>
<option value="kn">Kannada</option>
<option value="ml">Malayalam</option>
<option value="gu">Gujarati</option>
<option value="or">Odia</option>
<option value="ur">Urdu</option>
<option value="en">English</option>
<option value="as">Assamese</option>
<option value="ne">Nepali</option>
<option value="sa">Sanskrit</option>
<option value="mai">Maithili</option>
<option value="brx">Bodo</option>
<option value="doi">Dogri</option>
<option value="kok">Konkani</option>
<option value="mni">Manipuri</option>
<option value="sat">Santali</option>
<option value="sd">Sindhi</option>
</select>
<button class="btn" id="btn" onclick="generate()">Generate Speech</button>
<div class="status" id="status"></div>
<audio id="audio" controls></audio>
<p class="footer">Powered by <a href="https://huggingface.co/spaces/ai4bharat/indic-parler-tts" target="_blank">AI4Bharat Indic Parler-TTS</a></p>
</div>
<script type="module">
import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
const LANG_NAMES = {
as:"Assamese", bn:"Bengali", brx:"Bodo", doi:"Dogri",
en:"English", gu:"Gujarati", hi:"Hindi", kn:"Kannada",
kok:"Konkani", mai:"Maithili", ml:"Malayalam", mni:"Manipuri",
mr:"Marathi", ne:"Nepali", or:"Odia", sa:"Sanskrit",
sat:"Santali", sd:"Sindhi", ta:"Tamil", te:"Telugu", ur:"Urdu"
};
const SPEAKER_NAMES = {
as:"Sita", bn:"Aditi", brx:"Maya", doi:"Karan",
en:"Mary", gu:"Neha", hi:"Divya", kn:"Anu",
kok:"Sita", mai:"Sita", ml:"Anjali", mni:"Laishram",
mr:"Sunita", ne:"Amrita", or:"Debjani", sa:"Aryan",
sat:"Sita", sd:"Sita", ta:"Jaya", te:"Lalitha", ur:"Sita"
};
let client = null;
async function getClient() {
if (!client) {
const status = document.getElementById("status");
status.className = "status loading";
status.textContent = "Connecting to AI4Bharat server...";
status.style.display = "block";
client = await Client.connect("https://indic-tts-api.onrender.com/");
status.style.display = "none";
}
return client;
}
window.generate = async function() {
const text = document.getElementById("text").value.trim();
const lang = document.getElementById("lang").value;
const btn = document.getElementById("btn");
const status = document.getElementById("status");
const audio = document.getElementById("audio");
if (!text) {
status.className = "status error";
status.textContent = "Please enter some text.";
status.style.display = "block";
return;
}
btn.disabled = true;
btn.textContent = "Generating...";
audio.style.display = "none";
status.className = "status loading";
status.textContent = "Loading model & generating speech... This may take 30-60 seconds on first use.";
status.style.display = "block";
try {
const c = await getClient();
const speaker = SPEAKER_NAMES[lang] || "Divya";
const langName = LANG_NAMES[lang] || "Hindi";
const description = speaker + " speaks " + langName + " fluently with a native accent. Her voice is clear, warm, and expressive, with a moderate pace and pitch, using a friendly storytelling tone suited for children. The recording is of very high quality, with the speaker's voice sounding close up and easy to understand, in a quiet room with no background noise.";
const result = await c.predict("/generate_tts", [text, description]);
if (result.data && result.data[0]) {
const audioData = result.data[0];
let audioUrl;
if (typeof audioData === "object" && audioData.url) {
audioUrl = audioData.url;
} else if (typeof audioData === "string") {
audioUrl = audioData;
} else {
audioUrl = URL.createObjectURL(new Blob([new Uint8Array(audioData)], { type: "audio/wav" }));
}
audio.src = audioUrl;
audio.style.display = "block";
audio.play();
status.className = "status success";
status.textContent = "Audio generated successfully!";
} else {
throw new Error("No audio data received");
}
} catch (err) {
status.className = "status error";
status.textContent = "Error: " + err.message + ". The AI4Bharat server may be temporarily down. Try again later.";
console.error(err);
} finally {
btn.disabled = false;
btn.textContent = "Generate Speech";
}
};
</script>
</body>
</html>