One music collection, playing everywhere.
A music player that offers diverse navigation options through your music library and allows you to make choices about when to indulge in your favorite tunes. Whether you prefer the intimate experience on the device you're using for navigation or desire to immerse your space in a harmonious ambiance, the player seamlessly extends its capabilities to play music across multiple devices on the local network.
This schematic looks a bit busy, so let me attempt to explain:
- The UI is all the user will see. It allows the user to:
- search for music,
- playing music,
- switch between streaming music your phone (for example) and the multi-room streamer and
- control the volume on the client stream, the individual room clients of all room clients simultaneously.
- The UI talks to the Controller to:
- query the music collection,
- retrieve artist art (not part of MPD) via Discogs (discogs account is required)
- control playback,
- switch between client and multi-room output and
- control volume.
- The Client streamer can be used to receive playback from the MPD server on the client you are using the app on.
- The Multi-room streamer is where all multi-room clients receive their music stream from and can be used to control volume on the Room receivers.
- The Music Library Player is where the music collection resides who's playback is streamed to the Client streamer and/or the Multi-room streamer.
This section shows which languages and/or projects are used to implement the functional components.
- The UI is implemented needed to be accessible from any kind of device, so it came down to....
- The Client streamer is Icecast, which you can compare to a radio station that is tuned in to whatever you are playing.
- The Multi-room streamer solution Snapcast is used because it is awesome. Nuf said... Or is it? i've used this setup for over two years time. And I don't know if I told your before: it is just: AWESOME!
- The Music Library Player is MPD. Reliable, flexible and around since the dawn of civilization (2003).
- The Controller is where several back-end services are called so the UI developer doesn't need to worry about handling each of the component's quirks and hopefully get some kind of unifief interface. Since the author is using Python, FastAPI seemed a viable solution.
The total stack can be deployed by using Docker Compose and the docker-compose.yml file found in the repo's root directory. Before firing up the docker compose you need to:
- Create stack specific directories that need to be made up front which should be readable and writable by all containers, you can use/adjust and execute the file
init.sh
to create them. - change the
DIR_
variables in the.env
file to reflect your system. TheDIR_MUSIC
variable should point to your music collection.
After firing up docker compose, you have a stack which consists of the following components:
- MPD is a server side music player which also allows querying it's music library.
- ympd is a temporary MPD web client, included here to quickly review the stack's functionality. Once the stack is deployed you can find it at http://localhost:8080
- Icecast is used to stream music to the client. You can listen to the playback stream at http://localhost:8000/mpd
- Snapcast server is used to stream the music over the LAN to be received by all subscribed clients using Snapcast's client. Access the volume of all clients at http://localhost:1780/.
- Controller - Start of a self built FastAPI interface to MPD. Visiting http://localhost:5000/ gets you to the meat of how to communicate with it from your UI. If you are developing your UI you do all API requests to
localhost
, if you put it in production change the host tocontroller
.
How each components is created can be found within it's own subdirectory:
.
├── controller 'Developing playback commands, states and library querying'
├── icecast 'Stream music to client'
├── mpd 'The music library player'
├── snapserver 'Snapcast server that serves audio for multi-room purposes'
├── ui 'Developing UI'
└── ympd 'Contains a temporary UI that will de replaced by the developing ui'