frafall / service.snapcast

Run Snapcast as a Kodi addon
GNU General Public License v3.0
11 stars 1 forks source link

A newbie needs help #1

Closed FHoevi closed 6 years ago

FHoevi commented 6 years ago

Hi there, thanks for sharing your work, I'm really interested. Currently I'm experimenting quite a bit with Kodi and snapcast, hot topic is LibreElec and snapcast. Since I'm not quite experienced with Linux in general and building LibreElec in special I do not really know how to do the steps you are indicating. What exactly do I need and to do to get snapcast as an addon for LibreElec/Kodi? Please provide some advice for people like me.

Cheers F

FHoevi commented 6 years ago

I just started with a fresh raspbian stretch on my RPi3, after cloning anything from GITHub as instructed the create_addon script tells me that raspbian is not supported. What do I have to do to get that included in that environment?

[EDIT]: OK, I'm gonna cross-build it as instructed on an old PC running Lubuntu...

frafall commented 6 years ago

Hi, I have no experience with Kodi on Raspian as I stuck with Libreelec on my installs. But, I would try to download the pre-compiled addon, store it on the filesystem of Raspbian and use Kodi to install the addon from the zip file.

FHoevi commented 6 years ago

OK, thanks for letting me know, so far I did not realize that there are pre-compiled and zipped files.

I just installed the addon but I struggle with enabling the client and server services since systemd does not seem to be present: -sh: systemd: not found. What do I have to do? Without that I can't execute something like systemd enablepwd/snapclient.service, right?

BTW, cross-compiling like indicated here https://wiki.libreelec.tv/compile stopped on my old and slow PC after a couple of hours, the last lines were these:

Configured

for linux-x86_64.

Because of configuration changes, you MUST do the following before building:

make depend

