radio: stop a dead PulseAudio from crash-looping the whole radio
CI / compile (pull_request) Successful in 6s
CI / unit (pull_request) Successful in 23s
CI / integration (pull_request) Successful in 24s
build / build (push) Successful in 13m5s
CI / compile (push) Successful in 5s
CI / unit (push) Successful in 22s
CI / integration (push) Failing after 24s
CI / compile (pull_request) Successful in 6s
CI / unit (pull_request) Successful in 23s
CI / integration (pull_request) Successful in 24s
build / build (push) Successful in 13m5s
CI / compile (push) Successful in 5s
CI / unit (push) Successful in 22s
CI / integration (push) Failing after 24s
Field report: the radio died and kept restarting. The log chain is unambiguous - "Daemon startup failed" (pulse), then Connection refused on input.pulseaudio_0 / buffer.consumer_0 / pulse_out, then "Shutdown started!", then round again. Three fixes: * Clear stale pulse runtime state before starting the daemon. /run is part of the container's writable layer, so "docker restart" - and the loop that restart:unless-stopped produces - preserves /run/pulse/pid from the killed daemon; the next start then refuses with "Daemon startup failed", which is what makes the loop self-sustaining. We only remove it when no pulseaudio process is actually alive. * When pulse still won't start, say so loudly and explain the consequence and the way out (Icecast needs no sound device; comment the pulse tor out), instead of a one-line WARNING that gets lost above the traceback. * output.pulseaudio(fallible=true): the local monitor output can now fail without failing its clock and tearing down the radio. The mic input stays a hard dependency - documented inline, since removing it changes audio behaviour and cannot be verified without a liquidsoap runtime. Also: RADIO_FORCE_SCRIPT=1 re-seeds radio_conjurer.liq from the image (keeping a .bak). The live script is deliberately never overwritten so hand edits win - but that also means image fixes never reached volumes seeded long ago, which is why a running radio can still hold a stale script. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #23.
This commit is contained in:
@@ -155,7 +155,13 @@ interactive.persistent("/srv/betoniarka/data/script.params")
|
||||
# Configure output formats and destinations
|
||||
|
||||
output.icecast(%mp3, host="localhost", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio)
|
||||
output.pulseaudio(radio)
|
||||
# Local monitor output. fallible=true so a dead or missing pulse daemon degrades
|
||||
# to "no monitor" instead of failing its clock and taking the whole radio down
|
||||
# with it ("Shutdown started!"). The stream that actually matters is the Icecast
|
||||
# one above, which needs no sound device at all.
|
||||
# NOTE: input.pulseaudio() (the mic, further up) is still a HARD dependency - on
|
||||
# a headless container with no capture device, comment BOTH of them out.
|
||||
output.pulseaudio(fallible=true, radio)
|
||||
#output.file.hls("/tmp/hls", [("mp3-low", %mp3(bitrate=96)), ("mp3-hi", %mp3(bitrate=160))], radio)
|
||||
# Uncomment the following lines to enable additional output formats
|
||||
# output.icecast(%opus, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="opus-stream", radio)
|
||||
|
||||
Reference in New Issue
Block a user