Skip to main content

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

1

Install mpv

Install the mpv media player:
# Arch Linux
sudo pacman -S mpv

# Ubuntu/Debian
sudo apt install mpv

# macOS
brew install mpv
2

Make Script Executable

chmod +x ~/workspace/source/bin/radio
3

Add to PATH

echo 'export PATH="$HOME/workspace/source/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Usage

Basic Usage

# Launch interactive station selector
radio

Interactive Controls


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

1

Open Script for Editing

nano ~/workspace/source/bin/radio
# or
vim ~/workspace/source/bin/radio
2

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"
)
3

Test Your Changes

radio
# Navigate to your new station and test

Finding Stream URLs

1

Check Station Website

Look for “Listen Live” links and inspect the page source for .mp3, .aac, or .pls URLs
2

Use Browser Developer Tools

  1. Open station’s web player
  2. Open browser DevTools (F12)
  3. Go to Network tab
  4. Filter by media type
  5. Play the stream and find the streaming URL
3

Radio Directory Sites


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

# 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

# Better quality, more buffering
mpv --cache=yes --cache-secs=10 --audio-channels=stereo ${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

# 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)
Adjust cache settings:
# Edit script, change mpv line to:
mpv --cache=yes --cache-secs=5 ${choiceUrl}
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
man mpv

Command Overview

All available utilities

Update Utility

System update command

Radio-Browser

Worldwide internet radio directory

Build docs developers (and LLMs) love