Executing (host): make making all in crypto... make[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule. make[1]: Entering directory '/home/XXX/LibreELEC.tv/build.LibreELEC-RPi2.arm-8.2.0/openssl-1.0.2l/.i686-linux-gnu/crypto' /usr/bin/perl ../util/mkbuildinf.pl "/home/XXX/LibreELEC.tv/build.LibreELEC-RPi2.arm-8.2.0/toolchain/bin/host-gcc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O2 -Wall -pipe -I/home/XXX/LibreELEC.tv/build.LibreELEC-RPi2.arm-8.2.0/toolchain/include -Wno-format-security -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM" "linux-x86_64" >buildinf.h /home/XXX/LibreELEC.tv/build.LibreELEC-RPi2.arm-8.2.0/toolchain/bin/host-gcc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O2 -Wall -pipe -I/home/XXX/LibreELEC.tv/build.LibreELEC-RPi2.arm-8.2.0/toolchain/include -Wno-format-security -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -c -o cryptlib.o cryptlib.c In file included from /usr/include/stdlib.h:24:0, from cryptlib.h:62, from cryptlib.c:117: /usr/include/features.h:367:25: fatal error: sys/cdefs.h: No such file or directory compilation terminated. make[1]: *** [: cryptlib.o] Error 1 make[1]: Leaving directory '/home/XXX/LibreELEC.tv/build.LibreELEC-RPi2.arm-8.2.0/openssl-1.0.2l/.i686-linux-gnu/crypto'

What does that mean? Have you compiled it directly on a LibreELEC based machine?

frafall commented 6 years ago

Have you set the PROJECT and ARCH environment variables to reflect the platform you are trying to cross compile to? export PROJECT=RPi2 export ARCH=arm

I have made a virtual machine running Debian 16.04 as this is the recommended platform for developing Libreelec, ie I'm cross compiling on a x86 platform for the RPi.

I first tried my main Debian Buster and an Ubuntu 17.10 but found incompatibilities I did not want to struggle with, after moving to Ubuntu 16.04 it went smoothly.

FHoevi commented 6 years ago

Yeah, of course I've set the env vars like that.

Anyway, could you please provide some advice on the systemd problem outlined above? It's not present in case of LibreElec, so what to do in that case? Is there an alternative way to start the services?

frafall commented 6 years ago

The systemd issue is with Raspian? Does it support systemd? Then to get snapclient support I guess the easiest would be to unzip the .zip file, check if the snapserver/snapclient executables work (by trying to run them) and make a startup scripts for Raspbian. The startup scripts supplied in the addon are for systemd.

FHoevi commented 6 years ago

No, as I said, I installed your pre-compiled plugin on my RPi3 running LibreElec. When I login on that machine via putty/console, I cannot use systemd since it is not present. What to do?

frafall commented 6 years ago

What version of Libreelec are you running?

FHoevi commented 6 years ago

It's the 8.2.0.1 RPi2.arm running on an RPi3.

May it be linked to something like this: https://forum.libreelec.tv/thread/5672-libreelec-8-and-systemd/ ?

In my case /etc/systemd exists and contains 4 .conf files but systemd as such is not recognized by the shell (sh) used for LibreELEC. But systemctl does respond.

FHoevi commented 6 years ago

Is there a chance to get any help in this respect? I still cannot get it running.

frafall commented 6 years ago

The use of 'systemd' was a typo in my README, it should have been 'systemctl'.

Adding Snapcast as a service should have been done on install by Kodi, can you check if it is registered by doing a 'systemctl | grep -i snap'? Have you checked the journal 'journalctl -xe' for any errors during install or boot?

FHoevi commented 6 years ago

OK, now I do hear sound after a systemctl start snapserver.service since that was not active. But I still do have to start snapclient from the command line. How could I let that start at boot automatically? But thanks anyway for pointing me to these services and their resp. status.

Another question is about the latency of the sound output since snapcast introduces an offset of 1000 msec. In Kodi I could speedup the audio track by, e.g., 514 msec (not more because then the video will be stuttering). In addition, on OpenElec and on a machine running plain Raspbian Stretch and a snapclient I could do this pactl set-port-latency-offset alsa_card.platform-soc_sound analog-output 486000 for an additional 486 msec speedup to compensate for snapcast's 1000 msec lag in total. On those clients audio is in perfect sync with the video track. On the LibreElec server machine where a snapclient runs as well this command does not have any effect. pactl list sinks tells me that the latency is still set at 0. How could I achieve that? I think that'll be the last piece of that puzzle...

[EDIT]: Also, the --latency parameter of snapclient does not have an effect. Maybe that's another symptom of the same issue.

frafall commented 6 years ago

Hmm, the addon starts the snapclient, the service "service.snapcast.service" is the client starter.

$ systemctl -a | grep -i snap
  service.snapcast.service  loaded    active   running   Snapcast client

$ ps -ef | grep snapclient
22367 root       0:01 /storage/.kodi/addons/service.snapcast/bin/snapclient -d -s out_hdmi

$ systemctl status service.snapcast.service
● service.snapcast.service - Snapcast client
   Loaded: loaded (/storage/.kodi/addons/service.snapcast/system.d/service.snapcast.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2017-11-29 08:28:40 CET; 2min 11s ago
  Process: 22365 ExecStart=/storage/.kodi/addons/service.snapcast/bin/snapclient -d $USER_OPTS $SNAPCLIENT_OPTS (code=exited, status=0/SUCCESS)
  Process: 22353 ExecStartPre=/bin/sh /storage/.kodi/addons/service.snapcast/bin/snapcast.init (code=exited, status=0/SUCCESS)
 Main PID: 22367 (snapclient)
   CGroup: /system.slice/service.snapcast.service
           └─22367 /storage/.kodi/addons/service.snapcast/bin/snapclient -d -s out_hdmi

Nov 29 08:28:40 stue systemd[1]: Starting Snapcast client...
Nov 29 08:28:40 stue systemd[1]: Started Snapcast client.
Nov 29 08:28:40 stue snapclient[22367]: daemon started
Nov 29 08:28:40 stue snapclient[22367]: Connected to 192.133.64.10

You can try to start it with 'systemctl start service.snapcast.service'. If snapclient is not running you can check out why with 'journalctl -xe | grep -i snap' which should give an indication. The snapclient should be started at boot audomatically, if its not there is an error somewhere, typically in the ALSA setup, but the journal or systemctl status should show info on this.

As for the latency, the pactl is a Pulseaudio command, snapclient uses the ALSA sound system, ie. pactl does not affect snapclient.

Question is what are you trying to achieve by modifying snapcast latency?

FHoevi commented 6 years ago

What I need and what I know it works with snapcast is multi-room audio distribution based on Kodi as the central mutimedia application. But at the same time audio should be in perfect sync with video as well. This is working as well, I already achieved that with OpenElec. The difference is that I could get hold of the PA latency in that case by adjusting the parameter as I mentioned before. With LibreElec i was not successful so far since ot does not let me apply this adjustment as OpenElec does. I'm talking about the server machine, on the plain raspbian clients I could apply the adjustment and anything's fine. Only on the LibreElec machine which serves as a snapserver and as a snapclient at the same time it is not possible. At least I don't know how except for the obvious way which does not work in that case. So, yes, it's about pulseaudio, but that has to be switched on anyway.Snapcast introduces a lag of 1 sec which I need to compensate and to synchronize audio and video in the end.One solution could be to let this snapserver machine not to play audio at all, but then I would need another client doing this instead.So, audio output is switched to pulseaudio anyway to be able to use snapcast, but I cannot set the latency parameter as I can under plain raspbian.What to do?BTW, your service addon seems to be very stable, I think you really did a good job based on the original snapcast code. Have you changed something significantly?

frafall commented 6 years ago

So if I understand, you run Kodi->Pulseaudio, then let Pulseaudio stream to both Snapserver and ALSA?

My experience is that something like this is hard to synchronize, I'm planning (but haven't looked at yet) to run Kodi->Pulseaudio->snapserver->snapclient(s) let Snapcast do what its made for, namely synchronized multiroom playing. To compensate for video/audio sync I though I could modify audio latency in the advancedsettings.xml.

My ideal setup would be to have snapserver and snapclient integrated into the Kodi audio subsystem to drop Pulseaudio and minimize latency but I haven't started looking at the integration yet, even the Kodi Airplay is basically a piped approach addressed as an URL.

FHoevi commented 6 years ago

No, what I have in mind is exactly matching your idea, Kodi -> PA -> Snapserver -> Snapclient(s) -> (PA -> ) ALSA. With OpenElec this works, but unfortunately not with LibreElec, the only missing piece is this godforsaken latency adjustment on the server machine which is intended to work as a snapclient at the same time. As I've said, compensating for snapcast's 1 sec latency is indeed possible with adjusting a) within Kodi, and b) within PA in tandem.Perhaps I still have not configured PA -> ALSA on that machine 100% correctly. I will have another look asap.

