jade71 downloadsReads your markdown notes aloud via a local OpenAI-compatible TTS server (e.g. OpenVox). Select a sentence for a quick play button, with chunk prefetching for gapless playback, a draggable toolbar, table/parens/code filters, and WAV export.
Audiobook-style TTS for your notes.
Read any markdown note aloud through a local OpenAI-compatible TTS server. Gapless chunked playback, per-note resume, and a draggable mini-player — listen to your notes on a walk, while cooking, or just to rest your eyes.
A local OpenAI-compatible TTS server on http://127.0.0.1:8000 (configurable).
/v1 endpoints this plugin uses. Install, launch, done./v1 contract, with no daily character limit. Runs open-source backends (Kokoro, Chatterbox / Chatterbox Multilingual, Qwen3-TTS) with zero-shot voice cloning and up to 25 languages. Cross-platform (macOS MPS / Linux · Windows CUDA / CPU)./v1 contract works too.Read current note aloud. The mini-toolbar appears at the bottom — that's your player.Tip: select a sentence to get a one-click ▶ button next to it.
Reading
Read this folder as a queue / Read backlinks as a queue5/23 in the toolbar)8 chunks · ≈ 12 min)Playback
mm:ss, click-to-cycle speed, optional now-playing tickerPerformance
Content filters
(...) / (...)Export
Assign hotkeys under Settings → Hotkeys.
http://127.0.0.1:8000/v1omnivoicekoKorean-Female-EunjiOther Korean voices on OmniVoice: Korean-Female-Jiwoo, Korean-Male-Hyunwoo, Korean-Male-Jihoon, Korean-Male-Junseo.
main.js, manifest.json, and styles.css from the latest release.<vault>/.obsidian/plugins/narrate/ (create the folder if needed).Install BRAT, then add jang-hs/obsidian-narrate as a beta plugin.
Pending submission.
With Save audio file on (or via the generate command), all chunk WAVs are concatenated into one file written into the vault as <noteName>.wav.
Audio folder → saved next to the source note.Audio folder (e.g. audiobooks) → saved there using the source note's basename./v1 endpoints the plugin talks toAll requests go to the configured base URL (default http://127.0.0.1:8000/v1).
| Method | Path | Used for |
|---|---|---|
GET |
/health |
Reachability check before any speech request. |
GET |
/models |
Populate the Model dropdown (the Fetch button). |
POST |
/models/{model}/load |
Optional warm-up before the first speech request. |
GET |
/models/{model}/languages |
Populate the Language dropdown. |
GET |
/models/{model}/voices?language={code} |
Populate the Voice dropdown for the chosen language. |
POST |
/audio/speech |
Synthesize one chunk; body { model, input, language, voice, response_format: "wav" } returns a raw WAV. |
POST |
/audio/speech with stream: true |
(Not used by default — plugin requests full WAV per chunk and prefetches the next ones.) Server-sent events response.created → audio.chunk (base64 WAV) → response.completed. |
Behavior:
AbortController so the server doesn't keep working in the background.MIT — see LICENSE.
If this plugin makes your reading life a little better, you can buy me a coffee — it's genuinely appreciated and helps keep the project maintained.