Skip to content

Latest commit

 

History

22 Commits

Folders and files

Repository files navigation

addictune

A terminal client for DI.FM and other AudioAddict radio networks

addictune is an unofficial DI.FM client for your terminal. It also supports the other AudioAddict networks: RadioTunes, ROCKRADIO.COM, JAZZRADIO.com, Classical Radio and ZenRadio. Browse live channels, DJ mixshows, curated playlists and your liked tracks. Control playback from the keyboard or your system's media controls.


CI Release License: MIT Donate USDT

Python 3.12+ Built with Textual Managed with uv Code style: Ruff Platforms SDK: addictune-sdk

Demo · Features · Install · Quick start · Keys · Privacy · How it works · Contributing


addictune playing a live DI.FM show, stacked in front of Jazz Radio, Classical Radio and Zen Radio, each in its own color theme

Note

Beta software. addictune is in beta and under active development. Features and behavior may change between releases.

Unofficial project. addictune is not affiliated with, endorsed by or sponsored by AudioAddict, DI.FM, RadioTunes, ROCKRADIO.COM, JAZZRADIO.com, Classical Radio or ZenRadio. All names and trademarks belong to their owners. You need your own AudioAddict account.

🎬 See it in action

addictune demo: arrowing through DI.FM channels, the info sidebar, starting the live show, the expanded player, switching tabs, searching for ASOT and opening the command palette

Channels and the info sidebar · a live show · the expanded player · Mixshows, Playlists and Tracks · global search · command palette



📻
Six networks
Each in its own color theme
🔴
Live shows
On-air badges, schedule and recent tracks
⌨️
Keyboard first
Arrows or vim keys, search and filters
🎛️
Media keys
MPRIS, macOS and Windows controls

⭐ Like what you see? Star the repo to help other terminal dwellers find it.

✨ Features

  • Six networks, one client. Each network has its own color theme. Switch networks from the command palette.
  • Channels, Mixshows, Playlists, Tracks. Tabs appear when the active network supports that content. The Tracks tab shows your liked tracks.
  • Live shows. A LIVE NOW badge marks channels with a show on air. The info panel shows current and upcoming shows, plus recently played tracks.
  • Follow and rate. Follow channels, mixshows, playlists and live shows, and like or dislike tracks from the keyboard.
  • Search and filters. / searches the current list, Ctrl+G searches across categories, and Ctrl+F opens filter and sort options.
  • Playback controls. Seek, adjust volume, mute, and skip between tracks. Expand the playback bar to see more detail, including stream format and bitrate.
  • System media controls. Use media keys and view playback information through MPRIS on Linux, MediaPlayer on macOS, and SMTC on Windows.
  • Artwork. Cover art rendered as pixel art in your terminal.
  • Responsive playback. Audio runs in a separate process to keep the interface responsive. Interrupted live streams reconnect automatically.
  • Audio settings. Choose the output device, sample rate and latency without restarting the app.
  • Vim navigation. Use j, k, g and G alongside the arrow keys.
DI.FM channel list with the info panel and compact playback line DI.FM channel list with the info panel and the expanded playback bar
Channels with the info panel Info panel and expanded playback bar
Playlists tab with a track playing in the expanded playback bar Settings dialog on the Audio Output page with output device and sample rate options
Playlists Audio settings
More networks: Jazz Radio, Classical Radio, Rock Radio, RadioTunes, Zen Radio and the network picker
Jazz Radio channel list in its red theme with Bebop playing Classical Radio channel list in its blue theme with Bach playing
Jazz Radio Classical Radio
Rock Radio channel list in its charcoal and yellow theme with Heavy Metal playing RadioTunes channel list in its navy and orange theme with New Age playing
Rock Radio RadioTunes
Zen Radio channel list in its teal theme with Relaxation playing Choose Radio Station dialog listing the six AudioAddict networks
Zen Radio Network picker, from the command palette

📦 Install

Prebuilt binaries (no Python needed)

Download the latest beta build for your OS from the Releases page:

OS Asset Install
macOS (Apple Silicon) addictune-cli-<version>-macos-arm64.pkg Open the installer and enter your admin password when prompted. It installs to /usr/local and adds the addictune-cli command to /usr/local/bin.
macOS (Intel) addictune-cli-<version>-macos-x86_64.pkg Same as above.
Linux (x86_64) addictune-cli-<version>-linux-x86_64.tar.gz Extract it and run addictune-cli/addictune-cli.
Windows (x64) addictune-cli-<version>-windows-amd64.zip Extract it and run addictune-cli\addictune-cli.exe.

Linux binaries also require PortAudio. On Debian/Ubuntu, install it with sudo apt install libportaudio2 before launching the app.

Each release includes SHA256SUMS for verifying the downloaded files. Run addictune-cli --self-test to check UI resources and the audio worker without signing in or playing audio.

Important

The binaries are not code-signed or notarized. macOS Gatekeeper or Windows SmartScreen may display a warning on first launch. You can also install from source using uv below.

From source with uv

