#!/usr/bin/liquidsoap # Radio Susan — pre-generated daily playlist # Tracks, announcements, and jingles are all baked into playlist.m3u # Liquidsoap just plays it sequentially. %include "secrets.liq" set("log.file.path", "/var/lib/radio/radio.log") set("log.level", 3) set("server.telnet", true) set("server.telnet.port", 1234) state_file = "/var/lib/radio/track_state.json" playlist_file = "/var/lib/radio/playlist.m3u" # Primary source: pre-generated daily playlist music = playlist( id="daily_playlist", mode="normal", reload=3600, reload_mode="watch", playlist_file ) # Fallback 1: live DJ (per-track) def get_next_track() = result = list.hd(default="", process.read.lines("/usr/bin/python3 /var/lib/radio/radio_dj.py")) if result != "" then log("DJ fallback picked: #{result}") request.create(result) else log("DJ returned nothing") null() end end dj_fallback = request.dynamic(id="dj_fallback", get_next_track) # Fallback 2: static random playlist (last resort) random_fallback = playlist( id="random_fallback", mode="randomize", reload=3600, "/var/lib/radio/playlists/all.m3u" ) # Chain: playlist → DJ → random radio = fallback(id="Radio_Susan", track_sensitive=true, [music, dj_fallback, random_fallback]) # Write track metadata to state file on each new track radio = source.on_track(radio, fun(m) -> begin artist = m["artist"] title = m["title"] data = '{"artist":"#{artist}","title":"#{title}"}' ignore(file.write(data=data, state_file)) log("Now playing: #{artist} - #{title}") end) radio = mksafe(radio) output.icecast( %mp3(bitrate=192), host="localhost", port=8910, password=icecast_password, mount="/stream", name="Radio Susan", description="Personal radio station", genre="Eclectic", url="https://radio.jihakuz.xyz", radio )