frafall commented 6 years ago

As far as I know the snapclient only supports ALSA (linux), Core Audio (OSX) and Opensl (Android). So, anything you do in Pulseaudio will not influence snapclient output latency.

But, for a detailed discussion on latency topics you are probably better off talking to Badaix.

FHoevi commented 6 years ago

Yes, that's true. But via pulseaudio/pavucontrol or pactl settings I can set latency for an ALSA device as well. Only on LibreElec my parameter change has no effect, whereas on plain raspbian it has. That's exactly my problem, it only has to do with LibreElec, with nothing else.

FHoevi commented 6 years ago

BTW, where could I find the mentioned file advancedsettings.xml and how does it work?

frafall commented 6 years ago

I didn't know you could access the ALSA device settings through Pulseaudio, never to late to learn something new :)

Could it be that you need to activate the sound device for Pulseaudio? Pulseaudio in Libreelec is not set up to detect cards automatically.

Quick google:advancedsettings.xml

FHoevi commented 6 years ago

The card shows up as it does on the parallel raspbian installation. So, 'pactl list sink' yields the same result regarding this device. And the latency command has no errors but also not the desired result. I already opened a thread in the LibreElec forum, let's wait.

FHoevi commented 6 years ago

Ah, ok, those advanced settings are a Kodi setting. But there the max speedup for audio on a RPi3 is about 500 msec, above video gets stuttering. So, to compensate for another 500 msec you would need to adjust at a second place, i.e. this pulseaudio setting I was mentioning before.

frafall commented 6 years ago

Well, you probably could experiment with the -b option to snapserver, I haven't tried it but it seems to me a lower value might be feasible in a home network, as far as I understand this is what makes the 1000ms latency.

FHoevi commented 6 years ago

Puh, after at least 3 more hours full of experiments I recognized that all my own settings in .kodi/addons/service.snapcast/default/snapserver do not have an effect. E.g. I've set sampleformat=44100:16:2 but a snapclient tells me after hooking up that still the default 48000:16:2 is set. I already stopped and restarted the snapserver service but nothing changes. How could I change that?

Second, my pulseaudio latency setting is correct and gets recognized, which I could check by looking at pactl list cards, not pactl list sinks, since it is a card's latency which is set by pactl set-port-latency-offset CARD PORT VALUE. But still it has no effect which indeed it has on my parallel plain raspbian setup running a snapclient in perfect sync.

Man, I think I have to switch to a setup where one central machine with no sound card attached runs LibreElec and snapserver (no snapclient at all) with a pulseaudio file sink and all clients with soundcards on their backs are running plain raspbian with snapclient which hooks up to the fifo pipe on the server.

One machine more in my collection, I'm gonna try that tomorrow...

FHoevi commented 6 years ago

OK, sampleformat ist now set to 44100:16:2, there was an unintentional linebreak in the config file, now it gets recognized as desired. Covergence is proceeding slowly but steadily ;)

FHoevi commented 6 years ago

With a setup like this one

  1. RPi3 running LibreELEC 8.2 as well as snapserver as a plugin, no audio output
  2. 2 RPi3 running Raspbian Stretch as well as snapclient, audio output via HifiBerry Amp2

anything works in perfect sync now. Kodi audio delay is set to +514ms on the first machine, via pulseaudio or pavucontrol on the two other client machines I adjusted the latency parameter for the ALSA card to 486ms, so it adds up to 1000ms, compensating for snapcast's latency.

Now I'm gonna add a third client but I think now I do know how I have to configure anything properly.

frafall commented 6 years ago

Nice :+1:

Pretty much what I use, only my central server is a x86 in the basement, mainly as I already had it running and it has cpu to transcode whatever. But, I haven't done any Kodi output to Snapcast, I use Spotify/Shairplay.sync/Mopidy audio sources.

Spent the last few days pushing metadata through snapcast to let clients display it.

FHoevi commented 6 years ago

Thank you very much for your work in terms of the two services! Now I think it's really a nice setup.

Well, my central data server is a NAS, located in the basement as well, on which a PlexServer is running. With the corresponding PlexKodiConnect plugin as a client I can hook on to that, next to other potential Plex clients like my PC on my desk.

May I ask another question? When I do want to let snapclient start as a service already at boot on my raspbians as well, could I use the service.snapcast file as well? Could you please provide a crisp instructable on that as well?

frafall commented 6 years ago

Assuming the Raspian runs systemd it should be possible to use it. You would have to modify the paths, also you need a default/snapclient file put somewhere and you can comment out the ExecStartPre. Potential issue is the After/Requires - not sure these exists with same name in Raspian. But, I guess the Raspbian could use the systemd files included in snapcast/server/debian which I used as a starting point.

[Unit]
Description=Snapcast client
After=network-online.target sound.target
Requires=network-online.target

[Service]
Type=forking
EnvironmentFile=-/storage/.kodi/addons/service.snapcast/default/snapclient
#ExecStartPre=/bin/sh /storage/.kodi/addons/service.snapcast/bin/snapcast.init
ExecStart=/storage/.kodi/addons/service.snapcast/bin/snapclient -d $USER_OPTS $SNAPCLIENT_OPTS
PIDFile=/var/run/snapclient/pid
Restart=always

[Install]
WantedBy=multi-user.target
FHoevi commented 6 years ago

OK, the stuff below was already set up by default, I did not have to care about it, I just had to wait. The snapclient service takes some time to start up.

But now I exectued systemctl status snapserver on my RPi running LibreELEC and acting as snapserver, as well as systemctl status snapclient on one of my RPis running Raspbian Stretch and acting as snapclient. The output looks like this:

Snapserver: systemctl status snapserver | more

