A containerized web utilities platform featuring speaker-attributed video transcription and non-destructive Gemini Flash transcript formatting.
The application runs entirely with Docker Compose:
cp .env.example .env
# Optional: Set HF_TOKEN, GEMINI_API_KEY, and a long INTERNAL_TOKEN in .env
# By default, FAKE_PIPELINE=true enables deterministic local/CI execution without external model downloads.
docker compose up -d --build --waitOpen http://localhost:3000/utilities/video-transcription. The API listens on http://localhost:8080; only frontend and api publish host ports. PostgreSQL, worker, diarization, and object-store communicate exclusively over the internal private Compose network.
- Frontend (
frontend/): SvelteKit SPA serving/utilities/video-transcriptionand proxying/api/*requests to the Go API over the internal network. - API (
backend/cmd/api): Validates publichttp/httpsURLs (blocking private, loopback, link-local, and metadata destinations), manages job state in PostgreSQL, enforces per-client rate limits, and invokes Gemini Flash (GEMINI_API_KEYorGEMINI_API_KEY_FILE) to store non-destructive formatted previews informatted_transcripts. - Worker (
backend/cmd/worker): Claims queued jobs withSELECT ... FOR UPDATE SKIP LOCKED, resolves media withyt-dlp, normalizes audio to 16 kHz mono WAV with FFmpeg, verifies the RIFF/WAVE signature, uploads the normalized WAV to the private S3-compatibleobject-store(jobs/<job-id>/audio.wav), transcribes speech viawhisper.cppGo bindings, calls the internaldiarizationsidecar with the artifact key, merges speaker turns by maximum millisecond overlap, and deletes the temporary artifact (with background TTL and retention cleanup). - Object Store (
object-store): Private S3-compatible service backed by theobject-datavolume storing intermediate WAV artifacts with AWS Signature V4 authentication and TTL-based expiration (ARTIFACT_TTL, default1h). - Diarization Sidecar (
services/diarization): FastAPI service authenticated withX-Internal-Tokenthat fetches the normalized WAV artifact fromobject-store(or shared/workvolume) and returns millisecond-aligned speaker turns usingpyannote/speaker-diarization-3.1.
To run with live ML models instead of the deterministic development pipeline:
- Download a Whisper GGML model (e.g.,
ggml-base.en.bin) into./models/and setWHISPER_MODEL_PATH=/models/ggml-base.en.bin:curl -L --fail -o models/ggml-base.en.bin \ https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin
- Supply
HF_TOKEN(having accepted the conditions forpyannote/speaker-diarization-community-1on Hugging Face) andGEMINI_API_KEY(via.envor*_FILEsecret mounts) and setFAKE_PIPELINE=false. - For NVIDIA GPU acceleration on diarization, run with
--profile gpu.
- Liveness & Readiness:
GET http://localhost:8080/healthz— API liveness and database ping.GET http://localhost:8080/readyz— Verifies PostgreSQL andobject-storebucket readiness.GET http://localhost:8080/metrics— Prometheus text format (or JSON withAccept: application/json) counters for HTTP requests, rate-limited requests, job submissions/completions/failures/cancellations/retries, and formatted previews.
- Verification Commands:
# Go unit tests docker run --rm -v "$PWD/backend:/src" -w /src golang:1.24-alpine go test -v ./... # Python diarization unit tests docker run --rm web-utils-diarization pytest -v # Frontend component & store unit tests docker run --rm web-utils-frontend npm test # End-to-end journey tests against running Compose stack docker compose exec -T frontend npm run test:e2e