The player¶
The application in app/ turns a board with a display and an I2S DAC into
a Spotify Connect speaker with its own touch UI.
ESP32-S3¶
The supported board is the VIEWE UEDX32480035E-WB-A (ESP32-S3, 8 MB PSRAM, 480x320 touch display). It has no DAC on board; see Hardware for the wiring.
west build -p -b uedx32480035e_wb_a/esp32s3/procpu zspot/app
west flash
Using it¶
Control |
Action |
|---|---|
Wi-Fi symbol, held 1 second |
Wi-Fi settings: pick a network and type the password. Stored networks are listed first; hold one for 1 second to forget it. The symbol is red while the network or the Spotify connection is down. |
Search bar |
Search for a song or artist and play a hit |
List button |
Your Library: Liked Songs and playlists |
Microphone button |
Switch between cover and lyrics |
Repeat button |
Cycle through off, repeat the queue and repeat the track (shown with a “1”). The Spotify app shows either repeat as on, and its repeat toggle turns the button on and off. Skipping ahead ends repeating the track, as in the app. |
Wi-Fi credentials are stored on the device. Once it is connected, select it in the Spotify app; the layout adapts to the resolution and orientation of the display.
The screen turns off after CONFIG_ZSPOT_SCREEN_TIMEOUT_SECONDS (60 by
default, 0 to keep it on) without a touch, together with the backlight when
the board has the devicetree alias zspot-backlight. The next touch wakes
it and does nothing else; playback is not affected.
Lyrics come from LRCLIB and need no account. Lists show the first 30 entries, and the fonts cover Latin text only.
A battery symbol appears next to the Wi-Fi symbol when the board has a fuel
gauge behind the devicetree alias fuel-gauge0.
Search and Your Library¶
These use the Spotify Web API and need a one-time setup:
Create an application at https://developer.spotify.com/dashboard with the Web API enabled and the redirect URI
http://127.0.0.1:8888/callback.Export its credentials as
ZSPOT_WEB_CLIENT_IDandZSPOT_WEB_CLIENT_SECRET, e.g. from a private file that~/.bashrcsources.Run
scripts/spotify_authorize.py --save <that file>and approve the access in the browser; it addsZSPOT_WEB_REFRESH_TOKEN.Rebuild with
west build -pfrom a shell that has the three variables.
Warning
The values give access to the account: keep them out of version control and do not share the build directory.
Search covers songs only; podcasts and episodes are not searched.
native_sim¶
The display is an SDL window with the mouse as the touch screen. The audio
goes through Zephyr’s native_sim I2S driver to the host’s default ALSA device
(CONFIG_I2S_NATIVE_SIM_ALSA). It needs the SDL2 and ALSA development
packages (SDL2-devel and alsa-lib-devel on Fedora, libsdl2-dev and
libasound2-dev on Debian and Ubuntu). Another ALSA device or a file is
picked with --i2s_tx_tx=<path>, e.g. --i2s_tx_tx=alsa:hw:0,0 or
--i2s_tx_tx=out.pcm for raw 16-bit little-endian stereo PCM at 44.1 kHz.
Create the TAP interface once per boot and give it internet access:
sudo tools/net-tools/net-setup.sh start --config nat.conf
Then build and run:
west build -p -b native_sim/native/64 zspot/app
./build/zephyr/zephyr.exe
The Spotify app finds devices through mDNS on its own network. To make the simulator visible there:
scripts/native_sim_lan_bridge.py 8080 192.0.2.1 &
avahi-publish-service zspot _spotify-connect._tcp 8080 \
VERSION=1.0 CPath=/spotify_info Stack=SP &
Checking the audio without a DAC¶
Build with -DCONFIG_ZSPOT_PCM_TAP=y and the player serves a copy of its
audio on TCP port 5000:
nc zspot.local 5000 | aplay -f S16_LE -r 44100 -c 2 -B 1000000 -R 1000000
When the copy sounds right but the DAC does not, the fault is in the I2S configuration, the wiring or the DAC.
Application options¶
Kconfig |
Purpose |
|---|---|
|
Stored credentials; skips the zeroconf hand-over |
|
Idle time before the screen turns off (0: never) |
|
Interval between two fuel gauge readings |
|
Copy of the audio over TCP |
|
Web API access for search and Your Library |
The full list is in app/Kconfig.