Dec 05 20:20:44 LEServer snapserver[459]: Exception in StreamSession::reader(): read_some: End of file Dec 05 20:20:45 LEServer snapserver[459]: StreamServer::NewConnection: ::ffff:192.168.10.30 Dec 05 20:20:47 LEServer snapserver[459]: Exception in StreamSession::reader(): read_some: End of file Dec 05 20:20:48 LEServer snapserver[459]: StreamServer::NewConnection: ::ffff:192.168.10.30 Dec 05 20:20:50 LEServer snapserver[459]: Exception in StreamSession::reader(): read_some: End of file Dec 05 20:20:51 LEServer snapserver[459]: StreamServer::NewConnection: ::ffff:192.168.10.30 Dec 05 20:20:53 LEServer snapserver[459]: Exception in StreamSession::reader(): read_some: End of file Dec 05 20:20:54 LEServer snapserver[459]: StreamServer::NewConnection: ::ffff:192.168.10.30 Dec 05 20:20:57 LEServer snapserver[459]: Exception in StreamSession::reader(): read_some: End of file Dec 05 20:20:58 LEServer snapserver[459]: StreamServer::NewConnection: ::ffff:192.168.10.30

The IP address corresponds to the server machine, to me this output looks healthy, even if some exceptions popped up.

Snapclient: systemctl status snapclient | more

Dez 05 00:50:41 WZLinks systemd[1]: Starting Snapcast client... Dez 05 00:50:41 WZLinks snapclient[535]: daemon started Dez 05 00:50:41 WZLinks systemd[1]: Started Snapcast client. Dez 05 00:50:42 WZLinks pulseaudio[536]: [autospawn] core-util.c: Failed to create secure directory (/var/lib/snapclient/.config/pulse): Datei oder Verzeichnis nicht gefunden Dez 05 00:50:42 WZLinks pulseaudio[554]: [autospawn] core-util.c: Failed to create secure directory (/var/lib/snapclient/.config/pulse): Datei oder Verzeichnis nicht gefunden Dez 05 00:50:42 WZLinks pulseaudio[554]: [autospawn] lock-autospawn.c: Fehler beim Zugriff auf Autostart-Sperre. Dez 05 00:50:42 WZLinks pulseaudio[554]: [pulseaudio] main.c: Failed to acquire autospawn lock Dez 05 00:50:42 WZLinks snapclient[535]: Connected to 192.168.10.30

Some of the remarks are in german corresponding to the chosen settings, it means that the directory in question has not been found. Looks as if the user pi would not have sufficient privileges to create the directory /var/lib/snapclient/.config/pulse, does that mean a problem?

Currently my user settings in '/etc/pulse/default.pa' are ignored as well. Still not perfect though...

frafall commented 6 years ago

The /var/lib/snap... messages are pulseaudio, it must be something in it's config I'd guess. This will not do anything for snapclient as it does not use pulseaudio. But, there must be some pulseaudio config refering to snapcast, where would it get the path from?

FHoevi commented 6 years ago

Yeah, well, as I already told you, I need to use pulseaudio on the client to be able to adjust the latency of the audio output. It works like charm from the console of the user being logged in but neither via /etc/pulse/system.pa nor /etc/pulse/default.pa (which is most likely not used at all when no user is logged in).

All ways to place the necessary pulseaudio commands I found so far do not work at all, I'm going nuts...

lucianm commented 6 years ago

Hi guys, interesting discussion so far :+1: @frafall:

frafall commented 6 years ago
  1. In my fork of Snapcast I have added support for metadata (and sent a pull request back to @Badaix). I support any tag but recommend to stick with the Vorbis standard to simplify interfacing to client. So far this implements the following:

    • Distribution of metadata from server to clients
    • JSON api (Stream.SetMeta) to set metadata for a given stream, stream status gives metadata and separate metadata JSON notifications
    • Modified stream Airplay/Spotify to include metadata (text only so far). Airplay metadata requires Expat library during compile '_make -DHASEXPAT=1'
    • Added metatdata output from client, so far as json on stderr, but open for more channels like pipe/shell script.
  2. I run two instances of snapclient on my Libreelec, one on the SPDIF interface (Digi+) for headless music and one on the HDMI/Kodi interface. Kodi (on Libreelec) is ok with sharing the interface but I had to make the ALSA interface visible. Snapclient uses ALSA interfaces, check dtparam=audio=on

I have looked at tighter integration with Kodi, ex. the Kodi Airplay is really a piped approach specifying Kodi to play from a local pipe URL, this would work with Snapclient as well in an addon handling metadata.

