Closed tatokis closed 1 month ago
Thank you very much for taking the time to implement this! It is really appreciated.
I just tested it, and it seems to only work when Liquidsoap is started with PulseAudio not running.
2024/10/13 17:52:52 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:52:53 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:52:54 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:52:55 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:52:56 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:52:57 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:52:58 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:52:59 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
2024/10/13 17:53:00 [input.pulseaudio:2] Error while connecting to pulseaudio: Pulseaudio error: Connection refused
It keeps retrying every retry_delay seconds, and when the PulseAudio server finally starts up, it connects successfully.
However, if I run systemctl --user restart pipewire-pulse
while Liquidsoap is running, it 100%s a CPU core, keeps spamming the following ad nauseam, and never reconnects.
2024/10/13 17:55:31 [output_file:3] Source failed (no more tracks) stopping output...
2024/10/13 17:55:31 [input.pulseaudio:2] Error while reading from pulseaudio: Pulseaudio error: Connection terminated
2024/10/13 17:55:31 [output_file:3] Source failed (no more tracks) stopping output...
2024/10/13 17:55:31 [input.pulseaudio:2] Error while reading from pulseaudio: Pulseaudio error: Connection terminated
2024/10/13 17:55:31 [output_file:3] Source failed (no more tracks) stopping output...
2024/10/13 17:55:31 [input.pulseaudio:2] Error while reading from pulseaudio: Pulseaudio error: Connection terminated
2024/10/13 17:55:31 [output_file:3] Source failed (no more tracks) stopping output...
2024/10/13 17:55:31 [input.pulseaudio:2] Error while reading from pulseaudio: Pulseaudio error: Connection terminated
2024/10/13 17:55:31 [output_file:3] Source failed (no more tracks) stopping output...
2024/10/13 17:55:31 [input.pulseaudio:2] Error while reading from pulseaudio: Pulseaudio error: Connection terminated
2024/10/13 17:55:31 [output_file:3] Source failed (no more tracks) stopping output...
2024/10/13 17:55:31 [input.pulseaudio:2] Error while reading from pulseaudio: Pulseaudio error: Connection terminated
In short:
but
Not entirely sure this is the right way to fix this, thus not opening a PR, but it seems to work:
diff --git a/src/core/io/pulseaudio_io.ml b/src/core/io/pulseaudio_io.ml
index 7cb56d1ce..87aa0a03a 100644
--- a/src/core/io/pulseaudio_io.ml
+++ b/src/core/io/pulseaudio_io.ml
@@ -222,6 +222,7 @@ class input p =
(Printexc.to_string exn)
in
on_error error;
+ self#close_device;
Utils.log_exception ~log:self#log
~bt:(Printexc.raw_backtrace_to_string bt)
error;
EDIT: It doesn't actually fix the high CPU load, but it does stop the log spam and allows reconnecting at least.
Thanks for the follow-up. You're getting a different error than I get when restarting pulseaudio.
I pushed some fixes to mitigate your issue. Can you confirm if they help on your end?
With
2024/10/14 16:39:10 [main:3] Liquidsoap rolling-release-v2.3.x-7-g61d12cd+dev
it reconnects as expected. The high CPU usage unfortunately is still there though.
While not the same, perhaps you can reproduce it by running it as follows
PULSE_SERVER=unix:/dev/null liquidsoap test.liq
It seems like whatever is going wrong is causing the clock to run as fast as it possibly can, which explains the high CPU usage.
I tried adding a playlist fallback for when pulse fails, and it ends up decoding and pushing the audio to the stream much, much faster than realtime. Something like 30 minutes of buffered audio in the player within 60 wall clock seconds.
stream = input.pulseaudio(device="stream.monitor")
fallback_dj = playlist(mode="random", "/path/to/music/files")
out_stream = fallback(track_sensitive=false, replay_metadata=true, [stream, fallback_dj, sine()])
output.icecast(
%ffmpeg(format="ogg", %audio(
codec="libopus",
samplerate=48000,
b="128k",
vbr="constrained",
application="audio",
channels=2,
compression_level=10,
)),
host = icecast_host,
port = icecast_port,
password = icecast_pass,
mount = "/live.ogg",
send_icy_metadata=false,
out_stream
)
Thanks. I think you did put your finger on it. The code was mistakenly using the device and not the stream (which is the part that gets defined when connected) to decide if the source controls its own latency. We probably didn't notice because it was always connected before.
Just pushed a patch fixing this. Hopefully this helps.
Yup, that fixed it. Awesome!
Thank you :)
Description
Liquidsoap exits when the connection to the PulseAudio server is terminated.
Steps to reproduce
systemctl --user restart pulseaudio
orsystemctl --user restart pipewire-pulse
Expected behavior
The PulseAudio source should be marked as failed so that a fallback can take place, and other streams aren't affected. It should periodically attempt to reconnect to the server.
Liquidsoap version
Liquidsoap build config
Installation method
From distribution packages
Additional Info
No response