feat(web): Nightjar web app - Plaud-style record/transcribe/summarise UI
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>
This commit is contained in:
parent
b9e56d0825
commit
19c3e156a0
10 changed files with 501 additions and 76 deletions
|
|
@ -1,48 +1,60 @@
|
|||
# OpenScribe server
|
||||
# Nightjar server + web app
|
||||
|
||||
Self-hosted FastAPI server: ingests recordings, transcribes them (faster-whisper),
|
||||
summarises them (Ollama), and serves the open API with exports. Everything runs on
|
||||
hardware you own.
|
||||
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.
|
||||
|
||||
> Status: M0 scaffold. The API shape is live and browsable at `/docs` with in-memory
|
||||
> stubs. Transcription lands in M5, summaries in M6, real storage/DB alongside.
|
||||
## Try it in two minutes
|
||||
|
||||
## Run (dev)
|
||||
You need one AI key. The default config uses **Groq** (free tier, fast Whisper + LLM) for
|
||||
both transcription and summaries.
|
||||
|
||||
```bash
|
||||
cd server
|
||||
python -m venv .venv
|
||||
. .venv/Scripts/activate # Windows; or: . .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env # edit as needed
|
||||
. .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
|
||||
```
|
||||
|
||||
- API docs (Swagger UI): http://localhost:8000/docs
|
||||
- Health: http://localhost:8000/health
|
||||
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).
|
||||
|
||||
## Self-hosted dependencies
|
||||
Confirm your providers loaded at **http://localhost:8000/health**.
|
||||
|
||||
For the AI features (M5/M6) you run, on your own kit:
|
||||
### Or with Docker
|
||||
|
||||
- **MinIO** (or WebDAV / NAS) for object storage - `OPENSCRIBE_STORAGE_BACKEND=s3`.
|
||||
- **Ollama** for summaries - `ollama serve` and `ollama pull llama3.1`.
|
||||
- **faster-whisper** downloads its model on first use; CPU works, CUDA is faster.
|
||||
|
||||
None of these are required for plain recording and transfer; they add transcription and
|
||||
summaries.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
app/main.py FastAPI app + routes (mirrors ../api/openapi.yaml)
|
||||
app/config.py Settings from env / .env
|
||||
app/models.py Pydantic models (kept in sync with the OpenAPI schemas)
|
||||
requirements.txt
|
||||
.env.example
|
||||
```bash
|
||||
cd server
|
||||
docker build -t nightjar .
|
||||
docker run -p 8000:8000 --env-file .env -v "$PWD/media:/app/media" nightjar
|
||||
```
|
||||
|
||||
## API
|
||||
## Choosing a different AI
|
||||
|
||||
The contract is `../api/openapi.yaml`. The device implements the LAN "device" paths; this
|
||||
server implements ingest, transcript, summary and export.
|
||||
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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue