WIP Stream to multiple devices with Snapcast
asked 2017-12-06 17:17:40 +0200
This post is a wiki. Anyone with karma >75 is welcome to improve it.
Disclaimer: This is a work in progress and is not polished at all, but may get better in the future. I haven't created any of the software used, I just made them do my bidding. Things may break and you may have to reboot your phone to ensure that it works normal again.
Baiscally I wanted to have a cheap and mostly open source Sonos solution at home. Fortunately some great people already made some contributions and Jolla uses pulseaudio, which makes at least some things easier to achieve.
The following was used to make this work.
- Jolla C and Xperia X with Sailfish X
- Raspberry PI 3 with Raspbian lite
- PulseTunnel from Jolla Store
- Snapcast
First of I installed Raspbian on my Raspberry Pi 3. I used the lite image but I guess it will work, with the full on as well. Once your installed and ready, start up the system and install some further packages, which are needed for this endeavor.
sudo apt-get install pulseaudio
To make pulseaudio autostart put the following in /etc/rc.local before the exit 0 command.
su -c 'pulseaudio --start' - pi
Next get the packages for Snapcast server. You can run Snapcast server and client on the same machine, if you want to.
wget https://github.com/badaix/snapcast/releases/download/v0.12.0/snapserver_0.12.0_amd64.deb
Install it and dependencies if needed.
sudo dpkg -i snapserver_0.12.0_amd64.deb
sudo apt-get install -f
Edit /etc/default/snapserver with the following.
SNAPSERVER_OPTS="-d -s pipe:///tmp/snapfifo?name=Radio&mode=read"
You can change the name Radio to the one you want to use.
Add the following to your /etc/pulse/default.pa . The first line is that you can connect without any authentication. The following lines create a Snapcast sink to which we will stream later, which takes input from PulseAudio and forwards it to Snapserver.
load-module module-native-protocol-tcp auth-anonymous=1
load-module module-pipe-sink file=/tmp/snapfifo sink_name=Snapcast
update-sink-proplist Snapcast device.description=Snapcast
Now we need Snapcast to start on boot so that you can use it directly.
sudo systemctl enable snapserver
And if you're running the client on the same machine.
sudo systemctl enable snapclient
You can either start the all the needed services manually or reboot the PI and let them start automatically. In case you don't want to reboot.
pulseaudio --start
sudo systemctl start snapserver
sudo systemctl start snapclient
Now let's go to the Sailfish side of things.
First of all install PulseTunnel from Jolla Store.
When you startup the app and have no sound playing you shouldn't be able to see streams. Use the Pulley menu and go into sinks. Use the Pulley Menu once again to add a tunnel. Type in the IP of your machine and if you have used Snapcast as the sink name, you can use it here as well.
If you used a different name for your sink and have forgotten it, either look it up with
pacmd list-sink
Or take one more look at your /etc/pulse/default.pa
Now start a Song in media player or anything else that will give out sound. You should see something similar to this.
Type on the stream and you can chose on which sink to play. Chose your PI as the sink and music should come out of the boxes.
If you have an HDMI cable connected to your PI, it will try to playback via HDMI most probably to set it to AUX use the following command.
amixer cset numid=3 1
If you want to revert this simply change the 1 to 0 which is automatic.
To have more control to which of the clients you want to stream, download the latest apk on your Jolla and install it by tapping on it. Once started you may see the following.
By pressing on the settings icon you can chose which clients should belong to which stream.
Here is the important thing. After every played song a new sink will be created and it won't be moved to your PI, which you can circumvent by setting the PI sink as your default one including unloading the enforcement module, which will forward ALL sounds including calls to the PI until you set it back MANUALLY to the primary sink. If you can't get it back to the default sink, restart your phone and default settings will be restored.
There are things I can work on myself, but honestly I'm no software engineer and got the most done by trial and error. However, I will try to improve some things myself, as far as I am able.
Things that I'd love to be improved:
- Get avahi on board to achieve discover of server on clients (solved: see answer below)
- Set only mediaplayer/app of your choosing to the PI as the default sink and leave the rest on the phone (solved by editing config files, see answer )
- Maybe create an image of Raspbian which has all the defaults set, so that setting up a client would be a bit easier. (solved: There is SnapOS or Volumio which does even more things)
- It would be nice to have the control app as a native app.
- Ideally the PulseTunnel app would be available via Notification quickbuttons similar to Airplay for example.
- The streaming needs tuning, as sometimes it stutters.
Last but not least thanks to all the great people who wrote the software in use. You rock!
great project! thanks for sharing!
h.berd ( 2017-12-07 12:45:45 +0200 )editI also thought about using pulseaudio for networkstreaming, but it needs a lot of bandwith. Wouldn't it be better to use snapcastserver directly on the Sailfish Device? I want to try to build a mutliroom audio setup too, but I don't know, when I have time for this. Then I will also take a look at starting a native app.
michfu ( 2017-12-07 15:31:31 +0200 )editYes, it probably would be better. Maybe it could be integrated into media player or one of the other media player apps.
peperjohnny ( 2017-12-07 17:07:43 +0200 )editWe'll see. I'm currently doing a rewrite of daedalus and SMPC https://github.com/fuchsmich/smpc/tree/rewrite Maybe I can integrate something there.
michfu ( 2017-12-07 17:11:39 +0200 )editI think I misunderstood how the whole snapserver thing is supposed to work. Maybe a better solution would be to have the snapserver run on your jolla and then broadcasting to the clients. I'll try this and let's see if this works any better than the previous solution.
peperjohnny ( 2017-12-07 17:39:35 +0200 )edit