A runnable, self-hosted web interface so the whole workflow can be tested end to end: record or upload audio in the browser, watch it transcribe and summarise, browse a library, play back, and export. What changed: - server/app/store.py: SQLite + on-disk audio storage for recordings (stdlib only). - server/app/pipeline.py: background task audio -> transcribe -> summarise via the existing provider layer, updating status (queued/transcribing/summarising/done/error). - server/app/main.py: web API - POST upload, list, detail, audio (Range), delete, and export (txt/md/srt/vtt/json) - and serves the SPA at /. - server/app/web/: Plaud-style single-page UI (index.html, styles.css, app.js). Sidebar library, in-browser recording (MediaRecorder) + file upload, live status polling, audio player, summary (overview/key points/actions), timestamped transcript, exports. - server/Dockerfile + README: two-minute run instructions (default provider: Groq free tier for both Whisper + LLM), and a Docker option. - config: env prefix switched OPENSCRIBE_ -> NIGHTJAR_ to match the brand and the site tutorials; .env.example rewritten with a ready Groq quick-start. - state/TODO: web app recorded as done. Why: - User asked for a Plaud-like web interface to test how it all works. Nothing testable existed before (marketing site is a brochure; pipeline was unwired). This delivers a real, runnable product demo and effectively lands M5/M6 for the HTTP providers. Notes: - Slim by design: AI is offloaded to the configured provider, so no local ML deps needed for the demo. Byte-compiles clean; JS passes node --check. Local faster-whisper still needs its model (M5) for the fully-offline path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.4 KiB
Nightjar server + web app
A self-hosted FastAPI app with a Plaud-style web interface: upload or record audio in the browser, watch it transcribe and summarise, browse a library, play back, and export. The AI is done by whichever providers you configure, so you own the whole pipeline.
Try it in two minutes
You need one AI key. The default config uses Groq (free tier, fast Whisper + LLM) for both transcription and summaries.
cd server
python -m venv .venv
. .venv/bin/activate # Windows: .venv\Scripts\activate
pip install fastapi "uvicorn[standard]" pydantic pydantic-settings python-multipart httpx anthropic
cp .env.example .env # then paste your Groq key into .env (both API_KEY lines)
uvicorn app.main:app --reload
Open http://localhost:8000 and press Record (or Upload an audio file). It will show
transcribing… → summarising… → done, then the transcript, a summary with key points and
action items, an audio player, and export buttons (TXT / Markdown / SRT / VTT / JSON).
Confirm your providers loaded at http://localhost:8000/health.
Or with Docker
cd server
docker build -t nightjar .
docker run -p 8000:8000 --env-file .env -v "$PWD/media:/app/media" nightjar
Choosing a different AI
Everything is set in .env (see .env.example and docs/ai-providers.md): OpenAI or any
OpenAI-compatible endpoint, Anthropic Claude, or fully local (Ollama + faster-whisper for a
"nothing leaves my machine" setup). Change the vars, restart, done.
What's inside
app/main.py FastAPI: upload/list/detail/audio/export + serves the web UI
app/pipeline.py audio -> transcribe -> summarise (background task)
app/store.py recordings in SQLite, audio on disk (demo storage)
app/providers/ the pluggable transcription + LLM providers
app/web/ the Plaud-style single-page UI (no build step)
This is the demo/single-node app. The hosted multi-tenant service (metering, billing,
object storage, Postgres, the Private-tier GPU node) is described in
../docs/hosted-service.md and ../docs/infrastructure.md.
Notes
- Recordings and the SQLite index live under
NIGHTJAR_LOCAL_MEDIA_DIR(default./media). - Browser recording produces WebM/Opus, which Groq and OpenAI accept directly - no ffmpeg needed for the demo.
- The API contract for the device/server is
../api/openapi.yaml.