summaryrefslogtreecommitdiffstats
path: root/lass/2configs/services/radio/radio.liq
blob: 1366287a7b7399586453d9bf84b23111085716cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
log.stdout.set(true)

# use yt-dlp
settings.protocol.youtube_dl.path.set("yt-dlp")

## functions

def stringify_attrs(attrs) =
  let json.stringify out = (attrs : [(string * string)] as json.object)
  out
end

def filter_music(req) =
  filename = request.filename(req)
  if string.match(pattern = '.*/\\.graveyard/.*', filename) then
    false
  else
    true
  end
end

def queue_contents(q) =
  list.map(fun (req) -> request.uri(req), q)
end
## main

env = environment()
port = string.to_int(env["RADIO_PORT"], default = 8000)

all_music = playlist(env["MUSIC"], check_next = filter_music)
wishlist = request.queue()
tracks = fallback(track_sensitive = true, [wishlist, all_music])
tracks = blank.eat(tracks)

last_metadata = ref([])
def on_metadata(m) =
  last_metadata := m
  print("changing tracks")
  out = process.read(env["HOOK_TRACK_CHANGE"], env = m, timeout = 5.0)
  print(out)
end
tracks.on_metadata(on_metadata)

# some nice effects
music = crossfade(tracks)
music = mksafe(music)
music = normalize(music)

news = request.queue()
radio = smooth_add(normal = music, special = amplify(1.5, news))

if string.length(env["ICECAST_HOST"]) > 0 then
  output.icecast(host = env["ICECAST_HOST"], mount = '/music.ogg', password = 'hackme', %vorbis(quality = 1), music)
  output.icecast(host = env["ICECAST_HOST"], mount = '/music.mp3', password = 'hackme', %mp3.vbr(), music)
  output.icecast(host = env["ICECAST_HOST"], mount = '/music.opus', password = 'hackme', %opus(bitrate = 128), music)

  output.icecast(host = env["ICECAST_HOST"], mount = '/radio.ogg', password = 'hackme', %vorbis(quality = 1), radio)
  output.icecast(host = env["ICECAST_HOST"], mount = '/radio.mp3', password = 'hackme', %mp3.vbr(), radio)
  output.icecast(host = env["ICECAST_HOST"], mount = '/radio.opus', password = 'hackme', %opus(bitrate = 128), radio)
else
  output(fallible = true, buffer(radio))
end

interactive.harbor(port = port)

def current(~protocol, ~headers, ~data, uri) =
  http.response(content_type = "application/json", data = stringify_attrs(
    !last_metadata
  ))
end
harbor.http.register("/current", port = port, current)

def skip(~protocol, ~headers, ~data, uri) =
  tracks.skip()
  http.response(content_type = "application/json", data = stringify_attrs(
    !last_metadata
  ))
end
harbor.http.register("/skip", method = "POST", port = port, skip)

def all_tracks(~protocol, ~headers, ~data, uri) =
  http.response(content_type = "application/json", data = json.stringify(
    all_music.remaining_files()
  ))
end
harbor.http.register("/all_tracks", port = port, all_tracks)

def wish_track(~protocol, ~headers, ~data, uri) =
  # disallow process:
  if string.match(pattern = '^process:', data) then
    http.response(code = 400)
  else
    # TODO report errors back
    wish = request.create(data)
    wishlist.push(wish)
    http.response(content_type = "application/json", data = "ok")
  end
end
harbor.http.register("/wish", method = "POST", port = port, wish_track)

def wish_tracklist(~protocol, ~headers, ~data, uri) =
  http.response(content_type = "application/json", data = json.stringify(
    queue_contents(wishlist.queue())
  ))
end
harbor.http.register("/wish", port = port, wish_tracklist)

def newsshow(~protocol, ~headers, ~data, uri) =
  news.push(request.create("http://c.r/news.ogg"))
  http.response(content_type = "application/json", data = "ok")
end
harbor.http.register("/newsshow", method = "POST", port = port, newsshow)