Overview
radio is an interactive command-line internet radio player featuring an arrow-key driven menu for selecting from preset radio stations. Uses mpv for high-quality audio streaming with optimized cache settings.
Currently configured with Rio de Janeiro radio stations, but easily customizable for any internet radio streams.
Features
Interactive station selection with arrow keys
Visual menu with highlighted selection
Keyboard-driven navigation (no mouse required)
Zero-cache streaming for real-time audio
Support for MP3 stream formats
Easy station list customization
Installation
Install mpv
Install the mpv media player: # Arch Linux
sudo pacman -S mpv
# Ubuntu/Debian
sudo apt install mpv
# macOS
brew install mpv
Make Script Executable
chmod +x ~/workspace/source/bin/radio
Add to PATH
echo 'export PATH="$HOME/workspace/source/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Usage
Basic Usage
# Launch interactive station selector
radio
Interactive Controls
Navigation
During Playback
Key Action ↑ (Up Arrow) Move to previous station ↓ (Down Arrow) Move to next station Enter Select station and start streaming Ctrl+C Exit menu or stop playback
Key Action q Quit mpv and return to terminal 9/0 Decrease/increase volume m Mute/unmute Space Pause/unpause (may cause buffering)
Default Stations
Preconfigured Rio de Janeiro stations:
95.7 SulAmérica Paradiso Classical and instrumental music
99.9 JB FM News and talk radio
102.1 Mix FM Contemporary hits and pop music URL: https://playerservices.streamtheworld.com/api/livestream-redirect/MIXRIO.mp3
102.9 Jovem Pan News, sports, and variety URL: https://live.paineldj.com.br/proxy/jptresrios?mp=/stream
Customization
Adding Your Own Stations
Open Script for Editing
nano ~/workspace/source/bin/radio
# or
vim ~/workspace/source/bin/radio
Modify Station Arrays
Find the station arrays and add your stations: radiosRioDeJaneiro = (
" 95.7 | SulAmérica Paradiso"
" 99.9 | JB FM"
"102.1 | Mix FM"
"102.9 | Jovem Pan"
# Add your stations here
"104.5 | Your Station Name"
)
radiosUrls = (
""
""
"https://playerservices.streamtheworld.com/api/livestream-redirect/MIXRIO.mp3"
"https://live.paineldj.com.br/proxy/jptresrios?mp=/stream"
# Add corresponding URL
"https://your-stream-url.com/stream"
)
Test Your Changes
radio
# Navigate to your new station and test
Finding Stream URLs
How to Find Internet Radio Stream URLs
Check Station Website
Look for “Listen Live” links and inspect the page source for .mp3, .aac, or .pls URLs
Use Browser Developer Tools
Open station’s web player
Open browser DevTools (F12)
Go to Network tab
Filter by media type
Play the stream and find the streaming URL
Source Code
#!/usr/bin/env bash
function select_option {
# https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu
ESC = $( printf "\033" )
cursor_blink_on () { printf " $ESC [?25h" ; }
cursor_blink_off () { printf " $ESC [?25l" ; }
cursor_to () { printf " $ESC [ $1 ; ${2 :- 1} H" ; }
print_option () { printf " $1 " ; }
print_selected () { printf " $ESC [7m $1 $ESC [27m" ; }
get_cursor_row () { IFS = ';' read -sdR -p $'\E[6n' ROW COL ; echo ${ ROW #* [}; }
key_input () { read -s -n3 key 2> /dev/null >&2
if [[ $key = $ESC [A ]]; then echo up; fi
if [[ $key = $ESC [B ]]; then echo down; fi
if [[ $key = "" ]]; then echo enter; fi ; }
# initially print empty new lines (scroll down if at bottom of screen)
for opt; do printf "\n" ; done
# determine current screen position for overwriting the options
local lastrow = ` get_cursor_row `
local startrow = $(( $lastrow - $# ))
# ensure cursor and input echoing back on upon a ctrl+c during read -s
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
cursor_blink_off
local selected = 0
while true ; do
# print options by overwriting the last lines
local idx = 0
for opt; do
cursor_to $(( $startrow + $idx ))
if [ $idx -eq $selected ]; then
print_selected " $opt "
else
print_option " $opt "
fi
(( idx ++ ))
done
# user key control
case ` key_input ` in
enter) break;;
up) (( selected -- ));
if [ $selected -lt 0 ]; then selected = $(( $# - 1)); fi ;;
down) (( selected ++ ));
if [ $selected -ge $# ]; then selected = 0 ; fi ;;
esac
done
# cursor position back to normal
cursor_to $lastrow
printf "\n"
cursor_blink_on
return $selected
}
clear;
echo
echo " Radios"
echo
radiosRioDeJaneiro = (
" 95.7 | SulAmérica Paradiso"
" 99.9 | JB FM"
"102.1 | Mix FM"
"102.9 | Jovem Pan"
)
radiosUrls = (
""
""
"https://playerservices.streamtheworld.com/api/livestream-redirect/MIXRIO.mp3"
"https://live.paineldj.com.br/proxy/jptresrios?mp=/stream"
)
select_option "${ radiosRioDeJaneiro [ @ ]}"
choice = $?
choiceName = ${ radiosRioDeJaneiro [ $choice ]}
choiceUrl = ${ radiosUrls [ $choice ]}
# echo "choice: ${choice}"
# echo "choiceName: ${choiceName}"
# echo "choiceUrl: ${choiceUrl}"
mpv -cache = no --no-cache ${ choiceUrl }
Advanced Configuration
Multiple Station Lists
US Stations
European Stations
Selection Menu
# Add to script
radiosUS = (
"88.5 | WFDD Public Radio"
"90.7 | WMFE NPR"
"95.5 | WPOC Country"
)
radiosUS_urls = (
"https://wfdd-ice.streamguys1.com/wfdd1-mp3"
"https://wmfe.streamguys1.com/wmfe_main_mp3"
"https://stream.revma.ihrhls.com/zc1609"
)
Enhanced mpv Options
High Quality
Low Latency
With Visualizer
# Better quality, more buffering
mpv --cache=yes --cache-secs=10 --audio-channels=stereo ${ choiceUrl }
# Minimal delay (current default)
mpv --cache=no --no-cache ${ choiceUrl }
# Audio visualizer
mpv --lavfi-complex= '[aid1]asplit[ao][a1];[a1]showwaves=mode=cline[vo]' ${ choiceUrl }
Example Workflows
Work Background Music
# Launch radio in background
radio &
# Or run in tmux/screen session
tmux new-session -d -s radio 'radio'
Scheduled Radio Alarm
Systemd Timer
At Command
Cron Job
# Create radio.service
[Unit]
Description = Radio Alarm
[Service]
Type = simple
User = yourusername
ExecStart = /home/yourusername/workspace/source/bin/radio
Troubleshooting
Install mpv media player: # Arch Linux
sudo pacman -S mpv
# Ubuntu/Debian
sudo apt install mpv
# macOS
brew install mpv
Test stream URL directly: # Test URL
mpv https://your-stream-url.com/stream
# Check URL is accessible
curl -I https://your-stream-url.com/stream
Common issues:
Stream URL changed or station offline
Geo-restricted content
Firewall blocking streaming ports
Terminal compatibility issue. Try: # Ensure proper terminal type
export TERM = xterm-256color
# Or use alternative terminal
# (alacritty, kitty, gnome-terminal)
Audio stuttering or buffering
Adjust cache settings: # Edit script, change mpv line to:
mpv --cache=yes --cache-secs=5 ${ choiceUrl }
Empty station plays nothing
Some default stations have empty URLs: radiosUrls = (
"" # Empty - will fail
"" # Empty - will fail
"https://..." # Working URL
)
Solution: Add valid URLs for all stations or remove empty entries
Tips & Best Practices
Favorite Stations : Put your most-listened stations at the top of the array for quick access.
Stream Quality : Most internet radio streams are 128kbps MP3. Higher quality streams (320kbps) use more bandwidth.
Network Usage : Streaming audio continuously uses approximately 1-2 MB per minute depending on bitrate. Monitor usage on metered connections.
Backup Players : If mpv isn’t available, the script can be modified to use mplayer, vlc, or ffplay as alternatives.
Alternative Players
Modify the last line for different players:
mplayer -cache 128 ${ choiceUrl }
See Also
mpv Documentation Complete mpv manual and options
Command Overview All available utilities
Update Utility System update command
Radio-Browser Worldwide internet radio directory