We have moved to a new Sailfish OS Forum. Please start new discussions there.
15

WIP Stream to multiple devices with Snapcast

asked 2017-12-06 17:17:40 +0200

this post is marked as community wiki

This post is a wiki. Anyone with karma >75 is welcome to improve it.

updated 2018-02-08 11:59:49 +0200

peperjohnny gravatar image

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. Sink Menu

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.

streams

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. snapcast app

By pressing on the settings icon you can chose which clients should belong to which stream. image description

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!

edit retag flag offensive close delete

Comments

great project! thanks for sharing!

h.berd ( 2017-12-07 12:45:45 +0200 )edit

I 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 )edit

Yes, 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 )edit
1

We'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 )edit

I 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

2 Answers

Sort by » oldest newest most voted
4

answered 2018-01-18 14:01:28 +0200

michfu gravatar image

updated 2018-02-07 20:59:36 +0200

Snapcast is ready for testing now:

https://build.merproject.org/package/show/home:fooxl:sailfish/snapcast

Installation

Become root

$ devel-su

Add the repository On an arm Device:

# ssu ar fooxl_merproject http://repo.merproject.org/obs/home:/fooxl:/sailfish/sailfish_latest_armv7hl/

Emulator/i486 Device:

# ssu ar fooxl_merproject http://repo.merproject.org/obs/home:/fooxl:/sailfish/sailfish_latest_i486/

Refresh the repository

# pkcon refresh fooxl_merproject

Install snapcast and avahi (TODO: Dependency)

# pkcon install snapcast avahi

Config

/etc/default/snapserver:

USER_OPTS="--user snapserver:inet"
SNAPSERVER_OPTS="-s pipe:///tmp/snapfifo?name=FIFO&mode=read&sampleformat=44100:16:2"

/etc/pulse/snapcast.pa:

load-module module-pipe-sink file=/tmp/snapfifo sink_name=sink.snapserver sink_properties=device.description="Snapserver_FIFO"

Put this somewhere in /etc/pulse/arm_qualcomm_msm_8909_l500d_flattened_device_tree_000b.pa (I put it before set-default-sink):

.ifexists /etc/pulse/snapcast.pa
.include /etc/pulse/snapcast.pa
.endif

/etc/pulse/xpolicy.conf.d/snapclient.conf

[stream]
property = application.process.binary@equals:"snapclient"
group = player

[group]
name   = snapserver
flags  = set_sink
sink   = sink.snapserver
source = sink.null.monitor

[stream]
property = application.name@equals:"harbour-unplayer"
group = snapserver`

I used Unplayer from openrepos for testing. If you want the default player streaming to snapserver replace harbour-unplayer with jolla-mediaplayer.

Restart the pulseaudio server:

$ systemctl --user restart pulseaudio

Running the Server

Still as root:

# systemctl start snapserver

(This should also start avahi-daemon as dependency.)

Running the client

If snapserver is not already running on this device: As root:

# systemctl start avahi-daemon

As user nemo:

$ systemctl --user start snapclient

Now it should be going bling-bling-bling-...... on your phone.


EDIT 2018-02-07: It's possible to route the ouput of a chosen player to snapserver now. See the config-section how to do this. You need to edit some files and restart pulseaudio.

edit flag offensive delete publish link more

Comments

Snapserver if crashing on Jolla C currently:

Failed to create server: No suitable network protocol available

I will test a bit more this weekend and try to debug it.

peperjohnny ( 2018-01-20 18:23:13 +0200 )edit

I've been tinkering a bit more but snapserver doesn't start yet. I get the following everytime it starts. To simplify I took your config.

`Sailfish systemd[1]: Starting Snapcast server...

Sailfish snapserver[19562]: Settings file: "/var/lib/snapserver/server.json"

Sailfish snapserver[19562]: file:///usr/share/sounds/jolla-ambient/stereo/positive_confirmation.wav?name=File

Sailfish snapserver[19562]: 2018-01-21 12-57-25 [Notice] Settings file: "/var/lib/snapserver/server.json"

Sailfish snapserver[19563]: daemon started

Sailfish systemd[1]: Started Snapcast server.

Sailfish snapserver[19563]: StreamServer::start: open: Permission denied

Sailfish snapserver[19563]: Exception: open: Permission denied

Sailfish snapserver[19563]: daemon terminated.

Sailfish systemd[1]: snapserver.service: Main process exited, code=exited, status=1/FAILURE

Sailfish systemd[1]: snapserver.service: Unit entered failed state.

Sailfish systemd[1]: snapserver.service: Failed with result 'exit-code'.

Sailfish systemd[1]: snapserver.service: Service hold-off time over, scheduling restart.

Sailfish systemd[1]: snapserver.service: Start request repeated too quickly.

Sailfish systemd[1]: snapserver.service: Unit entered failed state.

Sailfish systemd[1]: snapserver.service: Failed with result 'start-limit'.`

I didn't find anything helpful on the googles. Do you think I need to open a bug report?

peperjohnny ( 2018-01-21 14:03:20 +0200 )edit

Does snapserver work when you start it from CLI as root?

I guess it's something similar with avahi not having the proper permissions. I have no idea how to find this out. Tried it on the Sailfish OS mailinglist, but the tips didn't help.

michfu ( 2018-01-21 23:47:29 +0200 )edit

I have to try it on the phone itself, I used SSH before, maybe it makes a difference, although I don't expect it.

peperjohnny ( 2018-01-22 09:21:51 +0200 )edit
1

I got sound now!! :) See edit in aboce answer.

michfu ( 2018-01-26 18:57:03 +0200 )edit
2

answered 2017-12-08 13:21:37 +0200

michfu gravatar image

updated 2017-12-08 13:53:13 +0200

My theoretical setup would be:

  • (multiple) RasPI(s) as audio bridge from network to HIFI-System (snapclients)
  • Sailfish device as player (snapserver)

RasPI:

  • Install Snapcast
  • setup the client (there should be guides around for this)

Sailfish Device

  • Install Snapcast (package has to be created)

    either

  • configure a pulseaudio FIFO sink which becomes the source for snapserver on this device

  • tell your favourite player to use pulseaudio FIFO sink

    or

  • tell your favourite player to use FIFO sink directly

  • configure snapserver

edit flag offensive delete publish link more

Comments

1

Yup, I will try to build snapserver on sailfish this weekend, so that at least some of those things are done.

peperjohnny ( 2017-12-08 14:53:58 +0200 )edit

maybe an opensuse rpm and spec-file is a good starting point for this.

michfu ( 2017-12-08 17:20:29 +0200 )edit

I started building snapcast here:

https://build.merproject.org/package/show/home:fooxl:sailfish/snapcast

...but didn't get too far. Next step would be building avahi.

michfu ( 2018-01-10 16:10:07 +0200 )edit

Thanks for this!

Maybe you could use this as a starter.

peperjohnny ( 2018-01-12 12:50:20 +0200 )edit
1

That's what I did. :) ...but I'm not experienced in packaging things for Mer, opensuse or other rpm-based distros.

I also started an issue here: https://github.com/badaix/snapcast/issues/339 ...but there's not much reaction.

michfu ( 2018-01-12 13:01:10 +0200 )edit
Login/Signup to Answer

Question tools

Follow
8 followers

Stats

Asked: 2017-12-06 17:17:40 +0200

Seen: 2,763 times

Last updated: Feb 08 '18