ESP32 + VS1053 based network and SD audio player with a responsive web interface.
A very capable audio player with:
- MP3, M4A, AAC, OGG, and 16-bit FLAC playback
- Playlist queue for 100 items
- WebSocket based live UI
- A very fast SD card filebrowser
- Radio presets
- Automatic adding of premium/private channels during build
- Internet radio search with radio-browser.info
- Favorites system
- Mobile friendly interface
- No cloud dependency
- No accounts
- No telemetry
- No phone app install
- No ads
- No “smart platform”
- Just a websocket UI on your LAN
- VS1053 hardware decoder with MP3, M4A, AAC, OGG and FLAC decoding
- Local SD playback
- Internet radio streaming
- Playlist queue system
- Favorites saving/loading
- Playback state synchronization between UI clients
- Clean UI optimized for mobile use
- Responsive split-pane layout
- Works on all modern browsers
- Touch friendly controls
- Search interface for radio stations
- Overlay "now playing" mode
- Toast notifications and errors
The player can be configured with multiple WiFi networks and automatically connects to the strongest available known network.
This allows the same device to be used with different network setups such as a home network and a mobile phone hotspot without requiring reconfiguration.
Multiple simultaneous clients are supported and kept in sync with the player state.
Search and file browser requests are handled async to keep the UI responsive.
File browser example with a single client:
- The async backend handling and UI rendering of 100+ SD card items takes about ~2000ms
- While reading and playing 16-bit FLAC audio from the same SD card
- While the UI remains responsive
Minimal component count:
- WEMOS S3 MINI
- WEMOS Micro SD card shield
- Adafruit VS1053 Codec + MicroSD Breakout
- Optional Adafruit 1.3" I²C OLED status indicator
- Web browser as main UI
An optional Adafruit 1.3" I²C OLED display can be added for device status information.
It displays boot progress, connection status and the current IP address.
Note: To keep the player unobtrusive and power efficient, the OLED automatically sleeps after startup.
Wake-up is performed using a capacitive touch input, which can be as simple as a GPIO connected to a metal button, screw head or other exposed conductive surface.
The current implementation assumes dedicated SPI buses for SD card and VS1053 access.
Shared SPI configurations may compile, partially function, fully function or fail in creative and confusing ways.
Dedicated SPI wiring is the recommended and supported configuration.
Before compiling create a new file with your WiFi and location secrets:
src/secrets.hpp
Use this example setup as a template:
#pragma once
struct Secret
{
const char *SSID;
const char *PSK;
};
/* OSAP will connect to the strongest available network */
constexpr Secret networks[] =
{
{"network1", "password"},
{"network2", "password"},
};
/* Central European Time - see:
https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv */
const char *TIMEZONE = "CET-1CEST,M3.5.0,M10.5.0/3";
/* Replace "nl" with your own country code:
https://en.wikipedia.org/wiki/ISO_3166-2#Current_codes */
const char *NTP_POOL = "nl.pool.ntp.org";
/* Optional custom mDNS hostname */
//#define OSAP_HOSTNAME "music-player"Preset radio stations are defined in src/presets.hpp.
Adding private or premium radio presets is very easy.
Place one or more .pls playlist files in the project root before compiling.
During build:
.plsfiles are automatically parsed- presets are generated and merged into the main preset list
The added .pls files are ignored by git.
The web UI consists of two panes.
A selectable source tab on the left and a playlist tab on the right.
There are 4 source tabs, library, presets, favorites and search.
Click on a tab button to show a tab.
You will need a FAT32 formatted micro SD card.
Folders are navigated by clicking.
Single files can be added by clicking on the file or added and started with the play button.
Folders can be scanned and all found items added by clicking the play button.
This will add all files in a folder and start playing the first added item if nothing is playing.
Internet radio stations found through the search interface can be saved as favorites.
Favorites are stored on the SD card in the /.favorites folder.
Saved favorites can be inspected by visiting http://player-ip/favorites in a browser.
The generated files are formatted so they can easily be copied into src/presets.hpp if you want to make them permanent presets.
You can search for radio stations on radio-browser.info with the search bar.
Search results are displayed in the search tab.
The Info button at the bottom of the page toggles the Now Playing overlay.
The overlay shows the currently playing station or track and playback progress.
After 30 seconds no activity the overlay is show automatically.
When an Internet radio station originating from the search results is playing, a Save as Favorite button becomes available, allowing the station to be stored on the SD.
These libraries are used internally by the player:
- HTTP traffic and WebSocket UI messaging are handled by PsychicHttp webserver library - MIT
- Audio playback is handled by ESP32_VS1053_Stream library - MIT
- Low level codec access is handled by ESP_VS1053_Library - GPL-3.0
- The OLED is handled by Adafruit SSD1306 library - BSD
All frontend resources are compiled into the player UI:
- Vanilla HTML/CSS/JavaScript is used for the interface and application logic
- SVG icons from Google Fonts are inlined into the generated HTML during build - Apache 2.0
- Reconnecting WebSocket is included (minified) in the UI - MIT
- No frameworks, no runtime dependencies, no tracked downloads
- Hardware is feature complete, tested and stable
- No enclosure yet
Current focus:
- Designing a 3D printed hardware enclosure

