A terminal radio player written in Rust. It plays a small set of predefined stations through a single GStreamer pipeline and renders a live FFT-based spectrum from that same decoded audio stream.
- Rust toolchain (
cargo) - GStreamer
This project currently assumes a macOS setup with Homebrew.
Install GStreamer and Rust with Homebrew:
brew install gstreamer
brew install rustOn Apple Silicon, Homebrew is usually installed under /opt/homebrew.
On Intel Macs, Homebrew is usually installed under /usr/local.
cargo runIf you want to use the app as a normal command instead of running it through Cargo each time:
cargo install --path .Then run it from anywhere with:
iterm-playerIf the command is not found immediately, open a new terminal tab or run:
rehashYou can verify where Cargo installed it with:
which iterm-playerIf you update the repo later, reinstall the command with:
cargo install --path . --forceMake sure ~/.cargo/bin is on your shell PATH if you installed with cargo install --path .. The included iTerm2 widget launches iterm-player through a login zsh shell, so whatever works in a normal terminal should also work from the widget.
cargo build --releaseThe compiled binary will be available at:
./target/release/iterm-playerYou can also run that binary directly without installing it globally:
./target/release/iterm-playerOr create a symlink so the command is available on your shell PATH:
ln -sf "$(pwd)/target/release/iterm-player" "$(brew --prefix)/bin/iterm-player"Then run:
iterm-playerIf the command does not autocomplete or is not found immediately, run:
rehashAnd verify the symlink with:
ls -l "$(brew --prefix)/bin/iterm-player"
which iterm-player/play nts1/play nts2/play worldwide/play fip/color red/color yellow/color cyan/volume 3/stop/quitor/q
Running /play without a station shows the available station keys in the status panel.
Running /color without a value shows the available color names.
Running /volume without a value shows the current volume and expected range.
Tabcompletes commands such as/pl->/playTabalso completes station keys after/playTabcompletes color names after/colorTabcompletes/volumelike the other top-level commands
The repo includes an iTerm2 Python status bar script at iterm2/iterm_player_statusbar.py.
It provides one compact status bar widget in this order:
▶ or ■ | ▶▶ | Radio Name
When the player is stopped, the first control shows ▶. When the player is running, it shows ■. Clicking the widget opens a small popover with ▶/■ and ▶▶ buttons. The widget only controls the running player through the local Unix socket at /tmp/iterm-player.sock. If no player is running, using the widget starts a new iTerm2 window, launches iterm-player, and starts the first station.
- Create the iTerm2 AutoLaunch directory if it does not already exist:
mkdir -p "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch"- Symlink the script from this repo into AutoLaunch:
ln -sf "$(pwd)/iterm2/iterm_player_statusbar.py" "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/iterm_player_statusbar.py"-
Restart iTerm2, or launch the script manually from
Scripts > Manage. -
In iTerm2, enable the status bar for your profile:
Settings > Profiles > Session > Status Bar Enabled -
Open the status bar configuration:
Settings > Profiles > Session > Configure Status Bar... -
Add this component:
iTerm Player
- The widget expects the
iterm-playercommand to work in a normal login shell. - If the widget shows a bug icon or does not update, open
Scripts > Manage > Consolein iTerm2 to inspect Python script errors. - The widget reads
/tmp/iterm-player.jsonfor display state and sends commands to/tmp/iterm-player.sock.
The app accent color can be changed at runtime. This affects:
- panel borders
- spectrum color
- overall interface accent
Available colors:
cyanredyellowgreenbluepinkmagentawhitegreydark-greyorangebrownrainbow
The player volume can also be changed at runtime with /volume [0-10], where 0 is muted and 10 is full volume.
- Playback and analysis now come from the same GStreamer decode pipeline, which makes station behavior more consistent than the previous split
mpv+ffmpegapproach. - Spectrum analysis is still done in-process in Rust after pulling decoded PCM from GStreamer.
FIPnow uses a direct Icecast AAC stream instead of the old HLS playlist.- The app is radio-only now. Apple Music support was intentionally removed from the main codebase.
The old implementation was copied into:
archive/
That snapshot includes the original Node.js entrypoint, Apple Music integration code, and the previous README/config files.
