diff --git a/config/liquidsoap.liq b/config/liquidsoap.liq index 3141443..ebc547c 100644 --- a/config/liquidsoap.liq +++ b/config/liquidsoap.liq @@ -6,6 +6,46 @@ settings.log.level.set(3) source_pw = environment.get(default="", "SOURCE_PW") +# deck-shuffle: full shuffle once, hand out in order, reshuffle on exhaustion. +# returns a record with .source (request.dynamic) and .peek (returns next N filenames). +def make_deck(dir) = + files = ref([]) + cursor = ref(0) + + def reload_and_shuffle() = + files := list.shuffle(file.ls(dir, recursive=true, absolute=true)) + cursor := 0 + end + + def next_file() = + if !cursor >= list.length(!files) then reload_and_shuffle() end + f = list.nth(default="", !files, !cursor) + cursor := !cursor + 1 + f + end + + def next_request() = + f = next_file() + if f == "" then null() else request.create(f) end + end + + def peek(n) = + needed = !cursor + n + if needed > list.length(!files) and list.length(!files) > 0 then + # would exhaust the deck during peek; not worth pre-reshuffling. + # return whatever's left, the caller pads. + () + end + list.init( + min(n, list.length(!files) - !cursor), + fun(i) -> list.nth(default="", !files, !cursor + i) + ) + end + + reload_and_shuffle() + { source = request.dynamic(next_request), peek = peek } +end + def emit_now_playing(station, m) = filename = m["filename"] if filename != "" then @@ -68,13 +108,10 @@ def append_history(station, m) = end # === station: minecraft === -minecraft = playlist( - reload_mode="watch", - mode="randomize", - "/library/minecraft/tracks" -) +minecraft_deck = make_deck("/library/minecraft/tracks") +minecraft = minecraft_deck.source minecraft.on_track(fun (m) -> begin - emit_now_playing("minecraft", m) + emit_now_playing("minecraft", m, minecraft_deck.peek(4)) append_history("minecraft", m) end) minecraft = crossfade(minecraft)