Files
radio-bullshit/radio.liq

171 lines
3.9 KiB
Plaintext

#!/usr/bin/liquidsoap
# Radio Bullshit - Liquidsoap Configuration
# ============================================================================
# CONFIGURATION
# ============================================================================
# Get environment variables with defaults
hostname = environment.get(default="localhost", "HOSTNAME")
port = int_of_string(environment.get(default="8000", "PORT"))
folder_songs = "/songs"
folder_jingles = "/jingles"
folder_air_support = "/air-support"
# Log configuration
log.file.path := "/var/log/liquidsoap/radio-bullshit.log"
log.level := 3
# ============================================================================
# SOURCES
# ============================================================================
# Songs playlist - reload every 60 seconds to pick up new downloads
songs = playlist(
mode="randomize",
reload=60,
reload_mode="watch",
"#{folder_songs}/playlist.pls"
)
# Jingles playlist
jingles = playlist(
mode="randomize",
reload=60,
reload_mode="watch",
"#{folder_jingles}/playlist.pls"
)
# Air support (fallback audio when nothing else is available)
air_support = mksafe(
playlist(
mode="randomize",
reload_mode="watch",
"#{folder_air_support}/playlist.pls"
)
)
# ============================================================================
# METADATA UPDATE
# ============================================================================
def enrich_metadata(folder, m)
entry = process.read("/opt/met_extractor.py #{folder}/playlist.json '#{metadata.filename(m)}'")
let json.parse (entry :
{
index: int?,
file: string?,
title: string?,
duration: float?
}
) = entry
[("title", "#{entry.title}")]
end
songs = map_metadata(
fun (m) -> begin
enrich_metadata(folder_songs, m)
end,
songs
)
jingles = map_metadata(
fun (m) -> begin
enrich_metadata(folder_jingles, m)
end,
jingles
)
air_support = map_metadata(
fun (m) -> begin
enrich_metadata(folder_air_support, m)
end,
air_support
)
# ============================================================================
# ALTERNATING LOGIC
# ============================================================================
# Alternate between songs and jingles: play 1 jingle, then 4 songs
# This creates a pattern: jingle, song, jingle, ...
radio = rotate(
weights=[1, 1],
[jingles, songs]
)
# Add fallback to air support in case of errors
radio = fallback(
track_sensitive=false,
[radio, air_support]
)
# Normalize audio levels for consistent volume
# radio = normalize(radio)
# ============================================================================
# OUTPUTS
# ============================================================================
# Built-in HTTP server (replaces Icecast)
# Serves the stream directly via Liquidsoap's Harbor server
output.harbor(
%mp3(bitrate=128, samplerate=44100),
port=port,
mount="/radio-bullshit",
url="http://#{hostname}:#{port}",
radio
)
# Enable built-in HTTP server for stream and status
settings.harbor.bind_addrs := ["0.0.0.0"]
# Add static folder
harbor.http.static(
port=port,
path="/static/",
content_type=
fun (path) -> begin
file.mime.magic(path)
end,
"/var/www/static"
)
# Add index file
harbor.http.register(
port=port,
method="GET",
"/",
fun (_, response) -> begin
response.html(
file.contents("/var/www/index.html")
)
end
)
# Serve M3U playlist file
harbor.http.register(
port=port,
method="GET",
"/radio-bullshit.m3u",
fun (_, response) -> begin
m3u = "http://#{hostname}:#{port}/radio-bullshit"
response.content_type("audio/x-mpegurl")
response.data(m3u)
end
)
# Status endpoint (JSON)
harbor.http.register(
port=port,
method="GET",
"/status.json",
fun (_, response) -> begin
response.json(radio.last_metadata() ?? [("status", "down")])
end
)
log("Radio Bullshit is now streaming on http://#{hostname}:#{port}/radio-bullshit")