Text-to-speech mini-player with floating controls
Project description
Speakly
A lightweight floating TTS mini-player for your desktop.
Install
pipx install speakly
Or with Homebrew:
brew install noncuro/speakly/speakly
Quick Start
speakly "Hello, world!" # uses free edge-tts, no API key needed
speakly # reads from clipboard
speakly --file article.txt # reads from file
speakly --speed 2.0 # set playback speed
No API keys, no accounts, no configuration. It just works.
Features
- Floating mini-player -- always-on-top window with play/pause, scrub, speed control (1x-3x), and volume
- Free out of the box -- uses edge-tts (Microsoft Edge TTS), no API key required
- Premium voice upgrades -- swap in OpenAI, ElevenLabs, or Inworld when you want better quality
- Smart titles -- auto-generates a short title for the player window (Claude or GPT if configured, heuristic otherwise)
- Audio caching -- SHA256-based cache in
~/.speakly/cache/with 7-day TTL; repeated text plays instantly - Keyboard shortcut support -- wire up a system hotkey via macOS Shortcuts or Raycast
- Catppuccin Mocha dark theme -- easy on the eyes at any hour
Providers
| Provider | Quality | Speed Control | API Key | Best For |
|---|---|---|---|---|
| edge (default) | Good | Player only | None needed | Getting started, casual use |
| OpenAI | Great | Native 0.25-4x | Required | Speed range, consistent quality |
| ElevenLabs | Excellent | Player only | Required | Multilingual, natural voices |
| Inworld | Excellent | Player only | Required | High-quality at 2-3x speed |
Recommended: Inworld for fast listening
If you like listening at 2-3x speed, Inworld's TTS 1.5 Max model sounds excellent even sped up. Generation is fast and the audio quality is superb. Getting started takes a minute:
- Sign up at inworld.ai
- Grab your JWT key and secret from the dashboard
- Run
speakly configto save your keys
Configuration
speakly config # interactive setup -- set provider, speed, API keys
Config is saved to ~/.speakly/config.toml. API keys are stored securely in your system keychain via the keyring library.
You can also set environment variables directly:
export OPENAI_API_KEY=sk-...
export ELEVEN_API_KEY=...
export INWORLD_JWT_KEY=...
export INWORLD_JWT_SECRET=...
Usage
speakly [OPTIONS] [TEXT]
Options:
-p, --provider TTS provider: edge, openai, elevenlabs, inworld [default: edge]
-v, --voice Voice name or ID
-s, --speed Playback speed multiplier [default: 1.0]
-f, --file Read text from a file
--list-voices List available voices for the provider
--help Show help
Commands:
config Open interactive configuration
Keyboard Shortcut (macOS)
Three steps to read any text with a hotkey:
- Download
Speakly.shortcutfrom the latest release - Double-click to import into Shortcuts
- Go to System Settings > Keyboard > Keyboard Shortcuts > Services and assign a hotkey (e.g., Cmd+Shift+S)
Then: select text anywhere, copy it (Cmd+C), press your shortcut -- Speakly reads it aloud.
Some apps that support macOS accessibility services (Safari, Notes, TextEdit, VS Code) let the shortcut grab selected text directly, skipping the copy step.
How It Works
Text goes to edge-tts (or your chosen provider), comes back as MP3, and gets cached in ~/.speakly/cache/. The player window appears instantly in a loading state while TTS generates in the background. On a cache hit, playback starts immediately with no waiting.
Long text is automatically chunked and concatenated so there is no input length limit.
Contributing
git clone https://github.com/noncuro/speakly.git
cd speakly
uv sync
uv run speakly "test"
Fork it, branch it, send a PR. All contributions welcome.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file speakly-0.1.0.tar.gz.
File metadata
- Download URL: speakly-0.1.0.tar.gz
- Upload date:
- Size: 479.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46a85ab7c5d48bad727b349e92009ec9472fc72360769f7946cd033db6168e90
|
|
| MD5 |
07dde467d622aeca95e00ac3fbb49bb2
|
|
| BLAKE2b-256 |
97711442b5bc3b7b254c06b5c7ebd2e903f6736518e79cfa1be9a1fc8c508816
|
Provenance
The following attestation bundles were made for speakly-0.1.0.tar.gz:
Publisher:
publish.yml on noncuro/speakly
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
speakly-0.1.0.tar.gz -
Subject digest:
46a85ab7c5d48bad727b349e92009ec9472fc72360769f7946cd033db6168e90 - Sigstore transparency entry: 1007675025
- Sigstore integration time:
-
Permalink:
noncuro/speakly@367ab966258d24f1e2a0c727af3d377be5cf7e6b -
Branch / Tag:
- Owner: https://github.com/noncuro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@367ab966258d24f1e2a0c727af3d377be5cf7e6b -
Trigger Event:
release
-
Statement type:
File details
Details for the file speakly-0.1.0-py3-none-any.whl.
File metadata
- Download URL: speakly-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b03ae873e1e5d6baa7cb4976f691f356a4145538276325ad341b06304a668266
|
|
| MD5 |
1902995357f5cf9355198e7de037b0a8
|
|
| BLAKE2b-256 |
04914112922ca137d2079ef52ed250f473c292f6bae1a3e92de01c163001809e
|
Provenance
The following attestation bundles were made for speakly-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on noncuro/speakly
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
speakly-0.1.0-py3-none-any.whl -
Subject digest:
b03ae873e1e5d6baa7cb4976f691f356a4145538276325ad341b06304a668266 - Sigstore transparency entry: 1007675040
- Sigstore integration time:
-
Permalink:
noncuro/speakly@367ab966258d24f1e2a0c727af3d377be5cf7e6b -
Branch / Tag:
- Owner: https://github.com/noncuro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@367ab966258d24f1e2a0c727af3d377be5cf7e6b -
Trigger Event:
release
-
Statement type: