YouTube Music in classic Winamp — era-correct, country-localized, zero accounts.
Quick start · Features · Era radio · How it works · FAQ
Actual capture: Crystal Waters streaming at 192 kbps with live ICY titles. Really whips the llama's ass.
| 📻 Never-ending era radio | One command starts a shuffled 1995–2005 hit parade that refills itself — the bridge watches the playlist and mixes in fresh tracks before you run out, never repeating a song |
| 🌍 Localized to your country | Your IP's country is auto-detected and ~40% of the queue is that country's actual number-one hits of the era — fetched from real chart archives, never guessed |
| ⚡ Snappy controls | Upcoming tracks are prefetched and cached to disk; pressing next starts the next song in a fraction of a second |
| 🏷️ Real titles in Winamp | ICY (SHOUTcast-style) metadata, so the title bar and playlist show Artist – Title like a proper radio |
| ⏩ Seeking | The position slider works on cached tracks (HTTP Range requests) |
| 🎧 Public playlist radio | mix queues any public YouTube Music playlist by name — no auth needed |
| 🖥️ System tray controller | Now-playing menu, playback controls, era radio one click away |
| 🎯 Plays anything | Search queries, video URLs, whole YouTube/YouTube Music playlists |
| ❤️ Liked songs | Optional: your YouTube Music likes via ytmusicapi auth |
| 📦 Single-file exe | No Python, no PATH surgery — download and go |
| 🪶 No accounts, no API keys | For everything above except liked songs |
- Download
ytm-winamp-setup.exeand run it — a proper installer wizard: the app, Winamp (via winget), portable yt-dlp/ffmpeg, shortcuts, and the default Winamp Modern theme. - Check "Start the era radio" on the finish page.
- That's it — use the desktop/Start-menu shortcut next time, or
ytm-winampfrom any terminal.
Prefer portable? Grab the bare
ytm-winamp.exe
instead and run ytm-winamp setup once yourself.
Install from source instead
pipx install . # or: pip install .[liked]
ytm-winamp setup
ytm-winampRequires Python 3.10+. Everything setup does is idempotent — whatever is
already installed is detected and left alone.
Bare ytm-winamp (or ytm-winamp era) starts a never-ending radio of
Winamp-era hits, roughly 1995–2005. The bridge watches Winamp's playlist
position and appends a fresh batch of tracks before the queue runs out —
with no repeats. About 60% is the worldwide canon that was on every
playlist everywhere; the other 40% comes from your own country's charts
of those years. Want a fixed queue instead? ytm-winamp era --no-radio.
Local chart data sources:
| Source | Countries | Notes |
|---|---|---|
| Wikipedia national number-one lists (CC-BY-SA) | 🇩🇪 🇦🇹 🇨🇭 🇮🇹 🇪🇸 🇳🇱 🇫🇷 🇮🇪 🇩🇰 🇫🇮 🇨🇦 🇯🇵 | Per-year lists, List of number-one hits of YYYY (…) style |
| Wikipedia decade/all-time lists | 🇬🇧 🇳🇿 🇸🇪 🇳🇴 | Year-filtered while parsing |
| Wikipedia year-end charts | 🇺🇸 🇦🇺 🇧🇪 | Billboard Hot 100 year-ends; ARIA year-end top 100; Ultratop Wallonia |
| slagerlistak.hu | 🇭🇺 | Year-end Rádiós Top 40 charts |
That's 20 countries and counting. No list for yours? You get the global
parade with a console note — and adding a country is usually a one-line page
pattern in charts.py (COUNTRY_SOURCES).
PRs welcome.
ytm-winamp era --country DE # force a country (code or name)
ytm-winamp era --global-only # skip local charts
ytm-winamp era -n 50 # bigger queue (default 25)Winamp 5.x can't fetch YouTube directly — the googlevideo CDN rejects its HTTP
client ([access denied], if you ever tried). So a tiny localhost bridge does
the fetching instead:
search / URL / charts pre-resolved, cached
YouTube ───────────────▶ yt-dlp ──▶ ffmpeg ──▶ MP3 ──▶ http://127.0.0.1:8797 ──▶ Winamp
(disk cache + prefetch) (ICY titles)
- Stream URLs resolve when a track downloads, never when enqueued — googlevideo expiry is a non-issue
- Two download workers, one retry per track, graceful 502s — flaky networks don't freeze the player
- Titles ride along as ICY metadata; the playlist keeps
#EXTINFtitles like it's 1999
| Command | What it does |
|---|---|
ytm-winamp |
The era radio (same as era) |
ytm-winamp era [--country X] [--global-only] [--no-radio] [-n N] |
Never-ending era radio, optionally localized |
ytm-winamp play <query or URL> [-n N] |
Search, video, or whole playlist |
ytm-winamp mix <name> [--list] [-n N] |
Queue a public YouTube Music playlist found by name |
ytm-winamp tray |
System-tray controller (now playing, playback controls) |
ytm-winamp liked [--shuffle] |
Your YouTube Music liked songs (auth needed) |
ytm-winamp search <query> [-n N] |
List results with URLs |
ytm-winamp setup |
First-run onboarding: Winamp + tools + theme |
ytm-winamp serve |
Run the bridge in the foreground (debugging) |
⚙️ Configuration reference
| Setting | How |
|---|---|
| Winamp path | set YTM_WINAMP_EXE if Winamp isn't in the default location |
| Bridge port | --port (default 8797) |
| Bridge log | %TEMP%\ytm-winamp-bridge.log |
| Track cache | %TEMP%\ytm-winamp-cache (up to 32 tracks, LRU) |
| Portable tools | %USERPROFILE%\.ytm-winamp\bin |
| YT Music auth | %USERPROFILE%\.ytm-winamp\ytmusic.json |
| Era/geo data | %USERPROFILE%\.ytm-winamp\ (country.json, charts_*.json, era_cache.json) |
❤️ Liked songs: one-time auth
Reading your liked songs requires a YouTube Music login via ytmusicapi
(bundled in the exe). Run one of these once, then move the resulting file
to %USERPROFILE%\.ytm-winamp\ytmusic.json:
ytmusicapi oauth # recommended; needs a Google Cloud OAuth client
ytmusicapi browser # paste request headers copied from music.youtube.comPass a different location with ytm-winamp liked --auth <path>.
- Winamp-era radio with country-localized charts
- ICY stream titles
- Single-file exe + one-command setup
- YouTube Music liked songs
- Public YouTube Music playlists by name (
mix, no auth) - System tray controller
- Seeking (HTTP Range in the bridge)
- More countries in
COUNTRY_SOURCES(PRs welcome) - winget package submission (draft manifests in
packaging/winget/)
Does this download videos?
No. Audio is streamed and transcoded on the fly; a small rolling cache of
recent tracks (max 32) lives in %TEMP% and is evicted automatically.
Why does the first track take a few seconds?
Cold start: the bridge resolves and starts transcoding track one while prefetching the rest of the queue behind it. After that, cached tracks switch in a fraction of a second.
Winamp shows a video id instead of a title
You're on an old bridge from before ICY titles (v0.4.0). Re-run any play command — the bridge restarts itself on the new code.
Issues and PRs are welcome — especially new country sources for
COUNTRY_SOURCES (see the
era section). Run the tests with
python -m pytest tests/.
Unofficial hobby project, not affiliated with Winamp, YouTube, or Google. Streams audio through yt-dlp for personal playback; make sure your usage complies with YouTube's Terms of Service and applicable law. Chart data: Wikipedia (CC-BY-SA) and slagerlistak.hu.
Made with 🦙 for the llama-whipping community · MIT · back to top