uv tool install git+https://github.com/ukw2d/addictune-cli
addictune            # or: addictune-cli

Requires Python 3.12+. On Linux you also need the PortAudio library (libportaudio2 on Debian/Ubuntu) for audio output.

From a checkout

git clone https://github.com/ukw2d/addictune-cli
cd addictune-cli
just install         # editable install via uv
just run --dev       # run from source with debug logging

🚀 Quick start

  1. Run addictune (addictune-cli if you installed a prebuilt binary).
  2. Sign in with your AudioAddict email and password.
  3. Choose a network (change it later from the command palette, Ctrl+P).
  4. Navigate with ↑/↓ or j/k. Press Enter to play; use Space to play, pause or stop, depending on the content.

⌨️ Keyboard shortcuts

The footer shows keyboard shortcuts available in the current context.

Key Action Key Action
Enter Play selected Space Play / pause / stop
s Stop p / n Previous / next track
← / → Seek −10 s / +10 s + / - Volume up / down
m Mute l / d Like / dislike current track
f Follow / unfollow selected item Ctrl+L Follow / unfollow the airing live show
e Expanded playback bar i Media info panel
/ Find in current list Ctrl+G Search all categories
Ctrl+F Filter and sort options Ctrl+U Clear search
j k g G Down / up / top / bottom Esc Close search or dialog
Ctrl+P Command palette (settings, station, theme)

You need to be signed in to like, dislike or follow. Shortcuts are enabled when they apply; for example, p is unavailable during live radio playback.

🔐 Accounts and privacy

addictune saves your AudioAddict email and password so it can sign you in again when a session expires. It does not store session tokens. Credentials are saved in your operating system's credential store:

OS Credential store
macOS Login Keychain (item addictune-cli)
Linux Secret Service (GNOME Keyring, KWallet)
Windows Credential Manager

If no credential store is available, credentials are saved in session.json with 0600 permissions in the config directory. To sign out, choose Sign out in the command palette (Ctrl+P); it removes the saved credentials from the credential store (and session.json, if present) and returns to the login screen.

macOS Linux Windows
Config ~/Library/Application Support/addictune-cli ~/.config/addictune-cli %LOCALAPPDATA%\addictune-cli
Logs and artwork cache ~/Library/Caches/addictune-cli ~/.cache/addictune-cli %LOCALAPPDATA%\addictune-cli\Cache

addictune connects to AudioAddict's API, streaming servers and artwork servers, and once per launch asks the GitHub API whether a newer release exists (no account data is sent; turn it off in Settings → General → Updates). It does not collect analytics.

Error reports. When something breaks, addictune sends an anonymous error report to the developer's Sentry project so bugs can be fixed without asking you for logs. A report contains the app version, your OS, the error with its stack trace and the recent log lines leading up to it, and which station you were tuned to. It never contains your email, password, account id, listen key or stream tokens: every URL and every such value is redacted before sending (see telemetry.py), and your IP address is not stored. Reports are on by default; turn them off in Settings → General → Error reports (a stream that is already playing finishes under the old setting).

🧠 How it works

flowchart LR
    SDK["addictune-sdk<br/>(async API client)"] --> S["services<br/>channels · live shows · queue<br/>search · follow · votes"]
    S --> UI["Textual UI<br/>tabs · lists · playback bar"]
    UI -- commands --> A["audio process<br/>decode (PyAV) · output (PortAudio)"]
    A -- events --> UI
    UI --> M["OS media session<br/>MPRIS · MediaPlayer · SMTC"]
Loading
  • UI: Textual renders the interface and handles keyboard input.
  • API: addictune-sdk, an async client for the AudioAddict API.
  • Audio: PyAV decodes the audio and sounddevice sends it to your output device. Both run in a separate process that shuts down with the app. For playback logs and troubleshooting, see docs/debugging-playback.md.
  • Packaging: Nuitka produces standalone builds for each supported OS and CPU architecture.

🛠️ Development

just            # list recipes
just check      # ruff + full test suite
just test -k x  # run selected tests
just run --dev  # DEBUG logging + Textual devtools (run `uv run textual console` alongside)
just package    # build the standalone artifact for this OS into build/artifacts/

After retaking screenshots, run uv run python tools/readme_hero.py to rebuild the stacked header image.

See CONTRIBUTING.md for the workflow. release-binaries.yml can be run manually to test builds. A matching v* tag prepares a draft beta release with binaries and checksums; publish it after verifying the downloads.

☕ Support

addictune is free and open source. If you enjoy it, you can support development with a USDT donation. Starring the repo and reporting bugs help too.

USDT on TRON (TRC-20)

TBtdQtJ7FTvwYQqcpjy9NFe8mNaW66fWqv

USDT on Ethereum (ERC-20)

0x0548237F4573155d32b32739cE68a76eA66e6673

Warning

Send only USDT, and only on the network named above the address. Tokens sent on any other network may be lost.

📄 License

MIT © ukw2d

Made with ❤️ for DI.FM.

Releases

Sponsor this project

Packages

Used by

Contributors

Languages