DEV Community

Cover image for I put Spotify on a $25 Win98 desk player (ESP32, no PSRAM)
Enrique Uribe
Enrique Uribe Subscriber

Posted on

I put Spotify on a $25 Win98 desk player (ESP32, no PSRAM)

Phones already play music. They just refuse to sit on a desk and stay out of the way.

So I rebuilt Windows Media Player as a real desk object: a Hosyond 4" ESP32 touchscreen that shows Spotify now-playing, album art, and prev / pause / next — no phone unlock, no PSRAM, no full-screen framebuffer.

Desk hero

What it actually is

A dedicated now-playing surface on a Hosyond 4" panel:

  • Win98-styled chrome (title bar, menus, sunken wells, PLAYING / PAUSED lamp)
  • Live Spotify track, artist, progress
  • 160×160 album art over Wi‑Fi
  • Touch transport: previous / pause / next

Honest scope: this is not a Spotify Connect speaker. Audio still plays on your phone or computer. The on-screen volume slider is decorative. The point is constrained hardware that earns a spot on the desk — not a Linux kiosk taped to a screen.

Now playing

Design first, firmware second

I locked the UI in the browser at the panel's exact pixels (480×320) with a 98.css-flavored HTML prototype, then ported it to LVGL firmware. Same visual target. No "we'll make it look Win98 later."

Prototype beside the live panel

Stack

Hardware

  • Hosyond 4" 320×480 ESP32 touch (E32R40T-class)
  • ESP32-WROOM-32E, Wi‑Fi, no PSRAM, 4 MB flash
  • ST7796S IPS @ 480×320 landscape
  • XPT2046 resistive touch
  • USB‑C for flash / power

Firmware

  • PlatformIO · LVGL 8 · TFT_eSPI
  • Spotify Web API over TLS
  • tjpgd for JPEG decode

Flow (one glance)

Spotify Web API → ESP32 (playback JSON + JPEG + transport)
JPEG → tjpgd → 160×160 RGB565
LVGL 8 → TFT_eSPI → ST7796S
XPT2046 → LVGL pointer → control deck
Enter fullscreen mode Exit fullscreen mode

Tradeoffs that actually mattered

  1. No PSRAM / ~320 KB RAM → partial LVGL draw buffer (~20 lines). No full-file JPEG malloc. No full-screen framebuffer.
  2. Album art → stream JPEG through tjpgd MCU blocks into one 160×160 RGB565 buffer instead of decoding a huge image into RAM.
  3. Panel bring-up → manufacturer ST7796S init + calibrated XPT2046; landscape so USB sits correctly; fonts / RGB proven with an on-panel LVGL render test before the Win98 chrome.
  4. Auth without a keyboard → Spotify Client ID + refresh token / PKCE; secrets in a gitignored secrets.h, never committed.
  5. Prototype-first UI → lock the look at exact resolution in the browser, then implement in LVGL.

Made for a real desk, not a Dribbble shot.

Links

Unofficial personal project. Spotify is a trademark of Spotify AB.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more