← Projects
electronics intermediate Aug 22, 2026 ◑ 6 views ◯ 5 min read

Build an ESP32 Internet Radio Streamer: I2S DAC, WiFi Station Presets, and Rotary Encoder Control

Build time: 5-8 hours
Tools needed: Soldering iron, multimeter, small Phillips screwdriver, 3D printer for the enclosure, USB cable for flashing
Parts List
esp32internet radioi2swifi streamingmax98357arotary encoderaudio project

An internet radio streamer is a genuinely satisfying weekend ESP32 build: point it at a handful of streaming station URLs, and you get a dedicated little appliance that plays them over a real speaker with a knob to change stations and volume, no phone or app required. This build uses an ESP32 to decode and stream MP3/AAC internet radio stations over WiFi, output clean audio through an I2S DAC, and control station selection and volume with a rotary encoder and a small display.

This is a different kind of ESP32 audio project from playing local files or recording — it's a real-time network streaming and decoding pipeline, which puts more load on the chip's WiFi stack and available RAM than a typical sensor or automation project, so board and library choice matter more here than usual.

How It Works

The ESP32 connects to WiFi, opens an HTTP(S) connection to an internet radio stream URL (most stations serve plain MP3 or AAC over HTTP, sometimes via a playlist file like .pls or .m3u that needs to be resolved to the actual stream URL first), and feeds the incoming compressed audio data into a decoder library running on the chip. The decoded PCM audio is then pushed out over I2S to a DAC module, which converts it to an analog line-level or amplified signal for a speaker. A rotary encoder with a push button handles station cycling (turn) and play/pause or menu select (press), while a small OLED or TFT display shows the current station name and a simple menu.

Wiring

ComponentESP32 Connection I2S DAC (MAX98357A for amplified output, or PCM5102 for line-level)I2S pins — BCLK, LRCLK/WS, DOUT to the DAC's DIN, plus 3.3V/5V and GND per the DAC's requirements Rotary encoder with push buttonTwo GPIO pins for the quadrature encoder signals, one GPIO for the push button, with pull-ups enabled OLED display (SSD1306, I2C)I2C SDA/SCL pins, 3.3V, GND Speaker (if using an amplified DAC like the MAX98357A)Direct to the DAC's speaker output terminals

Software Setup

  1. Set up the ESP32 in the Arduino IDE or PlatformIO, and install an audio streaming library that supports I2S output and MP3/AAC decoding — the ESP32-audioI2S library (and similar community libraries built around it) is a common and well-documented starting point specifically built for this internet-radio-streaming use case.
  2. Write the WiFi connection logic first and confirm a stable connection before adding streaming — a flaky WiFi connection is the most common source of stuttering audio, and it's much easier to debug connectivity issues in isolation.
  3. Build a small array or config file of station presets — station name paired with stream URL — and write the logic to resolve playlist files (.pls/.m3u) to their actual underlying stream URL if a station serves one of those instead of a direct audio stream.
  4. Wire up the streaming call: open the HTTP connection to the current station's URL, and feed the response body into the audio library's streaming decode-and-play function, which handles buffering, decoding, and pushing samples out over I2S internally.
  5. Add the rotary encoder handling: turning changes the station index and triggers a reconnect to the new stream URL, tearing down the old HTTP connection cleanly before opening the new one; the push button can toggle play/pause or step into a simple settings/volume mode.
  6. Add the OLED display logic showing the current station name (and optionally, if the stream provides ICY metadata, the current track/show info) so you always know what's playing without needing a phone nearby.
  7. Handle disconnects and stream errors gracefully — internet radio streams do occasionally drop or hiccup, and the firmware should automatically attempt a reconnect rather than locking up or requiring a power cycle.

Buffering and Audio Quality Notes

Enclosure

A simple 3D-printed enclosure with a speaker grille, a cutout for the OLED display, and a knob for the rotary encoder turns this from a breadboard project into something that looks at home on a kitchen counter or workbench. Leave ventilation near the amplifier DAC if you're driving a speaker directly, since Class D amp chips like the one on the MAX98357A do generate some heat under sustained volume.

Troubleshooting

SymptomLikely Cause Audio stutters or drops out regularlyWeak WiFi signal, buffer too small, or too many other tasks competing for CPU time — check signal strength and try increasing buffer size first No audio at allI2S wiring mismatch (BCLK/WS/DOUT swapped), or the DAC not receiving power — verify with a multimeter before assuming it's a software issue Station won't play, others doThat station serves a .pls/.m3u playlist file rather than a direct stream, and the resolver logic needs to parse it, or the station requires HTTPS that the library isn't configured to trust Board resets/crashes when switching stations rapidlyOld HTTP connection and audio buffers not being torn down cleanly before the new one starts — add proper cleanup in the station-change handler

Once it's working, this is one of those ESP32 builds that quietly earns a permanent spot in the kitchen or workshop — a dedicated little radio with your own curated station presets, built entirely from parts that would otherwise be sitting in the project bin.