halpradio provides a flexible station management pipeline that combines bundled curated stations, custom local stations, online search via RadioBrowser API, and 1-click station sharing via GitHub PRs.
Station entries are managed by radio.Store across three distinct storage tiers:
flowchart LR
subgraph Storage Tiers
Embedded["Embedded Catalog (stations.yaml)"]
LocalConfig["User Config (~/.config/halpradio/stations.yaml)"]
OnlineAPI["RadioBrowser API (30,000+ Stations)"]
end
subgraph Store Manager
RadioStore["radio.Store"]
end
subgraph User Views
AllTab["Tab 1: All Stations"]
FavTab["Tab 2: Favorites"]
CatTab["Tab 3: Categories"]
APITab["Tab 4: Online Search"]
end
Embedded --> RadioStore
LocalConfig --> RadioStore
OnlineAPI --> RadioStore
RadioStore --> AllTab
RadioStore --> FavTab
RadioStore --> CatTab
RadioStore --> APITab
- Embedded Release Baseline: Included directly in the binary release via Go embed (
//go:embed stations.yaml). - Dynamic Remote Sync (Aggressive Caching & Lightweight Check):
- On launch,
halpradiochecks for updated catalog releases in the background. - Zero Server Load: Checks are throttled to once per 24 hours (
catalog_cache_ttl_hours: 24). Within TTL, zero network requests are sent. - Lightweight 304 Conditional Checks: When checking, conditional HTTP headers (
If-None-Matchwith ETag andIf-Modified-Since) are sent. If the remote catalog has not changed, the server returns304 Not Modifiedwith 0 body bytes. - Strict Validation: Downloaded YAML is strictly verified before caching to
~/.config/halpradio/catalog_cache.yaml. - CLI Update: Run
halpradio update-stationsorhalpradio -update-catalogto manually trigger an update.
- On launch,
- Created or edited interactively using the Add Station dialog (
akey binding). - Persisted locally on the user's computer.
- Merged seamlessly into the main station list without modifying git workspace files.
- Toggled on any station with the
fkey binding. - Stores complete station metadata, ensuring online RadioBrowser stations saved as favorites remain accessible across app restarts even when offline.
All station files (stations.yaml and ~/.config/halpradio/stations.yaml) adhere to the following schema:
stations:
- id: station-unique-id
name: "Station Name"
url: "https://stream.example.com/live.mp3"
genre: "Lofi / Chill"
country: "US" # 2-letter ISO country code (e.g. US, GB, SE, DE, FR, JP)
bitrate: 128 # Stream bitrate in kbps (e.g. 128, 192, 320)
codec: "MP3" # MP3, AAC, OGG, etc.
homepage: "https://example.com"halpradio includes a built-in client (radio.RadioBrowserClient) that connects to the public RadioBrowser API:
- Endpoint:
https://de1.api.radio-browser.info/json/stations/search - Features:
- Top-voted global station listings.
- Live keyword search by station name, tag, or country.
- Automatic fallback stream URL resolution.
- Stream metadata normalization (bitrate, codec, country flags).
Press Tab to navigate to the Online Search tab, type any genre or query (e.g., synthwave, bbc, jazz, japan), and press Enter to query thousands of live streams instantly.
To make expanding the public station catalog effortless for the community, halpradio includes an automatic snippet exporter:
- Select any station in your list (or create a new station via
a). - Press
p. halpradioautomatically formats the station as clean YAML and writes it directly to your system clipboard (using platform utilities likepbcopyon macOS,xclip/xselon Linux, or Windows clipboard).- Paste the snippet directly into
stations.yamland open a Pull Request!
# Generated by pressing 'p' in halpradio
- id: lofi-girl-radio
name: "Lofi Girl Radio"
url: "https://stream.example.com/lofi.mp3"
genre: "Lofi"
country: "FR"
bitrate: 128
codec: "MP3"