Files
captionninja/capture-local.html

85 lines
7.4 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Self-hosted captions</title><link rel="stylesheet" href="./caption-local/capture.css"></head><body>
<a class="skip-link" href="#captureControls">Skip to caption controls</a>
<header><h1>Self-hosted captions</h1>
<nav aria-label="Setup help"><a href="https://github.com/steveseguin/caption-local/blob/main/docs/SELF-HOSTING.md" rel="noreferrer">How it works</a><a href="https://github.com/steveseguin/caption-local/blob/main/docs/GETTING-STARTED.md" rel="noreferrer">Install and start</a><a href="https://github.com/steveseguin/caption-local/blob/main/docs/README.md" rel="noreferrer">All guides &amp; help</a></nav>
<p>Speech is processed by your Caption Local service. Choose your audio input, start captions, then Stop and download your transcript.</p></header>
<main>
<form id="auth" hidden>
<label>Service access token<input id="accessToken" type="password" autocomplete="off" spellcheck="false"></label>
<small>Use the token supplied by the server operator. It stays in this tab and is not sent to caption.ninja.</small>
<button type="submit">Connect to service</button>
</form>
<details class="panel" id="serviceConnection" open>
<summary id="connectionTitle">1. Connect your service</summary>
<form id="connection">
<div class="fields">
<label>Service address<input id="endpoint" type="url" required aria-describedby="connectionHelp" value="http://localhost:8765"></label>
<label>Service token (if required)<input id="connectionToken" type="password" autocomplete="off" spellcheck="false"></label>
</div>
<p id="connectionHelp" class="hint">Start Caption Local first. Use the token from your operator, or leave it empty if none is configured.</p>
<div class="actions"><button id="connect" type="submit">Connect and check service</button></div>
<p id="connectionError" role="alert"></p>
<details class="connection-help"><summary>Connecting to another computer?</summary>
<p>Use an SSH tunnel for a remote service. Hosted capture pages also need an allowed origin and browser local-network permission. Tokens stay in this tab. The bundled page connects to its own server.</p>
<a href="http://localhost:8765/capture-local.html" rel="noreferrer">Open the local capture page</a>
</details>
</form>
</details>
<p id="capabilities" role="status">Connect to check the model and supported languages.</p>
<section class="panel" aria-labelledby="audioTitle">
<h2 id="audioTitle">2. Choose your audio and output</h2>
<div class="fields">
<label>Microphone<select id="microphone"><option value="">System default</option></select></label>
<label>Spoken language<select id="language"><option value="en">English</option></select></label>
<label>Microphone sensitivity<select id="sensitivity"><option value="0.0008">Quiet speech</option><option value="0.002" selected>Normal</option><option value="0.006">Noisy room</option></select></label>
<label>Caption interval<select id="captionInterval"><option value="3">3 seconds — earlier</option><option value="6" selected>6 seconds — balanced</option><option value="9">9 seconds — more context</option></select></label>
<label>Caption output<select id="mode"><option value="transcribe">Spoken-language captions</option><option value="translate">English translation</option><option value="both">Original + English</option></select></label>
</div>
<p class="hint">Start with six-second captions. Shorter intervals can reduce accuracy and capacity. English translation means speech translated into English.</p>
</section>
<section class="panel" id="captureControls" aria-labelledby="captionsTitle" tabindex="-1">
<h2 id="captionsTitle">3. Capture and save</h2>
<div class="actions">
<button id="start" disabled>Start captions</button> <button id="stop" disabled>Stop</button>
<button id="retry" hidden>Retry pending audio</button> <button id="discard" hidden>Discard pending audio</button>
</div>
<p id="status" role="status">Ready</p><p id="error" role="alert"></p>
<label>Microphone level<meter id="meter" min="0" max="0.1" value="0"></meter></label>
<div id="captions" role="log" aria-live="polite" aria-label="Live captions"></div>
<button id="download">Download transcript</button>
<p class="hint">Stop and let pending audio finish before downloading. Audio is not saved; closing the tab can lose pending audio and unsaved text.</p>
</section>
<details><summary>Send captions to caption.ninja</summary>
<p>Optional: caption text will travel through the selected relay (caption.ninja’s public relay by default). Audio stays on the inference host. Paste the editor’s <strong>private automatic-caption room</strong> below. The editor reviews these captions before publishing to its separate public room.</p>
<label>Text to send<select id="relayOutput"><option value="transcript">Original transcription</option><option value="translation">English translation</option></select></label>
<label>Destination workflow<select id="relayTarget"><option value="editor">Human editor (private source room)</option><option value="overlay">Direct overlay (publishes without review)</option></select></label>
<p>For a direct overlay, use its room instead. Anyone with that room link can see the shared text; direct captions skip human review.</p>
<details><summary>Use a private relay</summary>
<label>Relay address<input id="relayAddress" type="url" value="wss://api.caption.ninja:443" spellcheck="false"></label>
<label>Caption website address<input id="captionSite" type="url" value="https://caption.ninja/" spellcheck="false"></label>
<label>Room publishing token<input id="relayToken" type="password" autocomplete="off" spellcheck="false"></label>
<label>Editor output room<input id="reviewRoom" value="output" autocomplete="off" maxlength="128"></label>
<p>A private relay needs its own room token, separate from the inference service token. The editor needs the source viewing token and output publishing token. Links carry the relay address, never tokens. Turn sharing off before changing these settings.</p>
</details>
<label>Source room<input id="room" autocomplete="off" maxlength="128"></label>
<label><input id="share" type="checkbox"> Send caption text to caption.ninja</label>
<p id="relay" role="status">Sharing off</p><a id="editorLink" hidden target="_blank" rel="noopener noreferrer">Open caption editor</a>
</details>
<details><summary>Connection and capture diagnostics</summary>
<p id="diagnostics">Connect to inspect capture status.</p>
<p>Response duration includes network, queue and inference time; it is not speech-to-caption delay. The last 100 requests are retained in memory. Downloads exclude tokens, service addresses, room names, audio and captions.</p>
<button id="downloadDiagnostics">Download diagnostics</button>
<button id="saveSettings">Save capture settings</button>
<label>Load capture settings<input id="loadSettings" type="file" accept="application/json,.json"></label>
<p>Settings include the service address, language, output and capture interval. Tokens, microphone identifiers, room names and sharing are excluded. Connect first, then load settings for that service.</p>
</details>
</main>
<script src="./caption-local/relay-config.js"></script><script src="./caption-local/private-relay-client.js"></script><script src="./caption-local/ws-publisher.js"></script><script src="./caption-local/audio-buffer.js"></script><script src="./caption-local/local-connection.js"></script><script src="./caption-local/app.js"></script><script src="./caption-local/local-page.js"></script>
</body></html>