Read Aloud
Nostos can read an EPUB or a PDF to you from the page it is open on. It marks the sentence being spoken, turns the page by itself and carries on into the next chapter.
Open a book, tap the page to bring up the toolbar, and press the speaker button. A small bar appears with previous sentence, play/pause, next sentence, speed and stop. It stays on screen while the rest of the toolbar is hidden.
Two kinds of voice
Section titled “Two kinds of voice”| Voice | Where it runs | Needs | Works with the screen locked |
|---|---|---|---|
| Device voice | The phone, tablet or computer you read on | Nothing | Usually not. Nostos keeps the screen awake while it reads |
| Natural voice | A speech server | A speech server connected to Nostos | It is built to: it plays as ordinary audio, like an audiobook. Not yet confirmed on every phone |
The device voice is always there and is what Nostos uses until a natural voice is connected. How it sounds depends on the device.
When a natural voice is connected, Nostos uses it for books in a language the voice can read and the device voice for every other book. If the natural voice fails in the middle of a book, reading carries on with the device voice and a short message says why.
The voice is chosen in the reader, under View settings → Read aloud voice. The choice is remembered on that device.
Connect a natural voice (self-hosted)
Section titled “Connect a natural voice (self-hosted)”The other AI services Nostos can use are set up on the same Settings page. AI Connections covers all of them.
Nostos talks to any speech server that offers the OpenAI speech route
(POST /v1/audio/speech). This guide uses Kokoro,
an open model, served by Kokoro-FastAPI.
It runs on your own machine, needs no account or key, and no text leaves it.
1. Run a speech server
Section titled “1. Run a speech server”With Docker Compose, add it next to Nostos:
services: nostos: image: ghcr.io/christian-gennari/nostos:latest # ...your existing nostos service, unchanged
kokoro: # Pin a release tag from the Kokoro-FastAPI project instead of `latest`. image: ghcr.io/remsky/kokoro-fastapi-cpu:latest restart: unless-stoppedThen run docker compose up -d. The speech server does not need a published
port: only Nostos calls it. Without Docker, start Kokoro-FastAPI any other way
and note its address, for example http://localhost:8880.
2. Connect it in Settings
Section titled “2. Connect it in Settings”Open Settings → AI connections → Read aloud voice:
- Switch on Enable the natural voice.
- Set Endpoint to the speech server’s address:
http://kokoro:8880in the Compose example above. - Leave Model as
kokoroand API key empty for a local server. - Press Test connection. It asks the server to say one word and reports whether audio came back.
- Press Save.
Then open a book and press the speaker button. The first sentence takes a moment while the server renders it; the play button pulses until sound starts.
Or connect it in configuration
Section titled “Or connect it in configuration”The same values can be set as environment variables (or in
appsettings.json), which suits a server set up from a script. Anything saved
in Settings takes precedence.
export ReadAloud__Enabled=trueexport ReadAloud__BaseUrl=http://localhost:8880Configuration settings
Section titled “Configuration settings”All of these go in the ReadAloud section of appsettings.json, or as
ReadAloud__Name environment variables. The first four can also be set in
Settings, which takes precedence.
| Setting | Default | What it does |
|---|---|---|
Enabled |
false |
Turns the natural voice on |
BaseUrl |
not set | Address of the speech server. http://host:8880 and http://host:8880/v1 both work |
Model |
kokoro |
Model name sent to the speech server |
ApiKeyEnvironmentVariable |
NOSTOS_READ_ALOUD_TOKEN |
Name of the environment variable holding a bearer token. Leave it unset for a local server |
MaxCharacters |
1200 |
Longest text accepted in one request. The reader sends one sentence at a time |
RequestTimeoutSeconds |
60 |
How long to wait for the speech server |
CacheDirectory |
a folder under the system temp directory | Where rendered sentences are kept |
CacheMaxBytes |
536870912 (512 MiB) |
Size limit of that folder. 0 turns the cache off |
Languages
Section titled “Languages”The natural voice reads books in these languages. A book declares its language in its own metadata; a book in any other language, or one that declares none, is read with the device voice.
| Language | Voices |
|---|---|
| English (US) | Heart, Bella, Michael, Fenrir |
| English (UK) | Emma, Isabella, George, Fable |
| Spanish | Dora, Alex |
| French | Siwis |
| Hindi | Alpha, Omega |
| Italian | Sara, Nicola |
| Japanese | Alpha, Kumo |
| Portuguese (Brazil) | Dora, Alex |
| Chinese (Mandarin) | Xiaoxiao, Yunxi |
What to expect from your hardware
Section titled “What to expect from your hardware”Kokoro runs on a CPU. On a 12-core desktop it rendered speech about three times faster than it is spoken, measured with the model’s ONNX build. Nostos fetches the next two sentences while the current one plays, so reading is continuous on a machine that renders faster than real time. On a slower machine there are pauses between sentences.
Rendered sentences are cached on the server, so going back a page or reading a chapter again costs nothing the second time.
A PDF has no sentences, only positioned pieces of text, so Nostos rebuilds them. It leaves out page numbers and running headers in the margins, rejoins a word hyphenated at the end of a line, skips raised note numbers, and says a sentence that runs over a page break in one go.
- A scanned PDF with no text layer has nothing to read, and the speaker button is not shown for it.
- A PDF does not say what language it is in. Nostos uses the language recorded for the book in your library, so set it there if the wrong voice reads.
- Pages with several columns, tables or formulas are read in the order the PDF stores them, which is not always the order you would read them in.
Limits
Section titled “Limits”- The natural voice needs to know the book’s language: from the EPUB’s own metadata, or from the book’s language in your library for a PDF.
- Changing speed is instant: it changes playback, not the rendering.
- With the device voice, most phones stop reading when the screen locks. That is a limit of the browser’s speech engine, which is why Nostos keeps the screen awake while it reads.