Add LiquidSoap script (in use as of 2025-07-20)
This commit is contained in:
324
server.ls
Normal file
324
server.ls
Normal file
@@ -0,0 +1,324 @@
|
||||
#!/usr/bin/liquidsoap
|
||||
set("log.file.path", "/tmp/lsl.txt")
|
||||
set("log.stdout", true)
|
||||
set("harbor.bind_addrs", ["127.0.0.1"])
|
||||
|
||||
|
||||
# Get next track dynamically [Each station]
|
||||
|
||||
def get_next_main() =
|
||||
uri = list.hd(default="", process.read.lines("uv run get_next_track.py main"))
|
||||
[request.create(uri)]
|
||||
end
|
||||
|
||||
def get_next_rock() =
|
||||
uri = list.hd(default="", process.read.lines("uv run get_next_track.py rock"))
|
||||
[request.create(uri)]
|
||||
end
|
||||
|
||||
def get_next_electronic() =
|
||||
uri = list.hd(default="", process.read.lines("uv run get_next_track.py electronic"))
|
||||
[request.create(uri)]
|
||||
end
|
||||
|
||||
def get_next_rap() =
|
||||
uri = list.hd(default="", process.read.lines("uv run get_next_track.py rap"))
|
||||
[request.create(uri)]
|
||||
end
|
||||
|
||||
def get_next_classical() =
|
||||
uri = list.hd(default="", process.read.lines("uv run get_next_track.py classical"))
|
||||
[request.create(uri)]
|
||||
end
|
||||
|
||||
def get_next_pop() =
|
||||
uri = list.hd(default="", process.read.lines("uv run get_next_track.py pop"))
|
||||
[request.create(uri)]
|
||||
end
|
||||
|
||||
|
||||
# Set up queues [Each station]
|
||||
|
||||
main_list = request.dynamic.list(
|
||||
id="requests",
|
||||
get_next_main,
|
||||
prefetch=0
|
||||
)
|
||||
|
||||
|
||||
rock_list = request.dynamic.list(
|
||||
id="rock_requests",
|
||||
get_next_rock,
|
||||
prefetch=0
|
||||
)
|
||||
|
||||
electronic_list = request.dynamic.list(
|
||||
id="electronic_requests",
|
||||
get_next_electronic,
|
||||
prefetch=0
|
||||
)
|
||||
|
||||
rap_list = request.dynamic.list(
|
||||
id="rap_requests",
|
||||
get_next_rap,
|
||||
prefetch=0
|
||||
)
|
||||
|
||||
classical_list = request.dynamic.list(
|
||||
id="classical_requests",
|
||||
get_next_classical,
|
||||
prefetch=0
|
||||
)
|
||||
|
||||
pop_list = request.dynamic.list(
|
||||
id="pop_requests",
|
||||
get_next_pop,
|
||||
prefetch=0
|
||||
)
|
||||
|
||||
|
||||
# Standard
|
||||
|
||||
silence = single("/home/kyle/ls/silence.ogg")
|
||||
|
||||
# Queue [Each station]
|
||||
|
||||
def main_queue(remaining, _) =
|
||||
log("MAIN: Queueing with #{remaining} seconds remaining")
|
||||
if not main_list.fetch() then
|
||||
log("Fetching next query failed")
|
||||
end
|
||||
end
|
||||
|
||||
def rock_queue(remaining, _) =
|
||||
log("ROCK: Queueing with #{remaining} seconds remaining")
|
||||
if not rock_list.fetch() then
|
||||
log("Fetching next query failed")
|
||||
end
|
||||
end
|
||||
|
||||
def electronic_queue(remaining, _) =
|
||||
log("ELECTRONIC: Queueing with #{remaining} seconds remaining")
|
||||
if not electronic_list.fetch() then
|
||||
log("Fetching next query failed")
|
||||
end
|
||||
end
|
||||
|
||||
def rap_queue(remaining, _) =
|
||||
log("RAP: Queueing with #{remaining} seconds remaining")
|
||||
if not rap_list.fetch() then
|
||||
log("Fetching next query failed")
|
||||
end
|
||||
end
|
||||
|
||||
def classical_queue(remaining, _) =
|
||||
log("CLASSICAL: Queueing with #{remaining} seconds remaining")
|
||||
if not classical_list.fetch() then
|
||||
log("Fetching next query failed")
|
||||
end
|
||||
end
|
||||
|
||||
def pop_queue(remaining, _) =
|
||||
log("POP: Queueing with #{remaining} seconds remaining")
|
||||
if not pop_list.fetch() then
|
||||
log("Fetching next query failed")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
# Initial fetch [Each station]
|
||||
|
||||
main_list.fetch()
|
||||
rock_list.fetch()
|
||||
electronic_list.fetch()
|
||||
rap_list.fetch()
|
||||
classical_list.fetch()
|
||||
pop_list.fetch()
|
||||
|
||||
# Source setup [Each station]
|
||||
|
||||
main_source = source.on_end(delay=1.0, main_list, main_queue)
|
||||
rock_source = source.on_end(delay=1.0, rock_list, rock_queue)
|
||||
electronic_source = source.on_end(delay=1.0, electronic_list, electronic_queue)
|
||||
rap_source = source.on_end(delay=1.0, rap_list, rap_queue)
|
||||
classical_source = source.on_end(delay=1.0, classical_list, classical_queue)
|
||||
pop_source = source.on_end(delay=1.0, pop_list, pop_queue)
|
||||
|
||||
all_tracks_main = fallback(track_sensitive=false, [main_source, silence])
|
||||
all_tracks_rock = fallback(track_sensitive=false, [rock_source, silence])
|
||||
all_tracks_electronic = fallback(track_sensitive=false, [electronic_source, silence])
|
||||
all_tracks_rap = fallback(track_sensitive=false, [rap_source, silence])
|
||||
all_tracks_classical = fallback(track_sensitive=false, [classical_source, silence])
|
||||
all_tracks_pop = fallback(track_sensitive=false, [pop_source, silence])
|
||||
|
||||
# HLS Setup [Standard]
|
||||
|
||||
aac_lofi =
|
||||
%ffmpeg(format = "mpegts", %audio(codec = "aac", channels = 2, ar = 44100))
|
||||
|
||||
aac_midfi =
|
||||
%ffmpeg(
|
||||
format = "mpegts",
|
||||
%audio(codec = "aac", channels = 2, ar = 44100, b = "96k")
|
||||
)
|
||||
|
||||
aac_hifi =
|
||||
%ffmpeg(
|
||||
format = "mpegts",
|
||||
%audio(codec = "aac", channels = 2, ar = 44100, b = "192k")
|
||||
)
|
||||
|
||||
streams =
|
||||
[("aac_lofi", aac_lofi), ("aac_midfi", aac_midfi), ("aac_hifi", aac_hifi)]
|
||||
|
||||
|
||||
# HLS Outputs [Each station]
|
||||
|
||||
output.file.hls(
|
||||
playlist="main.m3u8",
|
||||
segment_duration=1.0,
|
||||
segments=3,
|
||||
segments_overhead=4,
|
||||
persist_at="/tmp/hls/state.config",
|
||||
"/tmp/hls/main",
|
||||
streams,
|
||||
mksafe(main_source)
|
||||
)
|
||||
|
||||
output.file.hls(
|
||||
playlist="rock.m3u8",
|
||||
segment_duration=1.0,
|
||||
segments=3,
|
||||
segments_overhead=4,
|
||||
persist_at="/tmp/hls/rock/state.config",
|
||||
"/tmp/hls/rock",
|
||||
streams,
|
||||
mksafe(rock_source)
|
||||
)
|
||||
|
||||
output.file.hls(
|
||||
playlist="electronic.m3u8",
|
||||
segment_duration=1.0,
|
||||
segments=3,
|
||||
segments_overhead=4,
|
||||
persist_at="/tmp/hls/electronic/state.config",
|
||||
"/tmp/hls/electronic",
|
||||
streams,
|
||||
mksafe(electronic_source)
|
||||
)
|
||||
|
||||
output.file.hls(
|
||||
playlist="rap.m3u8",
|
||||
segment_duration=1.0,
|
||||
segments=3,
|
||||
segments_overhead=4,
|
||||
persist_at="/tmp/hls/rap_state.config",
|
||||
"/tmp/hls/rap",
|
||||
streams,
|
||||
mksafe(rap_source)
|
||||
)
|
||||
|
||||
output.file.hls(
|
||||
playlist="classical.m3u8",
|
||||
segment_duration=1.0,
|
||||
segments=3,
|
||||
segments_overhead=4,
|
||||
persist_at="/tmp/hls/classical_state.config",
|
||||
"/tmp/hls/classical",
|
||||
streams,
|
||||
mksafe(classical_source)
|
||||
)
|
||||
|
||||
output.file.hls(
|
||||
playlist="pop.m3u8",
|
||||
segment_duration=1.0,
|
||||
segments=3,
|
||||
segments_overhead=4,
|
||||
persist_at="/tmp/hls/pop_state.config",
|
||||
"/tmp/hls/pop",
|
||||
streams,
|
||||
mksafe(pop_source)
|
||||
)
|
||||
|
||||
|
||||
def get_next_http(~protocol,~data,~headers,uri) =
|
||||
log("Station from POST Data: #{data}")
|
||||
if data == "main" then
|
||||
_req = source.skip(all_tracks_main)
|
||||
elsif data == "rock" then
|
||||
_req = source.skip(all_tracks_rock)
|
||||
elsif data == "electronic" then
|
||||
_req = source.skip(all_tracks_electronic)
|
||||
elsif data == "rap" then
|
||||
_req = source.skip(all_tracks_rap)
|
||||
elsif data == "classical" then
|
||||
_req = source.skip(all_tracks_classical)
|
||||
elsif data == "pop" then
|
||||
_req = source.skip(all_tracks_pop)
|
||||
end
|
||||
http.response(
|
||||
protocol=protocol,
|
||||
code=200,
|
||||
data="OK #{data}"
|
||||
)
|
||||
end
|
||||
|
||||
harbor.http.register(port=29000, method="POST", "/next", get_next_http)
|
||||
|
||||
# Icecast Outputs [Each station]
|
||||
|
||||
output.icecast(
|
||||
%ogg(%vorbis(quality=1.0, samplerate=44100)),
|
||||
host="localhost", port=9992,
|
||||
user="redacted", password="redacted",
|
||||
mount="sfm.ogg",
|
||||
fallible=false,
|
||||
all_tracks_main
|
||||
)
|
||||
|
||||
output.icecast(
|
||||
%ogg(%vorbis(quality=1.0, samplerate=44100)),
|
||||
host="localhost", port=9992,
|
||||
user="redacted", password="redacted",
|
||||
mount="rock.ogg",
|
||||
fallible=false,
|
||||
all_tracks_rock
|
||||
)
|
||||
|
||||
output.icecast(
|
||||
%ogg(%vorbis(quality=1.0, samplerate=44100)),
|
||||
host="localhost", port=9992,
|
||||
user="redacted", password="redacted",
|
||||
mount="electronic.ogg",
|
||||
fallible=false,
|
||||
all_tracks_electronic
|
||||
)
|
||||
|
||||
|
||||
output.icecast(
|
||||
%ogg(%vorbis(quality=1.0, samplerate=44100)),
|
||||
host="localhost", port=9992,
|
||||
user="redacted", password="redacted",
|
||||
mount="rap.ogg",
|
||||
fallible=false,
|
||||
all_tracks_rap
|
||||
)
|
||||
|
||||
output.icecast(
|
||||
%ogg(%vorbis(quality=1.0, samplerate=44100)),
|
||||
host="localhost", port=9992,
|
||||
user="redacted", password="redacted",
|
||||
mount="classical.ogg",
|
||||
fallible=false,
|
||||
all_tracks_classical
|
||||
)
|
||||
|
||||
output.icecast(
|
||||
%ogg(%vorbis(quality=1.0, samplerate=44100)),
|
||||
host="localhost", port=9992,
|
||||
user="redacted", password="redacted",
|
||||
mount="pop.ogg",
|
||||
fallible=false,
|
||||
all_tracks_pop
|
||||
)
|
Reference in New Issue
Block a user