Vol. 0 · No. 1Status: early development

OPEN SOURCE · SELF-HOSTED

Every article you publish is already a podcast episode.

Paste one script tag. Visitors press play. Podcast apps subscribe. Everything runs on your own server, on a CPU.

Space or Enter plays · ← → seeks 10 s · this badge is a demo with recorded audio

PagePlayer turns written articles into audio. You paste one script tag into your pages, and every article gets a small badge. A visitor clicks it and hears the article read aloud by a text-to-speech model running on your server.

The same audio is published as a podcast RSS feed, so your back catalogue becomes a show in any podcast app. And with pre-warm, new posts can be synthesized from your sitemap before anyone visits.

Each article revision is synthesized once. Ask for it again and PagePlayer makes zero TTS calls. Fix a typo in paragraph seven and only paragraph seven is read again. It is early: verified so far by automated tests, not yet on real phones or with podcast apps.

§2Three ways it pays off

Three ways it pays off

§3The cache, live

Edit a paragraph. Watch what regenerates.

This is the cache rule, running live in your browser. Change any sentence on the left: only that paragraph's chunks would go back to the TTS model. Everything else is reused as-is.

Open the full playground →
§4Infographic

How it works

One Go process serves the API and runs the worker. Your database holds the state and the queue, and finished audio lands in S3-compatible storage. Read down the page and the red block follows one request from click to playback.

    The core flow, in plain English

    1. 1A visitor presses the badge. It sends the site key and the page URL, nothing else.
    2. 2The API checks the site and the URL, then answers from the cache or queues a job in Postgres.
    3. 3A worker claims the job, fetches the page through the SSRF guard and extracts the article.
    4. 4The text is normalized and chunked. Each chunk is looked up by hash(chunk text) + voice profile.
    5. 5Only missing chunks go to the TTS sidecar, through the provider pool, first chunk first.
    6. 6The chunks are stitched into one MP3 and Garage stores it. The badge and the RSS feed point at the same /audio/* URL.
    §5Catalog

    Two voices

    The TTS sidecar runs one engine per process. Both engines below are working today.

    PP-001 · DEFAULT ENGINE

    Kokoro

    Default · progressive playback
    • Parameters82M
    • WeightsApache-2.0 (to be verified)
    • VoicesMultiple presets
    • Built forCPU
    voice: af_heart

    PP-002 · OPTIONAL ENGINE

    Chatterbox

    Optional · background mode
    • Voice cloningFrom a short reference clip
    • WeightHeavier
    • Measured3.8 s of audio in 9.2 s on a dev CPU
    • Best forBackground pre-warm
    built-in voice

    Same API, same image, chosen per process with TTS_PROVIDER. Run both as two containers.

    §6Start here

    Self-host it in one command

    ~/PagePlayer
    
        

    What you get

    • Postgres
    • S3-compatible storage (Garage)
    • TTS sidecar
    • Go app
    • CPU-only
    • No telemetry
    • Secrets loaded from files
    • Swap in R2, MinIO or S3 by configuration

    Measured: a fresh-clone docker compose up --build took about 6.5 minutes.

    Then, on your pages

    Preview — API not final
    <script async src="https://your-host/badge.js"
            data-site-key="pk_…"></script>
    §7Design principles

    Built to be boring in production

    §8Letters

    Questions