Now-playing is a Python application for the Raspberry Pi that listens for background music, identifies the song, and displays the song information on an e-ink display.
This project was born out of a personal need: I love listening to vinyl, but since it's analog, I could never see what track was playing. The same goes for filmsโI'd often reach for my phone to Shazam a song. Now, I just glance at my display.
![]() |
![]() |
- Detects music using a local YAMNet ML model
- When music is detected, identifies the song with ShazamIO
- Displays song title, artist, and album cover on an e-ink display
- Pressing Button A on the e-ink display adds the current song to a Spotify playlist with Spotipy
- When no music is detected for a while, the display switches to a screensaver mode that shows the weather
This project builds on and refactors several previous works (see LICENSE):
All credits for the original idea go to them. While they laid the groundwork, this version focuses on clean code, modularity, and extensibility.
- Simplified, readable logic with meaningful function names
- Clear separation of concerns with dedicated services (e.g.,
DisplayService
has all logic concerning the e-ink display) - Application state is handled via a centralized
StateManager
- Type hints added for better clarity and IDE support
- Configurations via YAML (no more messy INI files)
- Cleaned up setup script for smoother installation
- Singleton pattern for
Logging
andConfig
- Threaded button control for responsiveness
- Many more...
- Raspberry Pi Zero 2 W (or newer)
- MicroSD card
- Power supply
- Pimoroni Inky Impression e-ink display
- USB microphone (min. 16kHz sample rate)
- Optional: 3D printed case
- Flash Raspberry Pi OS Lite to your microSD card using Raspberry Pi Imager
- Enable Wi-Fi and SSH (to allow remote access as the OS is headless) in the setup wizard
- Sign up at OpenWeatherMap
- Generate your API key
- Safely store it
- Go to Google Maps โ Search your location โ Right-click โ Copy coordinates
- Go to Spotify Developer Dashboard
- Click 'Create App' and fill out the form:
- App name
- App description
- Redirect URI = http://localhost:8888/callback
- Check 'Web API'
- Check the 'Terms of Service'
- Click on 'Save'
- Safely store your Client ID and Client Secret
- Copy the Playlist ID of the playlist you want your songs to be added to
Since Raspberry Pi OS Lite is headless (no browser), you must authorize Spotify once from a computer:
- On your PC or Mac, clone this repo:
git clone https://github.com/maurocastermans/now-playing
cd now-playing
- Fill in your
SPOTIFY_CLIENT_ID
andSPOTIFY_CLIENT_SECRET
inspotify_auth_helper.py
- Run:
python3 spotify_auth_helper.py
- Follow the browser prompt and allow access to your Spotify account. This will generate a .cache file locally containing a Spotify access token.
wget https://raw.githubusercontent.com/maurocastermans/now-playing/main/setup.sh
chmod +x setup.sh
bash ./setup.sh
Afterwards, copy the .cache file to your Raspberry Pi project root. Spotipy will refresh the token automatically using the stored refresh tokenโno need to do this again unless you change accounts.
Should you encounter any issues, check Known Issues
- Enables SPI and I2C
- Updates the system and installs dependencies
- Sets up a Python virtual environment and installs Python packages
- Creates config, log, and resources directories
- Prompts for credentials, your e-ink display size and generates config.yaml
- Copies and configures a systemd service to autostart on boot
- Starts the now-playing service
display:
width: 600 # or 640 (4"), or 800 (7.3")
height: 448 # or 400 (4"), or 480 (7.3")
small_album_cover: true
small_album_cover_px: 250 # or 200 (4"), or 300 (7.3")
screensaver_image: "resources/default.jpg"
font_path: "resources/CircularStd-Bold.otf"
font_size_title: 45
font_size_subtitle: 35
offset_left_px: 20
offset_right_px: 20
offset_top_px: 0
offset_bottom_px: 20
offset_text_shadow_px: 4
weather:
openweathermap_api_key: "YOUR_API_KEY"
geo_coordinates: "LAT,LON"
spotify:
client_id: "YOUR_SPOTIFY_CLIENT_ID"
client_secret: "YOUR_SPOTIFY_CLIENT_SECRET"
playlist_id: "YOUR_SPOTIFY_PLAYLIST_ID"
log:
log_file_path: "log/now_playing.log"
To update your configuration after installation:
nano config/config.yaml
After editing, restart the service to apply changes:
sudo systemctl restart now-playing.service
- Check status:
sudo systemctl status now-playing.service
- Start/Stop:
sudo systemctl stop now-playing.service
sudo systemctl start now-playing.service
- Logs:
journalctl -u now-playing.service
journalctl -u now-playing.service --follow
journalctl -u now-playing.service --since today
journalctl -u now-playing.service -b
Now-playing runs in a Python virtual environment (using venv). If you want to run Python code manually:
sudo systemctl stop now-playing.service
source venv/bin/activate
python3 src/now_playing.py
To leave the virtual environment:
deactivate
Some USB microphones have very low default input gain, meaning they only pick up sound when your audio device is extremely close to the mic. This can cause issues with audio detection.
To boost your microphoneโs gain:
- Open the audio mixer:
alsamixer
- Select your USB microphone:
- Press F6 to open the sound card list
- Use the arrow keys to select your USB microphone device
- Adjust the input gain:
- Press F4 to switch to Capture controls
- Increase the gain using the โ arrow key until it reaches an appropriate level
- Save the gain settings (so they persist after reboot):
sudo alsactl store
If you see:
Woah there, some pins we need are in use!
Chip Select: (line 8, GPIO8) currently claimed by spi0 CS0
Just recently (16/08/2024), the GPIO Kernel Module in Raspberry PI OS changed
โก๏ธ Check https://github.com/pimoroni/inky?tab=readme-ov-file#chip-select-line-8-gpio8-currently-claimed-by-spi0-cs0 and follow the instructions
There are still three unused buttons on the e-ink display. These could be mapped to additional features.
The Pimoroni Inky display actually supports rendering HTML, opening up all sorts of design possibilities. This could make the interface:
- More customizable and visually rich
- Easier to tweak via CSS/HTML templates
- Support dynamic layouts or themes
If you have more ideas for new features or you'd like to get involved, feel free to open an issue or submit a PR!