Closed badaix closed 4 years ago
Awesome! I think this would be very useful for streaming pulseaudio from a different machine on the network.
I'd love to test that on my Raspberry 4 running Raspbian Buster. I hope it could solve frequent drop-out of music when I interact with the desktop (for instance browsing internet).
Could you please update the building instructions for Raspbian? (in particular, Boost provided with Raspbian Buster seems too old...)
I will do so tonight. You will just need header only boost libs, i.e. it's enough to download and unzip the latest boost and let make/cmake point to the directory. I think you can pass the boost path to cmake like this cmake -DBOOST_ROOT=<path to your unzipped boost root>
(no guarantee, I have to cross check on my dev machine tonight).
Interesting. I'm using Mopidy since I first found out about Snapcast. I did not experience audible looping issues... How are you testing for that? Our GStreamer setup is the same.
I had terrible issues with Mopidy and Gstreamer, changing songs or radio channels meant delays, glitches, looping feedbacks etc then I moved to Mpd and it works great with SC. However I am interested in this imporvement as well.
I'm currently using MPD as input for snapcast (connected via pipe) and now I started playing with Mopidy, which seems to be more actively developed and more feature rich. I've observed some strange audio loops during my Mopidy tests, using this setup GStreamer setup:
[audio] output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/tmp/snapfifo
I was wondering if there are GStreamer sinks that are more reliable and implemented a TCP stream that can be configured to act as client or as server, allowing the following setups:
Snapcast running in TCP server mode
snapcast.conf:
[stream] stream = tcp://127.0.0.1?name=mopidy_tcp
the general pattern is:
tcp://<IP of the listen interface>:<port>?name=<name>&mode=[client|server]
default forport
(if omitted) is 4953, default formode
isserver
mopidy.conf (running GStreamer in client mode)
[audio] output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpclientsink
Snapcast running in TCP client mode
snapcast.conf:
[stream] stream = tcp://127.0.0.1?name=mopidy_tcp&mode=client
in client mode the IP and port are the server's IP, port to connect to (default for port is again 4953)
mopidy.conf (running GStreamer in server mode)
[audio] output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpserversink
If you want to give it a try: it's available in the current develop branch, any feedback is appreciated! This would also solve #486 (well, at least it would work around it)
Has anyone tried this? I run several clients and a server on raspberry pi's and have some issues with mopidy that don't seem to exist when using librespot - appreciate your good work on this software.
I'm running with the latest dev commit, and the following configs:
stream = tcp://0.0.0.0:4953?name=Spotify_1
stream = tcp://0.0.0.0:4954?name=Spotify_2
stream = tcp://0.0.0.0:4955?name=Mopidy
Librespot is running on two separate docker containers and is forwarding FIFO to network via netcat:
nc ${TARGET_HOST} ${TARGET_PORT} </tmp/snapfifo &
librespot ... --backend pipe --device /tmp/snapfifo
and mopidy:
[audio]
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpclientsink host=snapcast port=4955
It seems to work well :) I'll do more stress testing this week.
Ooh this looks good, just been discussing th issues Gstreamer has with fifos with the mopidy devs and one of them pointed me at this. I need to give this a try.
One thing is slightly confusing me though, is the nomenclature around client mode/server mode. I'd assume snapserver would always need to be in 'server mode' and snapclient in 'client mode' - but I'm not sure if that makes sense - and then mopidy in... what mode?
OK I managed to get it to build natively on a RaspberryPi 3B+ and the good news is it's working!
For anybody interested in trying, here's what I did. I'm no expert at editing MakeFiles so I just blundered around making edits until it built, so here's the full list of what I changed.
Download the latest libboost and unzip it somewhere. This will give you a directory we'll call \<boost dir>
I only rebuilt the Snapcast server. So, in \<snapcast dir>/server:
Edit CMakeLists.txt and find the SERVER_INCLUDE section and change it to
set(SERVER_INCLUDE
${CMAKE_SOURCE_DIR}/server
${CMAKE_SOURCE_DIR}/common)
list(APPEND SERVER_INCLUDE "<boost dir>")
Then edit Makefile:
Find the long line beginning CXXFLAGS += and change it to
CXXFLAGS += $(ADD_CFLAGS) -std=c++14 -Wall -Wextra -Wpedantic -Wno-unused-function -DBOOST_ROOT=<boost dir> -DBOOST_ERROR_CODE_HEADER_ONLY -DHAS_FLAC -DHAS_OGG -DHAS_VORBIS -DHAS_VORBIS_ENC -DHAS_OPUS -DVERSION=\"$(VERSION)\" -I. -I.. -I../common -I<boost dir>
and change the LDFLAGS line below it to
LDFLAGS += $(ADD_LDFLAGS) -lvorbis -lvorbisenc -logg -lFLAC -lopus -latomic
Now do
make
sudo make install
In my /etc/snapserver.conf I have
stream = tcp://127.0.0.1?name=mopidy_tcp&port=4953
And in /etc/mopidy/mopidy.conf I have
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpclientsink host=127.0.0.1 port=4953
Note that using 'localhost' in the mopidy.conf didn't work, I got errors saying GStreamer could not open the source, but using 127.0.0.1 fixed that. Wierd.
The only minor issue I now have is that the playback position reported by mopidy is about 5 seconds ahead of what's coming out of my speakers. I assume this is some buffer size thing in the tcp sink, it'd be interesting to know how to change that.
Can Snapcast run multiple modes at the same time? I still would like to be able to use fifo together with tcp
@gerroon you can define multiple streams that have different sources (fifo, tcp)
FWIW, the Mopidy team just dropped version 3.0.1 eleven days ago. I haven't had a chance to play with it yet. It requires Python 3.7 I've read and it uses a much more recent version of GStreamer, 1.14.0. This might be enough to resolve your issue. I'm planning on playing with it tonight. I got all of my backups in line this morning so I can step back if necessary, but I'm really excited about it.
https://mopidy.com/blog/2019/12/22/mopidy-3.0/
KO
I'm already running it. It doesn't solve the issue :) The Mopidy devs say that GStreamer and FIFOs don't play well together. They did try to make a fifo output within Mopidy some time ago but again, GStreamer makes it hard. This new TCP sink is the way forward.
My biggest concern is that the configuration seems to rely on static IP addresses, which I spent a few days getting rid of in favor of DHCP when I went to OpenWRT a month or two ago . I really want to stay dynamic. My implementation of the static IP addresses was ugly and I'd really prefer to not step back to it.
Well if you're using it in place of a fifo - which you can't use over a network anyway - then the only IP address you need is 127.0.0.1, which is 'local loopback' and requires no configuration.
TYVM!
I've been testing this all night, and it's working great with a bunch of streams. I've been able to separate my services (multiple librespot instances, mopidy, etc) and the FIFO mess is gone!
I've also been able to stream the audio from my PC to snapcast from pulseaudio.
Config:
stream = tcp://0.0.0.0:4956?name=PC
On my PC I pipe pulseaudio to netcat:
$ parec --rate=48000 --format=s16le --channels=2 | nc snapserver.home 4956
Does anyone know of a better way to have pulseaudio send raw PCM over a network to a host?
@badaix I have one suggestion... instead of tcp://...&mode=[client|server]
how about tcp-server://...
and tcp-client://...
? I think it'd be a lot more immediately clear what's going on there.
Another confirmed working: the develop branch builds just fine on Armbian (ubuntu bionic) after manually installing the ubuntu libboost1.71-dev package (https://launchpad.net/ubuntu/+source/boost1.71).
And the tcp stream works great with mopidy 3.0.
Thanks!
@fatg3erman very early testing suggests something seems to be up with the RompR snapcast volume control when using the TCP stream. Here's the output I get:
RompR v1.30
Cheers Nik
If I understand this correctly, I could run a stream in server mode, and on another machine netcat a PCM stream to the IP/PORT set in the stream, is that right? This is great timing as I've been looking for a way to easily stream a PCM capture from a remote device.
@eoware yes, correct.
I'm running with the latest dev commit, and the following configs:
stream = tcp://0.0.0.0:4953?name=Spotify_1 stream = tcp://0.0.0.0:4954?name=Spotify_2 stream = tcp://0.0.0.0:4955?name=Mopidy
Librespot is running on two separate docker containers and is forwarding FIFO to network via netcat:
nc ${TARGET_HOST} ${TARGET_PORT} </tmp/snapfifo & librespot ... --backend pipe --device /tmp/snapfifo
and mopidy:
[audio] output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpclientsink host=snapcast port=4955
It seems to work well :) I'll do more stress testing this week.
can't seem to get this to work with librespot (raspotify) -- could be my lack of understanding about netcat . . . I'm running librespot on the same server as the snapserver.... TCP seems to work ok with mopidy.
can't seem to get this to work with librespot (raspotify) -- could be my lack of understanding about netcat . . . I'm running librespot on the same server as the snapserver.... TCP seems to work ok with mopidy.
@JayGatsby7 can you provide more information?
can't seem to get this to work with librespot (raspotify) -- could be my lack of understanding about netcat . . . I'm running librespot on the same server as the snapserver.... TCP seems to work ok with mopidy.
@JayGatsby7 can you provide more information?
Do you have a pipe open on snapserver.conf for tmp/snapfifo? Or just the setting for TCP?
Netcat configs in your example. Are you putting those parameters in the librespot / raspotify config?
I’m using mopidy with tcp for the time being but would like to get librespot working with tcp on a separate port as well.
My biggest concern is that the configuration seems to rely on static IP addresses, which I spent a few days getting rid of in favor of DHCP when I went to OpenWRT a month or two ago . I really want to stay dynamic. My implementation of the static IP addresses was ugly and I'd really prefer to not step back to it.
@KraigoMpls: I will keep this in mind for the next version. I already started to implementing host resolution, but removed it for this first version of the tcp plugin. I think for most users the audio source will run on the same host. You can open a feature request for this, so that I will not forget about it.
@badaix I have one suggestion... instead of
tcp://...&mode=[client|server]
how abouttcp-server://...
andtcp-client://...
? I think it'd be a lot more immediately clear what's going on there.
@uSpike: valid suggestion, could be done together with the client host resolution feature. Can you also open a feature request for this?
I've now also tested this with mopidy and things work fine apart from one fact: If I stop music on mopidy or switch the song, this sometimes takes ~ 30 seconds to propagate to the snapclient instances. Any ideas on that? Sounds a like the buffer is too large.
@languitar GStreamer's tcpserversink
has the option buffers-max
, maybe this could help.
What happens when you stop/start playing? Will the delay be reset? Does it grow over time?
What is your gstreamer config (your [audio] output
)?
Remark: that's the inherent problem with TCP: it doesn't drop. I was initially playing with the UDP client/server sinks, but had lots of dropped packets, this would require a dedicated reader thread and packet queue.
@languitar GStreamer's
tcpserversink
has the optionbuffers-max
, maybe this could help.
I haven't configured anything special here so far.
What happens when you stop/start playing? Will the delay be reset? Does it grow over time?
It starts playing more or less immediately. Seems to accumulate over some time, though.
What is your gstreamer config (your
[audio] output
)?
The basic config that I have found in the docs / issues:
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpclientsink host=127.0.0.1 port=3333
Remark: that's the inherent problem with TCP: it doesn't drop. I was initially playing with the UDP client/server sinks, but had lots of dropped packets, this would require a dedicated reader thread and packet queue.
I don't think dropping packages here is needed as long as the buffer size is controlled somehow.
Does anyone know of a better way to have pulseaudio send raw PCM over a network to a host?
I'd be interested in this, too, as I stream from a local kodi instance (which needs pulseaudio). Or is it possible to create a tcp sink to use this new plugin?
Does anyone have problems with seeking when using tcpclientsink ?
I have mopidy 3.0.1, snapserver 0.18.1 and tried the tcpclientsink, but when I seek using any mpd/webclient the audio immediately stops, does nothing for ~1min (snapclient is not receiving any samples) and then starts playing at the seeked time.
It looks like a problem with gstreamer, but I even upgraded it to gstreamer 1.16.2 and had the same problem ( https://discourse.mopidy.com/t/seeking-takes-a-very-long-time-1min/ )
Does anyone have problems with seeking when using tcpclientsink ?
I have mopidy 3.0.1, snapserver 0.18.1 and tried the tcpclientsink, but when I seek using any mpd/webclient the audio immediately stops, does nothing for ~1min (snapclient is not receiving any samples) and then starts playing at the seeked time.
It looks like a problem with gstreamer, but I even upgraded it to gstreamer 1.16.2 and had the same problem ( https://discourse.mopidy.com/t/seeking-takes-a-very-long-time-1min/ )
Yep same problem here. I was going to look into debugging on the Mopidy end when I get some time.
First of all, thanks!! This is the feature I was waiting for! I've found a new way to connect a remote pulseaudio client to the snapserver, just add this to your ~/.config/pulse/default.pa (or /etc/pulse/default.pa):
load-module module-simple-protocol-tcp source=0 record=true port=4953 rate=48000 channels=2 format=s16le
(get source number from pactl list sources
).
and then create a in the snapserver tcp stream client mode:
stream = tcp://<YOUR PULSEAUDIO REMOTE IP>?name=<YOUR STREAM NAME>&mode=client
Everything works flawlessly. I also want to set the streams:
stream = pipe:///tmp/snapfifo?name=default
stream = tcp://127.0.0.1?name=mopidy_tcp
all three together, but this doesn't work. I can only set one stream at a time, when I set more than one only one of them works. What I am doing wrong? How can I set multiple streams at a time working all together?
Thanx in advance.
I've been testing this for a bit today and have run into the issue of always having the first half a second or so of the TCP stream cut off. I've tried with Mopidy 2 and Mopidy 3 (same Gstreamer backend). I've tried switching each between client and server, also without luck. I'm running Mopidy and Snapcast in separate Docker containers and have been feeding in files from Home Assistant, either dynamically generated TTS mp3s or other mp3s I have hosted locally.
I sometimes see this message in Snapcast's log:
2020-04-24 22-53-32 [Error] (AsioStream) Error reading message: End of file, length: 3528
When I switch back from Mopidy/TCP to MPD/pipe, all sounds good again and I don't lose the first part of the audio or see errors in Snapcast's log.
I suppose this issue is probably with Mopidy/Gstreamer, but I was wondering if anyone else has seen this before and if they managed to work around it.
@hawkeye217
To be honest I think that Mopidy using Gstreamer as a backend was a bad move and I myself wasted so many hours on the same issue while trying to fix it.
To be honest I think that Mopidy using Gstreamer as a backend was a bad move and I myself wasted so many hours on the same issue while trying to fix it.
Great, glad to know it's not me. I'll stop wasting more hours then :)
Ironically I've had a little more success with Mopidy by using the alsasink
output in mopidy.conf
:
[audio]
output = alsasink device=snapcast_fifo
and then creating a custom entry in my /etc/asound.conf
file like this:
pcm.snapcast_fifo {
type plug
slave {
pcm {
type file
file "/tmp/snapfifo"
slave.pcm null
format raw
}
rate 48000
format s16_le
channels 2
}
}
But it still is not as reliable as mpd
. Off to try something else... Volumio maybe?
Any ideas when this plugin might be on official release?
I'm interested because of remote parec
I've been testing this all night, and it's working great with a bunch of streams. I've been able to separate my services (multiple librespot instances, mopidy, etc) and the FIFO mess is gone!
I've also been able to stream the audio from my PC to snapcast from pulseaudio.
Config:
stream = tcp://0.0.0.0:4956?name=PC
On my PC I pipe pulseaudio to netcat:
$ parec --rate=48000 --format=s16le --channels=2 | nc snapserver.home 4956
Does anyone know of a better way to have pulseaudio send raw PCM over a network to a host?
Did you tried to use --server
in parec
command?
According to documentation you can specify hostname.
Dumb question. I'm having a an issue when I have more than 1 client connected to snapcast. One client plays a digital scream for about 10 seconds and then resumes the stream, the other blanks the audio for about 10 seconds as well. I made the changes to mopidy.conf and snapcast.conf but I am getting errors like "mopidy.audio.actor: Setting GStreamer state to GST_STATE_PLAYING failed" and "mopidy.audio.gst: GStreamer error: gst-resource-error-quark: Could not open resource for reading"
I've read and re-read this issue and it looks like a plugin is needed? I'm running the latest stable which was installed with the .deb file on Ubuntu 18.04.
Thanks
I’ve been running this regularly since it was first released and have at some point encountered all the problems described in the thread. I’ve done a lot of debugging and a lot of research and have come to the conclusion that, if it’s not outputting directly to audio hardware, GStreamer just isn’t very good.
To everybody having issues with mopidy my only advice is either learn to live with them or switch to MPD.
GStreamer just isn’t very good.
This is why Mopidy is not cutting it. I exactly did what fatg3erman says, switched to MPD.
Are there other output plugins available that could me more reliable? Also one could consider writing another sink for gstreamer, maybe a real pipe sink, instead of a file sink.
I did get the TCP stream working after upgrading to Mopidy 3. I need to do more testing but lastnight there were frequent short audio drops and no audio at all for extended periods of time. Last night may have been wi-fi congestion...
Have the following working with TCP between Mopidy and Snapcast, works much better than FIFO:
The issue is if i do 1. and 2. at the same time then both songs come out of music-1.local speakers at the the same time. It there a way to have it so the latest action cancels the previous action? Below are the configurations:
Server (Unraid VM/Ubuntu 20.04): music.local
/etc/snapserver.conf
stream = tcp://127.0.0.1:3333?name=mopidy_tcp
/etc/mopidy/mopidy.conf
[file]
media_dirs = /mnt/user/tunes
[http]
hostname = 0.0.0.0
zeroconf = Tunes on $hostname
[mpd]
hostname = 0.0.0.0
zeroconf = Tunes on $hostname
[audio]
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpclientsink hotost=127.0.0.1 port=3333
Remote/s (RPI/Ubuntu 20.04): music-1.local, music-2.local
/etc/defaults/snapclient
SNAPCLIENT_OPTS="--host 192.168.2.5"
/etc/mopidy/mopidy.conf
[file]
media_dirs = /mnt/user/tunes
[http]
hostname = 0.0.0.0
zeroconf = Tunes on $hostname
[mpd]
hostname = 0.0.0.0
zeroconf = Tunes on $hostname
[audio]
output = alsasink
Does anyone have problems with seeking when using tcpclientsink ?
Yes, if used with wavenc. But we don't need wavenc since snapcast wants S16LE PCM @ 48K (or whatever you have configured) and that's what audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE
provides us with. I've had no seeking problems (so far) using:
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! tcpclientsink host=127.0.0.1
I've tested with GStreamer 1.16.2.0 on Ubuntu 20.04 and GStreamer 1.14.4.0 on Raspbian Buster.
However, I do see the issue with the playback position within Mopidy not corresponding to what snapcast is playing. Mopidy's position is delayed. Need to spend more time looking at that. I also hear a little stutter when playing starts or seeks but I'm not convinced that's a Mopidy/GStreamer issue.
It's maybe worth also mentioning that seeking actually works OK if you substitute wavenc for a different encoder e.g. opusenc. Obviously snapcast can't decode opus (although it does try and it doesn't sound great!) but the seek does actually work and there's no GStreamer error as with wavenc. I don't know what's specifically wrong with wavenc or if it's a combination of it's problem along with the tcp*sinks themselves. Those sinks don't see much usage / love, I'm not sure how great they are (but I do like that they let you run Mopidy and Snapcast on different systems and they would also work for Mopidy on Windows).
I gave this all a try after also trying filesink. I didn't actually hit any problems using filesink myself - gapless worked, seeking worked, the playback position remained accurate. But it's a complicated beast and it's really not designed with FIFOs in mind, it just happens to work with them ...some of the time. There's a stark difference when comparing GStreamer's jack-of-all-trades filesink implementation to MPD's super simple FIFO output. FIFO-specific things like creating the FIFO (and then removing it after) and sensibly handling the full condition are handled by MPD but not by filesink. I'm a little tempted to have another look at a dedicated GStreamer fifosink... Although I'd want to understand better and reproduce what's currently wrong with filesink.
Latest snapcast has an ALSA loopback sink which is working much better than either fifo or tcp for me with mopidy. Still has the playback position being off, but surely that's just buffering in snapserver?
but surely that's just buffering in snapserver?
Unsure. Bizarrely the playback position offset seems to be noticeably better (less) when Mopidy is running on a different machine to snapserver. Not sure I expected that.
EDIT: Oh wait. I wasn't thinking, it makes sense. It would take longer for the audio data to travel over the network from the Mopidy machine to the snapserver machine, would arrive at snapserver later, and so would be played later. If there was enough delay then playback would appear more synchronised w.r.t Mopidy's delayed current position (but it's just dumb luck).
But for Mopidy's position to be behind, I think that must be a problem within Mopidy. Maybe tcpclientsink is reporting a much larger latency than it's actually seeing.
It's maybe worth also mentioning that seeking actually works OK if you substitute wavenc for a different encoder e.g. opusenc. Obviously snapcast can't decode opus (although it does try and it doesn't sound great!) but the seek does actually work and there's no GStreamer error as with wavenc. I don't know what's specifically wrong with wavenc or if it's a combination of it's problem along with the tcp*sinks themselves. Those sinks don't see much usage / love, I'm not sure how great they are (but I do like that they let you run Mopidy and Snapcast on different systems and they would also work for Mopidy on Windows).
I gave this all a try after also trying filesink. I didn't actually hit any problems using filesink myself - gapless worked, seeking worked, the playback position remained accurate. But it's a complicated beast and it's really not designed with FIFOs in mind, it just happens to work with them ...some of the time. There's a stark difference when comparing GStreamer's jack-of-all-trades filesink implementation to MPD's super simple FIFO output. FIFO-specific things like creating the FIFO (and then removing it after) and sensibly handling the full condition are handled by MPD but not by filesink. I'm a little tempted to have another look at a dedicated GStreamer fifosink... Although I'd want to understand better and reproduce what's currently wrong with filesink.
That would be interesting. I am using filesink as well and I am seeing playback stop in a playlist after every track. I am not using waveenc as that would mess up the data by including wav headers. As you write, PCM should be just fine. I have seen an end of stream but cannot figure out why playback stops.
I've now also tested this with mopidy and things work fine apart from one fact: If I stop music on mopidy or switch the song, this sometimes takes ~ 30 seconds to propagate to the snapclient instances. Any ideas on that? Sounds a like the buffer is too large.
@languitar I realize this was over a year ago now but did you ever solve this problem? I am not using mopidy but have the same results with the android client.
On Wed, May 19, 2021 at 12:34:33PM -0700, pcwii wrote:
I've now also tested this with mopidy and things work fine apart from one fact: If I stop music on mopidy or switch the song, this sometimes takes ~ 30 seconds to propagate to the snapclient instances. Any ideas on that? Sounds a like the buffer is too large.
@.*** I realize this was over a year ago now but did you ever solve this problem? I am not using mopidy but have the same results with the android client.
This is the logic being implemented in snapcast.
In snapcastc (an own rewrite that was created at a time when badaix was busy and I wanted things changed) I did experiment with other mechanics for start/stop and pausing. The program follows the same principle as snapcast but has different behavior in those two aspects:
There might be other things that could be tried. In essence snapcast(c) must be told the users intent. So a side channel is needed besides the audio stream. If mopidy supports calling hooks this could be realized with extending the API of either tool.
-- () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments
I'm currently using MPD as input for snapcast (connected via pipe) and now I started playing with Mopidy, which seems to be more actively developed and more feature rich. I've observed some strange audio loops during my Mopidy tests, using this setup GStreamer setup:
I was wondering if there are GStreamer sinks that are more reliable and implemented a TCP stream that can be configured to act as client or as server, allowing the following setups:
Snapcast running in TCP server mode
snapcast.conf:
the general pattern is:
tcp://<IP of the listen interface>:<port>?name=<name>&mode=[client|server]
default forport
(if omitted) is 4953, default formode
isserver
mopidy.conf (running GStreamer in client mode)
Snapcast running in TCP client mode
snapcast.conf:
in client mode the IP and port are the server's IP, port to connect to (default for port is again 4953)
mopidy.conf (running GStreamer in server mode)
If you want to give it a try: it's available in the current develop branch, any feedback is appreciated! This would also solve #486 (well, at least it would work around it)