Real-time speech-to-text using OpenAI Whisper (faster-whisper). Features browser audio capture, WebSocket streaming, and customizable display settings. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
160 lines
6.8 KiB
HTML
160 lines
6.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Live Captions</title>
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<!-- Caption Display Area -->
|
|
<div id="caption-container">
|
|
<div id="captions"></div>
|
|
</div>
|
|
|
|
<!-- Controls Bar -->
|
|
<div id="controls">
|
|
<button id="btn-start" class="btn btn-primary">
|
|
<span class="icon">►</span> Start
|
|
</button>
|
|
<button id="btn-stop" class="btn btn-danger" disabled>
|
|
<span class="icon">■</span> Stop
|
|
</button>
|
|
<button id="btn-clear" class="btn btn-secondary">
|
|
Clear
|
|
</button>
|
|
<label class="toggle-switch" title="Auto-save recordings">
|
|
<input type="checkbox" id="auto-save-toggle">
|
|
<span class="toggle-slider"></span>
|
|
<span class="toggle-label">Auto-save</span>
|
|
</label>
|
|
<button id="btn-recordings" class="btn btn-icon" title="Recordings">
|
|
📋
|
|
</button>
|
|
<button id="btn-settings" class="btn btn-icon" title="Settings">
|
|
⚙
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Status Indicator -->
|
|
<div id="status">
|
|
<span id="status-dot" class="dot"></span>
|
|
<span id="status-text">Ready</span>
|
|
</div>
|
|
|
|
<!-- Settings Panel -->
|
|
<div id="settings-panel" class="panel hidden">
|
|
<div class="panel-header">
|
|
<h2>Settings</h2>
|
|
<button id="btn-close-settings" class="btn-close">×</button>
|
|
</div>
|
|
<div class="panel-content">
|
|
<!-- Font Settings -->
|
|
<div class="setting-group">
|
|
<h3>Text</h3>
|
|
|
|
<label for="font-family">Font Family</label>
|
|
<select id="font-family">
|
|
<option value="Arial, sans-serif">Arial</option>
|
|
<option value="'Helvetica Neue', Helvetica, sans-serif">Helvetica</option>
|
|
<option value="'Segoe UI', sans-serif">Segoe UI</option>
|
|
<option value="'Roboto', sans-serif">Roboto</option>
|
|
<option value="'Open Sans', sans-serif">Open Sans</option>
|
|
<option value="Georgia, serif">Georgia</option>
|
|
<option value="'Times New Roman', serif">Times New Roman</option>
|
|
<option value="'Courier New', monospace">Courier New</option>
|
|
<option value="monospace">Monospace</option>
|
|
</select>
|
|
|
|
<label for="font-size">Font Size: <span id="font-size-value">32</span>px</label>
|
|
<input type="range" id="font-size" min="16" max="72" value="32">
|
|
|
|
<label for="font-weight">Font Weight</label>
|
|
<select id="font-weight">
|
|
<option value="normal">Normal</option>
|
|
<option value="bold">Bold</option>
|
|
<option value="lighter">Light</option>
|
|
</select>
|
|
|
|
<label for="text-color">Text Color</label>
|
|
<input type="color" id="text-color" value="#ffffff">
|
|
|
|
<label for="text-align">Text Alignment</label>
|
|
<select id="text-align">
|
|
<option value="left">Left</option>
|
|
<option value="center">Center</option>
|
|
<option value="right">Right</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Background Settings -->
|
|
<div class="setting-group">
|
|
<h3>Background</h3>
|
|
|
|
<label for="background-color">Background Color</label>
|
|
<input type="color" id="background-color" value="#1a1a2e">
|
|
|
|
<label for="background-opacity">Opacity: <span id="opacity-value">90</span>%</label>
|
|
<input type="range" id="background-opacity" min="0" max="100" value="90">
|
|
|
|
<label for="border-radius">Corner Radius: <span id="radius-value">10</span>px</label>
|
|
<input type="range" id="border-radius" min="0" max="30" value="10">
|
|
|
|
<label for="padding">Padding: <span id="padding-value">20</span>px</label>
|
|
<input type="range" id="padding" min="5" max="50" value="20">
|
|
</div>
|
|
|
|
<!-- Caption Behavior -->
|
|
<div class="setting-group">
|
|
<h3>Behavior</h3>
|
|
|
|
<label for="max-words">Max Words: <span id="max-words-value">30</span></label>
|
|
<input type="range" id="max-words" min="1" max="100" value="30">
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="setting-actions">
|
|
<button id="btn-save-settings" class="btn btn-primary">Save Settings</button>
|
|
<button id="btn-reset-settings" class="btn btn-secondary">Reset to Defaults</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recordings Panel -->
|
|
<div id="recordings-panel" class="panel hidden">
|
|
<div class="panel-header">
|
|
<h2>Recordings</h2>
|
|
<button id="btn-close-recordings" class="btn-close">×</button>
|
|
</div>
|
|
<div class="panel-content">
|
|
<!-- Recordings List -->
|
|
<div id="recordings-list" class="recordings-list">
|
|
<p class="recordings-empty">Loading recordings...</p>
|
|
</div>
|
|
|
|
<!-- Recording Viewer -->
|
|
<div id="recording-viewer" class="recording-viewer hidden">
|
|
<div class="viewer-header">
|
|
<button id="btn-back-to-list" class="btn btn-secondary btn-small">← Back</button>
|
|
<span id="viewer-filename" class="viewer-filename"></span>
|
|
</div>
|
|
<div id="viewer-content" class="viewer-content"></div>
|
|
<div class="viewer-actions">
|
|
<button id="btn-delete-recording" class="btn btn-danger btn-small">Delete</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Overlay for panels -->
|
|
<div id="overlay" class="hidden"></div>
|
|
</div>
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script>
|
|
<script src="/static/js/settings.js"></script>
|
|
<script src="/static/js/recordings.js"></script>
|
|
<script src="/static/js/app.js"></script>
|
|
</body>
|
|
</html>
|