Still missing is the metadata integration for Mopidy, I am thinking of two possible approaches:

  1. Make some kind of gstreamer interface to Snapcast, ideally with a networked approach
  2. Let Mopidy update Snapcast through JSON Stream.SetMeta call.
FHoevi commented 6 years ago

OK, clientwise snapclient's --latency parameter (value in ms, not mus!) indeed seems to do the job... But one has to make sure that all snapclient services involved run smoothly. So, no pulseaudio needed.

frafall commented 6 years ago

Great ;)

mdef commented 6 years ago

@FHoevi

All ways to place the necessary pulseaudio commands I found so far do not work at all, I'm going nuts...

Dit it here https://github.com/mdef/kodi-snapcast#installing https://github.com/mdef/kodi-snapcast/tree/master/storage/.config to configure PA permanent we should find out how PA is dealing with config locations.

@FHoevi also could you please share how do you adjusted the latency parameter for the ALSA card?

FHoevi commented 6 years ago

@mdef Well, let me explain my current setup:

  1. In the basement there is a Netgear ReadyNAS running PlexServer as central media center.
  2. I have an RPi3 running LibreELEC, PlexKodiConnect plugin as well as snapcast plugin as I took it from frafall's repo. Within Kodi audio output is set to pulseaudio which is already contained in LibreELEC (mainly for BT output as far as I know). In .kodi/addons/service.snapcast/default/snapserver I've set SNAPSERVER_OPTS="-s pipe:///tmp/snapfifo?name=XXX&codec=flac&sampleformat=44100:16:2&mode=read". Like in the instructions I copied snapserver.service.sample to snapserver.service, enabled this service, and started it. I stopped the service.snapcast. In /storage/.config/autostart.sh I added export PULSE_LATENCY_MSEC=60 pactl load-module module-udev-detect pactl load-module module-pipe-sink file=/tmp/snapfifo sink_name=XXX pactl set-default-sink XXX pactl set-sink-volume XXX 100% Essentially this https://wiki.libreelec.tv/pulseaudio is a usable source for PA commands under LibreELEC. Within Kodi I set audio output to +514ms (that was sort of max before video output starts stuttering).
  3. Now, I have a couple of RPi3s with HifiBerry Amp2 for high quality audio output running plain Raspbian Stretch. In /boot/config.txt I had to comment out dtparam=audio=on and add dtoverlay=hifiberry-dacplus. /etc/asound.conf had to be created containing pcm.!default { type hw card 0 } ctl.!default { type hw card 0 }. Snapclient was installed via wget https://github.com/badaix/snapcast/releases/download/v0.12.0/snapclient_0.12.0_armhf.deb sudo dpkg -i snapclient_0.12.0_armhf.deb sudo apt-get -f install. In /etc/default/snapclient I use this config: USER_OPTS="--user root:audio --latency 486". systemctl restart snapclient and systemctl status snapclient to check whether it's running smoothly. amixer -c 0 set Digital 80%, that's essentially it.

Currently, I observe that the client machines lose the latency compensation within snapclient which could be solved by simply restarting the snapclient service like already mentioned above. Maybe this is due to my current Wifi connection of those clients, which could make it harder to stay in sync. Within a wired configuration this was not the case and anything went smoothly.

Thus, in my case the "standard" service coming along with the standard snapcast package does the job, pulseaudio is no longer needed on the clients for latency compensation.

But that works as well, but just from the command line , when a user is logged in: pactl load-module module-udev-detect pactl set-sink-volume alsa_output.platform-soc_sound.analog-stereo 100% pactl set-port-latency-offset alsa_card.platform-soc_sound analog-output 486000. The first command lets PA find the sound card, the second adjusts the corresponding sink's volume and the third adjusts the corresponding audio card's latency to 486ms. My first attempt was to put these command line commands to /etc/pulse/default.pa, without the leading pactl of course, but no effect, they were simply ignored, even each one separately with an error message or no response at all but also still not working. I also tried to set them in /etc/pulse/system.pa, defined a pulseaudio service at system level to be loaded on system's startup but no effect either. My last and final resort was to check the latency parameter in snapclient which has to be specified in ms, not in mus like for PA's command line setting. But now it's working as outlined above. Remember, snapcast introduces a 1000ms (1s) delay between video and audio which has to be offset, once by moving the audio signal forward within Kodi (+514ms), and once within snapclient's config (--latency 486) to add up to a total 1000ms. Within Kodi it's just a slider being hard to set to a specific value. I've set it to +514ms, and the difference of that value to 1000ms within snapclient (see above), other split combinations may work as well, but most likely no combination being too different from the one I've chosen. If snapclient's latency compensation is too big it may be no longer possible to stay in sync and Kodi starts stuttering if the setoff within itself is getting too big.

