From a83d063814609555f53708b56c7f915e24ff7e16 Mon Sep 17 00:00:00 2001 From: devilreef Date: Thu, 30 Apr 2026 19:24:46 +0600 Subject: [PATCH] feat(liquidsoap): filename-based fallback when title/album tags are empty --- config/liquidsoap.liq | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/config/liquidsoap.liq b/config/liquidsoap.liq index 911732e..4ad78d4 100644 --- a/config/liquidsoap.liq +++ b/config/liquidsoap.liq @@ -56,6 +56,27 @@ def make_deck(dir) = { source = request.dynamic(next_request), peek = peek } end +# filename-based fallbacks for tracks with empty embedded tags. +# strips leading "08. " / "12 - " etc. from the file stem. +def filename_title(filename) = + base = path.basename(filename) + ext = file.extension(leading_dot=true, base) + stem = + if ext != "" then + string.sub(base, start=0, length=string.length(base) - string.length(ext)) + else base end + re = regexp("^[0-9]+[. \\-]+ *") + re.replace(fun(_) -> "", stem) +end + +def filename_album(filename) = + path.basename(path.dirname(filename)) +end + +def or_else(s, fallback) = + if s == "" then fallback else s end +end + # walk up from the audio file to find cover.{jpg,png,webp}. # falls back to /cover.* (one level above tracks/). def cover_for(filename) = @@ -85,9 +106,9 @@ def track_meta_json(filename) = request.destroy(r) d = null.get(default=-1., request.duration(filename)) obj = json() - obj.add("title", m["title"]) + obj.add("title", or_else(m["title"], filename_title(filename))) obj.add("artist", m["artist"]) - obj.add("album", m["album"]) + obj.add("album", or_else(m["album"], filename_album(filename))) obj.add("duration", if d > 0. then string(int_of_float(d)) else "" end) obj.add("cover_path", cover_for(filename)) obj @@ -108,8 +129,8 @@ def emit_now_playing(station, m, upcoming) = payload = json() payload.add("station", station) payload.add("artist", m["artist"]) - payload.add("title", m["title"]) - payload.add("album", m["album"]) + payload.add("title", or_else(m["title"], filename_title(filename))) + payload.add("album", or_else(m["album"], filename_album(filename))) payload.add("filename", filename) payload.add("duration", dur_str) payload.add("started_at", string(int_of_float(time())))