VoiceScript / frontend /index.html
Tusharz's picture
feat: add multilingual transcription, translation, timestamps, export TXT/SRT/PDF, animated UI
3e9a7ba
Raw
History Blame Contribute Delete
10.5 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VoiceScript — AI Speech Recognition</title>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header class="header">
<div class="header-inner">
<div class="logo">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<rect width="32" height="32" rx="8" fill="#6366f1"/>
<rect x="6" y="12" width="3" height="8" rx="1.5" fill="white"/>
<rect x="11" y="8" width="3" height="16" rx="1.5" fill="white"/>
<rect x="16" y="5" width="3" height="22" rx="1.5" fill="white"/>
<rect x="21" y="9" width="3" height="14" rx="1.5" fill="white"/>
<rect x="26" y="13" width="3" height="6" rx="1.5" fill="white"/>
</svg>
<span>VoiceScript</span>
</div>
<div class="header-badge">AI Powered</div>
</div>
</header>
<main class="main">
<section class="hero">
<div class="hero-pill">✦ Powered by OpenAI Whisper + Facebook Demucs</div>
<h1 class="hero-title">
Turn your voice<br/>into <span class="accent">text instantly</span>
</h1>
<p class="hero-sub">
Upload any audio file or record live — our AI transcribes, translates and exports in seconds.
</p>
</section>
<div class="cards-grid">
<div class="card">
<div class="card-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
</div>
<h2 class="card-title">Upload Audio File</h2>
<p class="card-desc">Supports WAV, MP3, FLAC, OGG, WebM</p>
<input type="file" id="audio-file-input" accept=".wav,.mp3,.flac,.ogg,.webm" hidden />
<div class="drop-zone" id="drop-zone" onclick="document.getElementById('audio-file-input').click()">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" style="opacity:0.4;margin-bottom:6px"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
<p id="drop-text">Click to choose a file or drag &amp; drop</p>
<span id="file-name-display" class="file-name-display"></span>
</div>
<div class="mode-toggle">
<button class="mode-btn active" id="mode-transcribe" onclick="setMode('transcribe')">Transcribe</button>
<button class="mode-btn" id="mode-translate" onclick="setMode('translate_to_english')">Any Language → English</button>
</div>
<button class="btn btn-primary" onclick="uploadAndTranscribe()">Transcribe File</button>
</div>
<div class="card">
<div class="card-icon card-icon-pink">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 00-3 3v8a3 3 0 006 0V4a3 3 0 00-3-3z"/><path d="M19 10v2a7 7 0 01-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>
</div>
<h2 class="card-title">Record Live</h2>
<p class="card-desc">Speak directly into your microphone</p>
<div class="record-visualizer" id="record-visualizer">
<div class="pulse-wrap">
<div class="pulse-ring"></div>
<div class="pulse-dot"></div>
</div>
<span id="record-status">Ready to record</span>
</div>
<div class="record-timer" id="record-timer">00:00</div>
<div class="record-btns">
<button class="btn btn-record" id="start-btn" onclick="startRecording()">Start Recording</button>
<button class="btn btn-stop" id="stop-btn" onclick="stopRecording()" disabled>Stop &amp; Transcribe</button>
</div>
</div>
</div>
<section class="results-section" id="results-section">
<div class="loading-state" id="loading-state">
<div class="spinner"></div>
<p id="loading-msg">Starting beast mode pipeline...</p>
<p class="loading-hint">⏳ Demucs + Whisper AI processing — please don't close this tab</p>
</div>
<div class="result-box" id="result-box">
<div class="result-header">
<h3 class="result-title">Transcript</h3>
<div class="result-header-right">
<span class="lang-badge" id="lang-badge" style="display:none;"></span>
<button class="btn-timestamps" id="timestamps-btn" onclick="toggleTimestamps()" style="display:none;">⏱ Timestamps</button>
<button class="btn-copy" id="copy-btn" onclick="copyTranscript()">Copy Text</button>
</div>
</div>
<p class="transcript-text" id="transcript-text"></p>
<div class="timestamps-view" id="timestamps-view" style="display:none;"></div>
<div class="result-meta">
<span id="word-count"></span>
<button class="btn-clear" onclick="clearResults()">Clear</button>
</div>
<div class="export-section">
<p class="export-label">Export As</p>
<div class="export-btns">
<button class="btn-export btn-export-txt" onclick="exportTXT()">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
TXT
</button>
<button class="btn-export btn-export-srt" onclick="exportSRT()">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="20" rx="2"/><path d="M7 8h10M7 12h10M7 16h6"/></svg>
SRT Subtitles
</button>
<button class="btn-export btn-export-pdf" onclick="exportPDF()">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
PDF
</button>
</div>
</div>
</div>
<div class="error-box" id="error-box">
<p id="error-text"></p>
</div>
<div class="translate-panel" id="translate-panel">
<div class="translate-header">
<span class="translate-title">Translate Transcript</span>
<span class="translate-hint">Powered by Google Translate</span>
</div>
<div class="translate-controls">
<select class="lang-select" id="lang-select">
<option value="">Select language...</option>
</select>
<button class="btn-translate" id="translate-btn" onclick="translateTranscript()">Translate</button>
</div>
<div class="translated-box" id="translated-box">
<div class="translated-header">
<span id="translated-lang-label">Translation</span>
<button class="btn-copy" onclick="copyTranslation()">Copy</button>
</div>
<p class="transcript-text" id="translated-text"></p>
</div>
</div>
</section>
</main>
<footer class="footer">
<div class="footer-inner">
<!-- Top: Brand + Stats -->
<div class="footer-top">
<div class="footer-brand">
<div class="footer-logo">
<svg width="28" height="28" viewBox="0 0 32 32" fill="none">
<rect width="32" height="32" rx="8" fill="#6366f1"/>
<rect x="6" y="12" width="3" height="8" rx="1.5" fill="white"/>
<rect x="11" y="8" width="3" height="16" rx="1.5" fill="white"/>
<rect x="16" y="5" width="3" height="22" rx="1.5" fill="white"/>
<rect x="21" y="9" width="3" height="14" rx="1.5" fill="white"/>
<rect x="26" y="13" width="3" height="6" rx="1.5" fill="white"/>
</svg>
VoiceScript
</div>
<p class="footer-tagline">
An AI-powered speech recognition system built with OpenAI Whisper and Facebook Demucs — transcribe, translate and export any audio in seconds.
</p>
</div>
<div class="footer-stats">
<div class="stat-item">
<span class="stat-number">99+</span>
<span class="stat-label">Languages</span>
</div>
<div class="stat-item">
<span class="stat-number"></span>
<span class="stat-label">Audio Length</span>
</div>
<div class="stat-item">
<span class="stat-number">3</span>
<span class="stat-label">Export Formats</span>
</div>
</div>
</div>
<!-- Tech Stack -->
<div class="footer-stack-section">
<p class="footer-stack-label">Built With</p>
<div class="footer-stack">
<span class="stack-badge badge-python">Python 3</span>
<span class="stack-badge badge-flask">Flask</span>
<span class="stack-badge badge-js">JavaScript</span>
<span class="stack-badge badge-whisper">OpenAI Whisper</span>
<span class="stack-badge badge-demucs">Facebook Demucs</span>
<span class="stack-badge badge-pydub">pydub</span>
<span class="stack-badge badge-ffmpeg">ffmpeg</span>
</div>
</div>
<!-- Divider -->
<div class="footer-divider"></div>
<!-- Bottom -->
<div class="footer-bottom">
<p class="footer-copy">© 2026 <span>Tushar Tamrakar</span>. MIT License.</p>
<div class="footer-links">
<a class="footer-link" href="https://github.com/TUSHARTAMRAKAR/VoiceScript" target="_blank">GitHub</a>
<a class="footer-link" href="https://huggingface.co/spaces/Tusharz/VoiceScript" target="_blank">Live Demo</a>
</div>
<div class="footer-heart">
Made with <span class="heart-icon">❤️</span> by Tushar Tamrakar
</div>
</div>
</div>
</footer>
<script src="app.js"></script>
</body>
</html>