Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meta stream switches streams with delay #1187

Closed
toofar opened this issue Dec 30, 2023 · 10 comments
Closed

Meta stream switches streams with delay #1187

toofar opened this issue Dec 30, 2023 · 10 comments
Labels
bug feature request next release fixed in develop branch and will be part of the next release

Comments

@toofar
Copy link

toofar commented Dec 30, 2023

Is your feature request related to a problem? Please describe.
Example: I've got all my clients in the MPD group playing music, I would like to broadcast a short notification to them.

Describe the solution you'd like
I would like to be able to mix multiple sources into one group/stream so the notification is mixed with the music. Ideally with ducking or fading, although that can wait till a further feature request if this one is progressed.

Describe alternatives you've considered
If you've got MPD streaming via a FIFO you can pause MPD and write to the fifo. That's what I'm doing now and it works okay but 1) I would like to mix the streams and reduce the music volume instead of pausing the music 2) there are clicks when I start and stop writing to the fifo, possibly something I could resolve by making the notification sample fade in and out more? I'm not sure.

The other option is to use the JSON RPC API to switch all the connected clients to the notification group, then back. I do have a script that nearly does this already actually, but again, that doesn't handle fading or ducking. I haven't tried this out yet for this use case to see if there are any extra delays or anything.

Another alternative would to have another application handling any mixing required feeding into snapcast. I haven't looked into this yet because I would rather not complicate my setup more at this point if not required. (Although I suppose pipewire could handle it, maybe it's time to set that up on my media server.)

Ah, another alternative (from #813) is to have multiple snapclients on each device , eg an extra client per device for the notification group.

Additional context
Nothing I can think of. Mostly wondering if this is something you see snapcast learning to do or whether you recommend I pursue other alternatives further.

@badaix
Copy link
Owner

badaix commented Jan 1, 2024

I think this is exactly what the meta source does

@toofar
Copy link
Author

toofar commented Jan 2, 2024

Thank you, I had missed that!

I've tried the meta source out now and it does indeed switch sources like I want, and a bit less abruptly than writing to the fifo.
But with my current setup it switches between streams a bit less promptly than ideal? Slower than my current hacked up method at least.
I've got a tcp source (tcp) and a pipe source (mpd), niether have any parameters beyond the name. The meta source is meta:///tcp/mpd?name=default.
While mpd is playing if I send a short audio clip to the tcp source with gstreamer it seems to take a little while to switch to the tcp source and then back to the mpd one. When switching back to the mpd one I can see it takes between 500ms and 1s to switch, based on the following log sequence from the server:

2024-01-03 11-08-57.360 [Error] (AsioStream) Error reading message: End of file, length: 3772
# gap here
2024-01-03 11-08-58.218 [Info] (PcmStream) State changed: tcp, state: 2 => 1
2024-01-03 11-08-58.218 [Info] (Server) onStateChanged (tcp): 1
2024-01-03 11-08-58.218 [Info] (MetaStream) Stream: default, switching active stream: tcp => mpd
2024-01-03 11-08-58.220 [Info] (Server) onResync (default): 839.964 ms
2024-01-03 11-08-58.240 [Info] (MetaStream) first read, updating timestamp

There doesn't seem to be a log messages for first read from a tcp connection so I don't have numbers for switching from mpd to tcp, but I'm pretty sure it's losing the first little bit of the audio I'm sending.

I'm assuming that's because of the asio stream state timer being called at minimum every 500ms? If that's the case, do you think calling setState() in do_read() on first read and on error as well would be appropriate for TCP streams?

@chatziko
Copy link

I also observed the same issue with the "meta" source, it takes too long to switch making unusable for notifications (the start of the notification was often lost cause it played before the switch happened).

Judging from past messages here notifications is likely a major use-case for "meta", so any solution to make it switch faster would be greatly appreciated.

@jkrenzer
Copy link

I'd also think that notifications are a major use-case for the meta source.

So the possibility to apply ducking or corking would be a major feature for the use case.

@badaix
Copy link
Owner

badaix commented Jan 20, 2024

I'm reviewing this whole stream reading, in #1170 it turned out that the "PosixStream" seems to be redundant and even causing issues. I will do some testing also with the meta stream and TCP streams. In general Snapcast must somehow figure out the state of a stream, if it is playing or not. Some streams always deliver data, even when not playing they are sending silence. For others no data is received or for TCP there might even be disconnect/connect events. Once disconnected, the stream state cannot be "playing". Also meta data should be considered, if available.
It was and still is actually planned to improve the meta stream in regards of event handling, like adding ducking, mixing, corking. I think there are some open feature requests for this.

@toofar
Copy link
Author

toofar commented Jan 21, 2024

Thanks for the update! It's good to know what direction you are heading.

I guess this would be the most appropriate issue open atm for mixing options: #700, so I'll close this one and go give that one a +1
And an issue linked from that one already has a lot of similar discussion as this one: #1005

I maaay raise a PR at some point to try to make the TCP steam switch faster when it encounters an error or connects again. Maybe just call setState() then reset the check_state() loop. And maybe shove it behind an option in case other steams end up getting a bit hysterical with that setup. But not any time soon I'm afraid.

@toofar toofar closed this as completed Jan 21, 2024
@badaix badaix changed the title Assign multiple sources to one group Meta stream switches streams delayed Mar 26, 2024
@badaix badaix reopened this Mar 26, 2024
@badaix
Copy link
Owner

badaix commented Mar 26, 2024

Reopened with slightly changed title

@badaix
Copy link
Owner

badaix commented Mar 26, 2024

Switching streams should work instantly now in v0.28.0

@badaix badaix added bug next release fixed in develop branch and will be part of the next release labels Mar 26, 2024
@badaix badaix changed the title Meta stream switches streams delayed Meta stream switches streams with delay Mar 26, 2024
@toofar
Copy link
Author

toofar commented Mar 28, 2024

Thank you! I can confirm when testing (with the 0.28.0-beta.1-1 artifact) with a pipe and a tcp stream it switches between them immediately and with no audio artifacts. Also thanks for building all the packages for the release, makes it easy to test!

@badaix
Copy link
Owner

badaix commented Apr 19, 2024

Fixed in version 0.28.0

@badaix badaix closed this as completed Apr 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug feature request next release fixed in develop branch and will be part of the next release
Projects
None yet
Development

No branches or pull requests

4 participants