171 lines
3.9 KiB
Plaintext
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")
|