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.
SD operations are mostly handled async to keep the UI responsive.
File browser requests are cached if it takes over 300 ms to read and process a folder.
File browser cache speedup example:
- The handling of 100+ SD card items takes about ~2000ms on the first request
- Because the operation took more than 300 ms to complete the response is cached
- Once cached the same folder takes only 3-8 ms to complete
Up to a 100 requests can be cached this way.
If the cache reaches max capacity the smallest cached item will be evicted and replaced.
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.
The following steps assume you already have a working VSCode/PlatformIO setup.
-
Clone this repository to your computer in a terminal:
git clone --branch v1.0.0 https://github.com/CelliesProjects/osap
Or click here to download the current release.
Download and then unzip this file. -
Open VSCode and select from the top menu
File->Open folderthen select the folder where you cloned or unzipped the repository to.
This is the project folder. -
Provide your wifi secrets by creating the file
src/secrets.hppin the project folder.
See the Building section below on how to format this file. -
Open PlatformIO and select
Project tasks->develop->Upload and monitor.
VSCode/PlatformIO will download and install all the assets that are needed to build the player firmware.
This might take a while depending on your internet speed and computer capabilities.
If all assets are installed, PlatformIO will start compiling and flash your player.
Note: The first time you build this project, a lot of files will be downloaded and then compiled which might take a long time.
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