That's pretty much it.

mdef commented 6 years ago

@FHoevi Thank you very much for explanation will apply settings to my kodi box. If you are still interesting to resove the following

My first attempt was to put these command line commands to /etc/pulse/default.pa, without the leading pactl of course, but no effect, they were simply ignored, even each one separately with an error message or no response at all but also still not working. I also tried to set them in /etc/pulse/system.pa, defined a pulseaudio service at system level to be loaded on system's startup but no effect either.

Configuration of pulseaudio in Libreelec and Openelec seems to be compatible: any *.conf file stored in storage/.config/pulse-daemon.conf.d/ will overwrite pulseaudio daemon configuration. The example below is used on my openelec kodi box. pulse-daemon.conf.d/my.conf my.conf is "saying" to pulseaudio to use alternative system.pa (not the default one) alternative one is stored at /storage/.config/system.pa in that alternative system.pa you can add the lines from your last comment:

pactl load-module module-udev-detect pactl set-sink-volume alsa_output.platform-soc_sound.analog-stereo 100% pactl set-port-latency-offset alsa_card.platform-soc_sound analog-output 486000

Also worth to mention: I do use Kodi as audio player(multiroom) and Video player(locally). You can run curl command from your workstation or I've configured Kodi_Callback to enter multiroom mode when I'm switched to "Music Tab" based on Window ID

With the following curl commands you can swtich audio devices. To multiroom: curl -v -H "Content-type: application/json" -X POST -d '{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.audiodevice", "value":"PULSE:Default"}, "id":1}' http://KODI_HOST:8080/jsonrpc

Back from multiroom to my 7.1 soundcard: curl -v -H "Content-type: application/json" -X POST -d '{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.audiodevice", "value":"ALSA:@:CARD=NX,DEV=0"}, "id":1}' http://KODI_HOST:8080/jsonrpc

Get the current audiodevice: curl -v -H "Content-type: application/json" -X POST -d '{"jsonrpc":"2.0","method":"Settings.GetSettingValue", "params":{"setting":"audiooutput.audiodevice"},"id":1}' http://KODI_HOST:8080/jsonrpc

Hope the info above will help you too.

FHoevi commented 6 years ago

@mdef I just tried to use a corresponding .conf file in /storage/.config/pulsedaemon.conf.d/custom.conf, but it still does not establish the fifo pipe, I tried that before already, following the instructions in README of that folder. I'll stick to do anything in /storage/.config/autostart.sh.

Like outlined above, the other pulseaudio problem occurs on the client machines, not the server, but the solution is the --latency parameter of snapclient.

What I find extremely interesting and thanks for pointing that out is the opportunity to execute such POST commands in an event-driven way via JSON-RPC. I do not want to switch audio output when switching from video to music but maybe other things like muting one client (in the kitchen) when starting a video which should only be played in another room for which two other clients are responsible. Do you know whether it is possible to use python as well in that context?

mdef commented 6 years ago

@FHoevi the content of /storage/.config/pulsedaemon.conf.d/custom.conf shoud be: load-default-script-file = yes default-script-file = /storage/.config/system.pa

but into /storage/.config/system.pa you need to put: load-module module-udev-detect set-sink-volume alsa_output.platform-soc_sound.analog-stereo 100% set-port-latency-offset alsa_card.platform-soc_sound analog-output 486000 and if you need fifio pipe add load-module module-pipe-sink file=/tmp/snapfifo rate=48000 sink_name=Snapcast update-sink-proplist Snapcast device.description=Snapcast

What I find extremely interesting and thanks for pointing that out is the opportunity to execute such POST commands in an event-driven way via JSON-RPC

I do not see a problem with it, just need to figure out the "Action/trigger" as in my example it is triggered by switching between video to music.

The curl/python script could be run against any kodi host (kitchen or living room) the ip of the host should be specified.