- Audio ingestion — pull episodes from RSS feeds (full, selective, or test mode) or upload audio files (
.mp3,.m4a,.wav,.ogg,.flac,.opus,.aac,.wma,.webm,.mp4) directly from the web UI. - Speech-to-text — WhisperX with
large-v3-turboby default, tunable down totinyfor low-RAM machines. - Speaker diarization — pyannote
speaker-diarization-community-1assignsSPEAKER_NNlabels locally (free), with an optional paid cloud upgrade to pyannote.ai's higher-accuracyprecision-2model; spaCy NER proposes real names from episode metadata, and you can rename or merge speakers in the UI. - Hybrid search — full-text keyword search (
"exact phrase",OR,-exclude) combined with pgvector semantic similarity, merged via Reciprocal Rank Fusion. - Persistent audio player — click any timestamp to play; the player keeps going while you navigate other pages.
- Ask AI (RAG) — ask natural-language questions and get streamed, citation-backed answers drawn from your transcript library (local Ollama by default, Fireworks optional).
- Export — download search results or full transcripts as Markdown or plain text, or open a print-friendly view (
/search/print) for the browser's print-to-PDF flow. - Queue dashboard — per-stage status, error classification, auto-retry for transient failures, manual retry for the rest.
- Meta-Analysis dashboard — speaker analytics across every feed at
/meta-analysis: per-speaker minutes and word counts episode by episode, and a host-vs-guest talking-time delta, drawn from either confirmed names or high-confidence inferred ones. - Notifications — Telegram and email alerts when episodes finish or fail, with optional daily/weekly digest.
- Local-first — no accounts, no cloud, no telemetry; optional Fireworks AI profile for users who prefer remote inference.
# 1. Clone, and switch to the newest released version
git clone https://github.com/brlauuu/podlog.git
cd podlog
git checkout "$(git tag -l 'v*' --sort=-v:refname | head -1)"
# 2. Configure (set POSTGRES_PASSWORD and HF_TOKEN)
cp .env.example .env
nano .env
# 3. Start from published images — no build
make up-releasePodlog is cloned rather than downloaded as loose files because updating
depends on it: make update moves the working copy with git, compares the
new .env.example against your .env, and reads VERSION to tell you what
you are running. See Updating.
Images are linux/amd64 only. On any other architecture, build from source.
Building from source compiles the machine-learning stack locally, which takes a while the first time and needs several gigabytes of disk:
git clone https://github.com/brlauuu/podlog.git
cd podlog
cp .env.example .env && nano .env
make build
make upmake up never contacts the registry, so it always runs the code in your
working copy — including changes you have just made.
Open http://localhost:3000. From the navbar you can reach Search (/search), Ask (/ask), Sources (/podcasts, where you add feeds or upload audio), Queue (/queue), Meta-Analysis (/meta-analysis), Settings (/settings), Docs (/docs) and About (/about).
First run: The worker downloads Whisper and pyannote model weights (~3 GB). Jobs are queued during this phase and start processing once models are cached.
If you want Fireworks-backed inference and no local ollama container:
# ensure FIREWORKS_API_KEY is set in .env
make up-remoteThis uses docker-compose.remote.yml on top of the default compose file.
For a side-by-side comparison of the local and remote options for both transcription and diarization — including a decision matrix and a list of providers we evaluated but didn't ship — see docs/guide/19-inference-providers.md.
- Docker with Compose V2
- A free HuggingFace account with an access token
- You must accept the pyannote license at pyannote/speaker-diarization-community-1 before diarization will work
postgresql-client(optional) — needed for host-level health monitoring (sudo apt install postgresql-client)
┌──────────────────────────────────────────────┐
Browser :3000 ──────>│ web (Next.js 16.2.4) │
│ Home, search, episodes, queue, audio player│
│ Reads PostgreSQL directly for FTS/vector │
│ Proxies to pipeline API for management │
└──────────────┬───────────────────────────────┘
│
┌──────────────▼───────────────────────────────┐
Pipeline API :8000 ──>│ pipeline (FastAPI) │
│ Feed management, queue control, health │
│ Embed API (MiniLM query embedding) │
└──────────────────────────────────────────────┘
│
┌──────────────▼───────────────────────────────┐
│ worker (Python) │
│ download → transcribe → diarize → chunk │
│ → embed → infer speakers → archive │
│ Sequential processing (concurrency=1) │
│ Whisper + pyannote never in memory at once│
└──────────────┬───────────────────────────────┘
│
┌──────────────▼───────────────────────────────┐
│ db (PostgreSQL 15 + pgvector) │
│ Episodes, segments, speaker names │
│ FTS via GIN index + vector HNSW index │
│ Job queue with FOR UPDATE SKIP LOCKED │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
Ollama API :11434 ──> │ ollama (local LLM) │
│ RAG-based Ask AI feature │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ backup (cron-style loop) │
│ Nightly DB dump + audio archive snapshot │
│ Writes to ./backups/ on the host │
└──────────────────────────────────────────────┘
Default profile: 6 containers (db, pipeline, worker, ollama, web, backup). Remote-inference profile: 5 containers (Ollama is disabled unless you opt in with the local-ask Compose profile). A seventh service, explore (Jupyter), is opt-in via make explore. No Redis, no Celery — the job queue is PostgreSQL-backed using FOR UPDATE SKIP LOCKED.
Only two variables are required. Everything else has sensible defaults.
| Variable | Default | Description |
|---|---|---|
POSTGRES_PASSWORD |
(required) | PostgreSQL password |
HF_TOKEN |
(required) | HuggingFace access token for pyannote |
WHISPER_MODEL |
large-v3-turbo |
Model size: tiny, base, small, medium, large-v3, large-v3-turbo |
WHISPER_COMPUTE_TYPE |
int8 |
int8 (fast, recommended for CPU) or float32 |
ARCHIVE_AUDIO |
true |
Archive audio as compressed MP3 after transcription |
FEED_POLL_INTERVAL_HOURS |
24 |
How often to check feeds for new episodes |
See docs/configuration.md for the full list of all environment variables.
| Document | Description |
|---|---|
| Changelog | Notable changes per release. Also rendered at the bottom of the in-app About page. |
| User Guide | Step-by-step guide for new users: setup, features, configuration |
| Configuration | All environment variables with defaults and explanations |
| Hardware Guide | System requirements, processing benchmarks, tested machine specs |
| Development | Local development setup, running tests, architecture notes, and Codex/Claude audit workflows |
| Audit Workflows | How Codex (nightly-audit) and Claude (/codebase-audit) audits are run, what they produce, and safety constraints |
| Episode Lifecycle | Pipeline stages, data produced at each step, and which features depend on which data |
make up # Start all services
make up-remote # Start Fireworks remote-inference profile
make down # Stop all services
make down-remote # Stop Fireworks remote-inference profile
make build # Rebuild Docker images
make logs # Follow logs for all services
make logs-remote # Follow logs for remote-inference profile
make test-unit # Run pipeline unit tests + healthcheck script tests
make shell-db # Open psql shell
make health-install # Install health monitoring cron (every 15 min)
make help # List all available commands| Layer | Technology | Role |
|---|---|---|
| WhisperX | Whisper large-v3-turbo + CTranslate2 | Speech-to-text transcription |
| faster-whisper | CTranslate2 backend | Fast CPU inference for Whisper |
| pyannote | speaker-diarization-community-1 (local) or precision-2 (pyannote.ai cloud) |
Speaker labeling and separation |
| sentence-transformers | all-MiniLM-L6-v2 | Semantic search embeddings (384-dim) |
| pgvector | PostgreSQL vector extension | Approximate nearest neighbor search |
| Next.js 16.2.4 | App Router, React Server Components | Web UI |
| Tailwind CSS + shadcn/ui | Utility-first CSS + components | Styling |
| FastAPI | Python async web framework | Pipeline API |
| PostgreSQL 15 | Relational database | Storage, FTS, job queue, vector search |
| Docker Compose | Container orchestration | Deployment |
Built by @brlauuu with support from:
Agents:
- Claude
- Gemini
- OpenCode (running Kimi K2.5 and Big Pickle)
Platforms:
- Omnara
- Fireworks AI (optional remote inference for Podlog)
O'Saasy License. See LICENSE.
pyannote models are subject to their own license — you must accept this independently at huggingface.co/pyannote/speaker-diarization-community-1. Users are responsible for copyright compliance with podcast audio content.
This software is an open-source tool for audio transcription. It does not include any copyrighted content. Users are responsible for ensuring their use of the software complies with local copyright laws and the Terms of Service of any content creators whose work they process.