Repository navigation
Spectator 0.2.0 — persistent Web UI
Highlights
A persistent web UI that wraps Spectator's CLI. Drag-drop a meeting recording, watch the rt-factor climb in real time, download the transcripts, and ask follow-up questions — all without touching a terminal.
./spectator ui-server start # localhost-only, port 7777
./spectator ui-server start --target <gpu-machine> # route all jobs to a remote
./spectator ui-server start --bind 0.0.0.0 --port 8080 # expose on the LANOpen http://localhost:7777/ and:
- Drop an audio or video file onto the upload zone (or click to browse).
- Submit with a quality preset / language / task / device override (audio) or a free-form summarization prompt (video).
- Watch progress live: a per-job WebSocket pushes a snapshot every 2 s — segments processed, rt-factor, wall-clock, ETA. The progress bar updates in place; no page reloads.
- Download Spectator's output bundle (
.txt/.srt/.vtt/.json/.tsv) with one click per format. - Toggle the VSS stack up or down from the dashboard.
- Ask questions of indexed videos (proxies to VSS's OpenAI-compat chat) or of completed audio jobs (transcript text → NVIDIA NIM).
What's new
ui-server lifecycle (CLI)
spectator ui-server start [--port N] [--bind ADDR] [--target HOST] [--workdir DIR]
spectator ui-server stop
spectator ui-server status
spectator ui-server logs [--follow] [--lines N]
Detached uvicorn process. PID + log live under $workdir/ui-server/. SIGTERMs the whole process group on stop so subprocesses (whisper, ssh, …) exit too.
REST + WebSocket surface
| Method + path | Purpose |
|---|---|
GET /api/status |
overall health (VSS reachable, audio-venv installed, jobs in flight) |
POST /api/vss/{up,down} + GET status |
VSS stack lifecycle |
POST /api/jobs (multipart) |
submit an audio or video job |
GET /api/jobs[/{id}] |
list / detail with metrics |
DELETE /api/jobs/{id} |
kill a running job (local PID or remote tmux) |
GET /api/jobs/{id}/log |
tail of the subprocess log |
GET /api/jobs/{id}/output/{filename} |
download an output file |
WS /api/jobs/{id}/progress |
live JSON snapshots every 2 s |
POST /api/query/{video,audio} |
Q&A against indexed videos / completed audio transcripts |
Persistent job ledger
$workdir/ui-server/jobs/<uuid>.json survives ui-server stop / start. The schema is the public contract for any agent watching alongside the UI:
{
"id": "...",
"kind": "audio",
"status": "running",
"created_at": 1715300000.0,
"started_at": 1715300004.5,
"input_path": "/.../audio-in/meeting.mp3",
"output_dir": "/.../audio-out/meeting/",
"params": {"quality": "meeting", "language": null, "task": "transcribe"},
"metrics": {"rt_factor": 3.04, "device": "mps", "wall_clock_s": 252.1},
"pid": 12345,
"target": null,
"log_path": "/.../jobs/<uuid>.log"
}Frontend
Vanilla HTML / JS / CSS — no React, no build step. CSS-vars theme with light + dark mode. NVIDIA-green accent on primary buttons and the progress bar fill. Single page, no routing.
Tests
14 new tests under tests/test_webui.py:
JobLedgerpersistence + status transitions + atomic delete.- Progress parser: running snapshots, finished runs (
==== END rc=0 ====marker + exit code), unknown duration, long-formHH:MM:SS.mmmtimestamps for multi-hour audio. - FastAPI routes via
TestClient: status / list / submit / 404 / 400 / path-traversal guard.
Total suite: 30 passing.
New runtime dependencies
| Package | License | Why |
|---|---|---|
fastapi >= 0.110, < 1.0 |
MIT | HTTP + WebSocket framework |
uvicorn[standard] >= 0.30, < 1.0 |
BSD-3-Clause | ASGI server |
python-multipart >= 0.0.9 |
Apache-2.0 | multipart file upload |
THIRD_PARTY_NOTICES.md updated.
Compatibility
No breaking changes vs v0.1.1. The CLI's audio + video pipelines are unchanged — the Web UI is a thin orchestration layer on top. Existing ./spectator audio transcribe, ./spectator process, ./spectator query invocations work the same. Nothing in the existing tests was modified; the smoke suite still asserts what it always did.
Security defaults
--bind 127.0.0.1(localhost-only).- No built-in auth. Pass
--bind 0.0.0.0only on networks you trust. - Path-traversal blocked on output downloads.
Quick try
git clone https://github.com/myurasov/Spectator.git spectator && cd spectator
./spectator install
./spectator audio install
./spectator ui-server start
open http://localhost:7777/
# drop a meeting.mp3 onto the upload zone