radio: /srv/betoniarka paths, in-container Icecast, drop ffmpeg.pref

Per review of the first radio-container cut:

- radio_conjurer.liq: replace the cargo-culted /home/pi/Conjurer and
  /home/pi/MediaFolder paths with the container layout -
  /srv/betoniarka/data (playlists, script.params, persistence/radio logs),
  /srv/betoniarka/music (library + emergency track) and
  /srv/betoniarka/secrets/icecast_credentials.json;
  interactive.persistent now uses an absolute path;
  output.icecast targets host="localhost" (icecast lives in the container)
- Icecast2 now runs INSIDE the radio container: entrypoint renders
  /etc/icecast2/icecast.xml from docker/icecast.xml.tpl, filling
  source/admin/relay passwords from the secret provisioned at install time
  (same pattern as the bot's netrc); optional admin_password/relay_password
  fields default to password; icecast starts as its unprivileged user;
  port 8000 exposed for listeners; extra_hosts hack removed
- compose.radio.yaml: same-path mounts for /srv/betoniarka/{data,music,secrets}
- ffmpeg.pref removed from the repo (the pin only mattered against the
  RPi OS repo; bookworm ships the right FFmpeg 5.x natively) - verdict
  preserved in the docs and the legacy installer note updated
- docs: updated radio section (volumes, secret provisioning, wire-up)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Michal Tuszowski
2026-07-08 11:32:48 +02:00
committed by Michał Tuszowski
parent ebc73c16d4
commit fcb03e304c
8 changed files with 162 additions and 64 deletions
+14 -14
View File
@@ -1,16 +1,16 @@
# FILEPATH: /home/mtuszowski/conjurer/conjurer_musician/radio_conjurer.liq
# Radio Conjurer - Liquidsoap script (containerised paths: /srv/betoniarka/*)
# This script sets up a Liquidsoap radio stream with various features and configurations.
# Load icecast credentials from a JSON file
let json.parse credentials = file.contents("/home/pi/Conjurer/icecast_credentials.json")
let json.parse credentials = file.contents("/srv/betoniarka/secrets/icecast_credentials.json")
# Enable replaygain metadata processing
enable_replaygain_metadata()
# Set up a playlog for tracking played tracks
l = playlog(duration = 72000.0, persistency="/home/pi/Conjurer/persistence.log")
l = playlog(duration = 72000.0, persistency="/srv/betoniarka/data/persistence.log")
# Function to check if a track can be played based on its metadata
def check(r)
@@ -25,20 +25,20 @@ def check(r)
end
# Define playlists to be used in the stream
s1 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/all_playlist.playlist"))
s2 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/priority_queue.playlist"))
s3 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/hit.playlist"))
s1 = replaygain(playlist(reload_mode="watch", check_next=check, "/srv/betoniarka/data/all_playlist.playlist"))
s2 = replaygain(playlist(reload_mode="watch", check_next=check, "/srv/betoniarka/data/priority_queue.playlist"))
s3 = replaygain(playlist(reload_mode="watch", check_next=check, "/srv/betoniarka/data/hit.playlist"))
# Create a request queue for user-generated requests
requests_queue = request.queue()
# Function to process the request queue and add new requests
def queue_processing()
text=file.lines("/home/pi/Conjurer/request.playlist")
text=file.lines("/srv/betoniarka/data/request.playlist")
if text != [] then
list.iter(fun(item) -> requests_queue.push.uri(item), text)
file.remove("/home/pi/Conjurer/request.playlist")
f = file.open("/home/pi/Conjurer/request.playlist", create=true)
file.remove("/srv/betoniarka/data/request.playlist")
f = file.open("/srv/betoniarka/data/request.playlist", create=true)
f.close()
end
end
@@ -63,7 +63,7 @@ end
s4 = random(id="randomizer", weights=[2, 3, 5], [s1, s2, s3])
# Load jingles playlist
jingles = (playlist(reload_mode="watch", "/home/pi/Conjurer/jingles.playlist"))
jingles = (playlist(reload_mode="watch", "/srv/betoniarka/data/jingles.playlist"))
# Create the main stream with random playlist and jingles
s = rotate(id="randomizer", weights=[10, 1], [s4, jingles])
@@ -111,7 +111,7 @@ s=switch(track_sensitive=true,
# Configure logging settings
log_to_stdout = true
log_to_file = true
logpath = "/home/pi/Conjurer/radio_log.log"
logpath = "/srv/betoniarka/data/radio_log.log"
loglevel = 3
set("log.stdout", log_to_stdout)
set("log.level", loglevel)
@@ -120,7 +120,7 @@ set("log.level", loglevel)
set("log.file", log_to_file)
set("log.file.path", logpath)
# Set up emergency fallback track
emergency = single("/home/pi/MediaFolder/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3")
emergency = single("/srv/betoniarka/music/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3")
radio = fallback(id="switcher2", track_sensitive=false, [s, emergency])
# Set up an interactive control for skipping tracks
@@ -150,11 +150,11 @@ thread.run(every=15., check_skip)
# Enable persistent script parameters
interactive.persistent("script.params")
interactive.persistent("/srv/betoniarka/data/script.params")
# Configure output formats and destinations
output.icecast(%mp3, host="radio", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio)
output.icecast(%mp3, host="localhost", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio)
output.pulseaudio(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