Skip to main content

Convert Discourse threads to multi-voice audio using TTS

Project description

DPO Reader

Turn Discourse threads into podcasts. Each author gets their own voice.

PyPI Version Python Versions License


I got tired of skimming long forum threads. DPO Reader converts them to audio so I can listen while doing other things. Point it at any Discourse thread and it'll synthesize the whole thing with different voices for each participant.

Install

# uv (recommended)
uv tool install dpo-reader

# Or run directly without installing
uvx dpo-reader listen "https://discuss.python.org/t/your-thread"

# pipx works too
pipx install dpo-reader

Usage

# Basic: generate audio and play it
dpo-reader listen "https://discuss.python.org/t/your-thread"

# Interactive TUI with read-along highlighting
dpo-reader listen "https://discuss.python.org/t/your-thread" --ui

# Start from a specific post (the /50 in the URL does this automatically)
dpo-reader listen "https://discuss.python.org/t/your-thread/12345/50" --ui

# Or explicitly with -s
dpo-reader listen "https://discuss.python.org/t/your-thread" -s 50

# Export without playing
dpo-reader export "https://discuss.python.org/t/your-thread" -o thread.wav

# See what you're getting into before generating
dpo-reader info "https://discuss.python.org/t/your-thread"
dpo-reader preview "https://discuss.python.org/t/your-thread"

Options

-o, --output PATH         Output file (default: output.wav)
-e, --engine ENGINE       openai | bark | piper
-s, --start-post INT      Start from this post number
-n, --max-posts INT       Limit number of posts
--ui                      Interactive TUI with controls
--no-attribution          Skip "Author says:" prefix
--no-play                 Don't auto-play after generating
-c, --cache-dir PATH      Cache audio chunks (useful if generation crashes)
-p, --pause FLOAT         Seconds between posts (default: 1.5)
-f, --file PATH           Load from local JSON (testing)

TTS Engines

Engine Quality Speed Notes
OpenAI Best Fast Needs API key, costs money
Bark Excellent Slow (~10s/sentence) Local, wants a GPU
Piper Good Fast (~0.1s/sentence) Local, CPU-only

Bark is the default. It runs locally and produces natural-sounding speech with good intonation. A GPU helps a lot but isn't strictly required.

OpenAI (-e openai) sounds the best if you have an API key. Get one at platform.openai.com/api-keys and set OPENAI_API_KEY in your environment or a .env file.

Piper (-e piper) is the lightweight option. Install with uv pip install dpo-reader[piper]. Good for batch processing or machines without GPUs.

TUI Controls

When using --ui:

Key Action
Space Play/Pause
←/→ Skip 5 seconds
↑/↓ Speed up/down
n/p Next/Previous post
l Toggle logs
q Quit

Requirements

Python 3.10-3.13. The onnxruntime dependency doesn't support 3.14 yet.

Development

git clone https://github.com/JacobCoffee/dpo-reader.git
cd dpo-reader
make dev

make lint        # Linting
make type-check  # Type checking
make test        # Tests
make ci          # All of the above

# Test TTS locally
make test-listen  # Piper
make test-bark    # Bark

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dpo_reader-0.1.0.tar.gz (26.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dpo_reader-0.1.0-py3-none-any.whl (29.1 kB view details)

Uploaded Python 3

File details

Details for the file dpo_reader-0.1.0.tar.gz.

File metadata

  • Download URL: dpo_reader-0.1.0.tar.gz
  • Upload date:
  • Size: 26.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dpo_reader-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8328ef1a412f0156e8004bf64b5a584f17e2044673ef2f69ef2f3dda0823d6ac
MD5 fe8b65a152259da0252598f4360b1712
BLAKE2b-256 ae574939e2731d4a02abb1f45dce1d82e5a106de93eb4a7db2aec23a986986a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for dpo_reader-0.1.0.tar.gz:

Publisher: publish.yml on JacobCoffee/dpo-reader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dpo_reader-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dpo_reader-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dpo_reader-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 274b2459fad463526281ebfb66bc34696652ce437ee411a464307c7a7c2c600f
MD5 6ee4e39a8a701e7bff166fbdc137feb7
BLAKE2b-256 ffda54bf3b6a9ecb3f22e74e9a015ae0d0ffd5ca69403d5e772455a44569fd5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for dpo_reader-0.1.0-py3-none-any.whl:

Publisher: publish.yml on JacobCoffee/dpo-reader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page