diff --git a/static/css/home.css b/static/css/home.css index 7389823..07f56f3 100644 --- a/static/css/home.css +++ b/static/css/home.css @@ -22,8 +22,9 @@ main { } .article:hover { - box-shadow: 0 1px 4px 2px #acacac; + box-shadow: 0 1px 4px 3px #989898; opacity: 1; + border-radius: .5em; } @media screen and (min-width: 767px) { diff --git a/static/img/mopidy-iris-1.jpeg b/static/img/mopidy-iris-1.jpeg new file mode 100644 index 0000000..ecb02c0 Binary files /dev/null and b/static/img/mopidy-iris-1.jpeg differ diff --git a/static/img/mpd-1.png b/static/img/mpd-1.png new file mode 100644 index 0000000..0f4d05f Binary files /dev/null and b/static/img/mpd-1.png differ diff --git a/static/img/ncmpcpp-1.png b/static/img/ncmpcpp-1.png new file mode 100644 index 0000000..151ec39 Binary files /dev/null and b/static/img/ncmpcpp-1.png differ diff --git a/static/img/ncmpcpp-2.png b/static/img/ncmpcpp-2.png new file mode 100644 index 0000000..dbd482a Binary files /dev/null and b/static/img/ncmpcpp-2.png differ diff --git a/static/img/ncmpcpp-3.png b/static/img/ncmpcpp-3.png new file mode 100644 index 0000000..a3e6d8d Binary files /dev/null and b/static/img/ncmpcpp-3.png differ diff --git a/static/img/snapcast-1.png b/static/img/snapcast-1.png new file mode 100644 index 0000000..efb3b79 Binary files /dev/null and b/static/img/snapcast-1.png differ diff --git a/static/img/snapcast-2.jpeg b/static/img/snapcast-2.jpeg new file mode 100644 index 0000000..4510247 Binary files /dev/null and b/static/img/snapcast-2.jpeg differ diff --git a/static/pages/Build-your-open-source-multi-room-and-multi-provider-sound-server-with-Platypush-Mopidy-and-Snapcast.md b/static/pages/Build-your-open-source-multi-room-and-multi-provider-sound-server-with-Platypush-Mopidy-and-Snapcast.md new file mode 100644 index 0000000..0244edf --- /dev/null +++ b/static/pages/Build-your-open-source-multi-room-and-multi-provider-sound-server-with-Platypush-Mopidy-and-Snapcast.md @@ -0,0 +1,316 @@ +[//]: # (title: Build your multi-room and multi-provider sound server with Platypush, Mopidy and Snapcast) +[//]: # (description: How to leverage Platypush and other open-source projects to build an extensible and versatile music server.) +[//]: # (image: /img/mpd-1.png) +[//]: # (published: 2019-10-22) + +Today’s abundance of music streaming services has created lots of opportunities to listen to whichever music you like +wherever you like, but there’s a huge fragmentation problem that hasn’t been tackled seriously by the music tech +industry yet. + +Spotify allows you to find and discover a lot of tunes, but not all the music is there. + +You may want to integrate your collection of mp3s into your Spotify collection, but that is simply not an option. + +You may have favourite tracks that are only available on SoundCloud or albums that aren’t available on Spotify, but +you’ve purchased in the past on Google Music or iTunes, but there’s no way to have them all in one place: each of these +solution comes with its separate app. + +You may want to integrate your favourite online radios or podcasts into your music app, but that’s, again, not an option +— TuneIn, Podcast Addict or Google Podcasts are distinct apps. + +You may want to easily stream your playlists to any speaker or pair of headphones you own, but that’s not as easy as it +sounds. You may have to replace your existing speakers with expensive solutions (like Sonos or Bose) to enjoy a proper +multi-room setup. Apps like Spotify come with their solutions (e.g. Spotify Connect), but only a limited number of +devices is supported and, again, it works as a solution only as long as you stream Spotify content from the Spotify app. + +There have been commercial solutions that have tried to tackle this fragmentation problem and provide you with the +possibility to stream music from any app to any speaker without having to replace your audio system, but the situation +isn’t that bright after Google +has [discontinued its Chromecast Audio support](https://www.theverge.com/2019/1/11/18178751/google-chromecast-audio-discontinued-sale), +and AirPlay works relatively well only as long as you’re in an Apple ecosystem. + +As of today the problem “how do I play whichever piece of music I like, from whichever service I like, on whichever +device I like, all in one interface, without having to install 10 different apps” is still largely unsolved if you rely +on commercial solutions. + +Luckily, we’ve got plenty of open source software around that comes to rescue. It requires a bit more work than just +downloading an app and logging in, but the rewards are priceless. + +## One music server to rule them all + +[Mopidy](https://mopidy.com/) is one of the best open source solutions around when it comes to integrating multiple +music services under one single interface. It’s entirely written in Python, it’s (almost) 100% compatible +with [MPD](https://www.musicpd.org/doc/html/protocol.html), a music protocol that has been around since 2003 and comes +with lots of compatible clients (command-line, web-based, mobile apps etc.), and there are countless plugins that let +Mopidy integrate with any kind of music service around. + +It’s relatively easy to install mopidy on a RaspberryPi and turn it into a powerful music centre. + +- Add the mopidy repository to your apt lists and install the base package: + +```shell +wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add - + +# Run the following if you're running Raspbian/Debian Buster +sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/buster.list + +# Run the following command if you're running Raspbian/Debian Stretch +sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/stretch.list + +# Update the repositories and install mopidy +sudo apt-get update +sudo apt-get install mopidy mopidy-mpd +``` + +- Install any additional extension for the music services you like: + +```shell +# Spotify support +sudo apt-get install mopidy-spotify + +# Local files support +sudo apt-get install mopidy-local + +# Dirble support +sudo apt-get install mopidy-dirble + +# Podcast support +sudo apt-get install mopidy-podcast mopidy-podcast-gpodder mopidy-podcast-itunes + +# Last.FM scrobbling support +sudo apt-get install mopidy-scrobbler + +# Soma.FM support +sudo apt-get install mopidy-somafm + +# Soundcloud support +sudo apt-get install mopidy-soundcloud + +# TuneIn support +sudo apt-get install mopidy-tunein + +# YouTube support +sudo apt-get install mopidy-youtube +``` + +And there are even more extensions available for Mopidy - you may want to take a look on +[their website](https://mopidy.com/ext/) to get an overview of the compatible services. + +Head to the pages of those extensions to find out whether they need some extra dependencies or extra configuration to be +added to your `~/.config/mopidy/mopidy.conf` file. + +You may also want to make sure that the HTTP module is enabled in your mopidy configuration, since most of the web +frontends (including Platypush) rely on it to interact with mopidy over websockets: + +```yaml +[http] +enabled = true +hostname = 0.0.0.0 +port = 6680 +``` + +There is also a wide range of frontend clients available for Mopidy, from command-line MPD clients to full-blown web +clients that do a very good job replicating the UI of some of the most popular music apps around. Let's have a quick +overview of my favourite solutions to interact with Mopidy: + +- `netcat`/`telnet`. Mopidy is compatible with the MPD protocol, and once started it will listen by default on port 6600 + for MPD commands. It’s relatively straightforward to explore your library or control the playback even without + installing another client (although it’s probably not the most user-friendly way, but very good if you want to make + some scripts): + +```shell +$ echo status | nc localhost 6600 +OK MPD 0.19.0 +volume: 100 +repeat: 0 +random: 1 +single: 0 +consume: 0 +playlist: 3 +playlistlength: 1489 +xfade: 0 +state: stop +song: 513 +songid: 560 +nextsong: 173 +nextsongid: 220 +OK + +$ echo currentsong | nc localhost 6600 +OK MPD 0.19.0 +file: spotify:track:218UgZapIcNRP9f38C5cMp +Time: 365 +Artist: 3rd Force +Album: Vital Force +Title: Echoes Of A Dream +Date: 1997 +Track: 6 +Pos: 513 +Id: 560 +AlbumArtist: 3rd Force +X-AlbumUri: spotify:album:3mSCVZabNB0rUmpYgPkDuV +OK + +$ echo play | nc localhost 6600 +OK MPD 0.19.0 +OK + +$ echo stop | nc localhost 6600 +OK MPD 0.19.0 +OK +``` + +- `mpc` is a tiny command-line utility that makes it a bit easier to interact with MPD/mopidy instances for scripting + purposes without handling low-level protocol messages: + +```shell +sudo apt-get install mpc +mpc help # To see available commands +mpc play # Play the music +``` + +- `ncmpcpp` is a ncurses-based terminal client that I've been using for more than a decade, and it's probably one of + the lightest yet most versatile music clients I've seen around - and definitely my favourite: + +```shell +sudo apt-get install ncmpcpp +``` + +![ncmpcpp screenshot 1](../img/ncmpcpp-1.png) +![ncmpcpp screenshot 2](../img/ncmpcpp-2.png) +![ncmpcpp screenshot 3](../img/ncmpcpp-3.png) + +- `mopidy-iris` is probably one of the most user-friendly, well-maintained and feature-rich Mopidy clients around, and + it's compatible with desktop, tablet and mobile and it comes with a UI that successfully mimics that of many popular + music apps: + +```shell +sudo apt-get install mopidy-iris +``` + +After installing it head to `http://your-raspberry:6680` and select Iris as the web interface. + +![iris interface](../img/mopidy-iris-1.jpeg) + +And you have many more compatible clients available (just check the list of extensions), from minimal, to feature-rich +(such as MusicBox), to a specific client for party mode optimized for multiple users! And, being compatible with MPD, +all the MPD clients out there should also work out of the box. And the list also includes a *Mopidy Mobile* app and +several MPD apps for Android and iOS. + +## Hook Mopidy to Platypush + +You can connect Platypush to Mopidy. That provides you with one more UI for interacting with your instance (embedded in +the Platypush web panel), and it opens a world of possibilities when it comes to automating music interactions. + +- Install Platypush with the HTTP and MPD dependencies: + +```shell +[sudo] pip install 'platypush[http,mpd]' +``` + +- Enable the MPD/mopidy plugin and backend in your platypush configuration file: + +```yaml +music.mpd: + host: localhost + port: 6600 + +backend.music.mopidy: + host: localhost +``` + +A `backend.music.mpd` is also provided, but if you use Mopidy instead of a bare MPD server then it's advised to use +`backend.music.mopidy` instead - the former checks for updates by polling the server at regular intervals, while the +Mopidy-specific backend listens for events continuously over the provided websocket interface. + +- Restart Platypush and head to `http://your-raspberry:8008`. You should see a new tab for Mopidy — yet another web + interface to interact with the server. + +![Platypush MPD interface](../img/mpd-1.png) + +Before proceeding on how to automate the interaction with your new music server, let's see how to turn Mopidy into a +full multi-room music server with Snapcast. + +## Multi-room setup + +The ability to synchronize music across multiple rooms and devices is a great feature of a modern smart home. However, +most of the commercial solutions available today (like Sonos or Bose) are expensive and require in most of the cases to +replace your speakers with theirs. Luckily it’s relatively easy to set up a multi-room experience with multiple +RaspberryPis, without having to change your speakers. Let’s see how. + +- Install Snapcast by following the instructions on their [Github page](https://github.com/badaix/snapcast) + +- Create an `/etc/default/snapserver` file on the machine(s) where you’re running your Mopidy instance(s) with the + following content: + +```yaml +USER_OPTS="--user snapserver:snapserver --stream=pipe:///tmp/snapfifo?name=mopidy&codec=pcm --codec=pcm" +SNAPSERVER_OPTS="" +``` + +In the example above we’ll use a PCM lossless codec for streaming the music, and we’ll be using `/tmp/snapfifo` as a +file queue where Mopidy will push its audio stream. + +- Start snapserver on your Mopidy machine(s) by simply running the executable, and optionally add it to your startup + configuration. + +- Configure the [audio] section of your mopidy.conf file to stream to the Snapcast FIFO (note: with this configuration + Mopidy will only stream to the new file and not to your speakers, you'll need to run `snapclient` to play the audio): + +```yaml +[audio] +mixer = software +mixer_volume = 100 +output = audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/tmp/snapfifo +``` + +The `audio.output` setting of Mopidy is actually a very flexible way of building GStreamer pipelines to redirect and +transform the audio however you like. In this example I'm transforming the audio to stereo WAV at 48 kHz, which may be +perfect if you're seeking for a true loseless audio experience, but may cause some glitches if your network isn't very +stable (we're basically passing uncompressed audio around). It's possible to encode and compress the stream by applying +e.g. an MP3 or OGG encoder to the pipeline, but this causes the GStreamer pipeline to become very unstable for some +reason (the bug has been opened for a couple of years and Mopidy developers are still scratching their head on why it +happens), so the loseless stream option may be the only one that works for now. + +- Create an `/etc/default/snapclient` file on all the machines that will be connecting to your Snapserver, included the + Mopidy machine itself if you want to directly play music from too (opposed to using it just as a music backend): + +```yaml +START_SNAPCLIENT=true +USER_OPTS="--user snapclient:audio" +``` + +- Start `snapclient` on the machines that will be connecting to your Mopidy instance. The command will + be `snapclient -h localhost` on the machine that runs mopidy itself and `snapclient -h remote-host-ip-or-name` on the + other machines. You can run as many `snapclient` instances on a host as the servers you want to connect it to. + +- Enable the Snapcast backend and plugin in the Platypush configuration of each of the machines that will be running the + client or the server: + +```yaml +backend.music.snapcast: + hosts: + - server1 + - server2 + - server3 + +music.snapcast: + host: default-server-ip-or-name +``` + +- Restart Platypush and head to the web panel on port 8008. You should see a new tab for Snapcast, identified by the + speaker icon. From here you can control which stream will be playing on which host, you can create streaming groups, + change the volume etc. + +![Platypush Snapcast interface](../img/snapcast-1.png) + +- You can also install an [Android app](https://play.google.com/store/apps/details?id=de.badaix.snapcast) to control + your multi-room setup, even though the app allows you to control one server at the time. The app however will allow + you to play audio streams also on your smartphone. + +![Snapcast app interface](../img/snapcast-2.jpeg) + +If you use Iris as a web interface to Mopidy you can now head to settings and enable the Snapcast plugin. A speaker icon +will appear in the bottom bar, and you’ll be able to control your music setup from there as well. + +Time to enjoy your low-cost but powerful multi-room music setup!