This repository has no description
3.5 kB
112 lines
1log.stdout.set(true)
2
3# use yt-dlp
4settings.protocol.youtube_dl.path.set("yt-dlp")
5
6## functions
7
8def stringify_attrs(attrs) =
9 let json.stringify out = (attrs : [(string * string)] as json.object)
10 out
11end
12
13def filter_music(req) =
14 filename = request.filename(req)
15 if string.match(pattern = '.*/\\.graveyard/.*', filename) then
16 false
17 else
18 true
19 end
20end
21
22def queue_contents(q) =
23 list.map(fun (req) -> request.uri(req), q)
24end
25## main
26
27env = environment()
28port = string.to_int(env["RADIO_PORT"], default = 8000)
29
30all_music = playlist(env["MUSIC"], check_next = filter_music)
31wishlist = request.queue()
32tracks = fallback(track_sensitive = true, [wishlist, all_music])
33tracks = blank.eat(tracks)
34
35last_metadata = ref([])
36def on_metadata(m) =
37 last_metadata := m
38 print("changing tracks")
39 out = process.read(env["HOOK_TRACK_CHANGE"], env = m, timeout = 5.0)
40 print(out)
41end
42tracks.on_metadata(on_metadata)
43
44# some nice effects
45music = crossfade(tracks)
46music = mksafe(music)
47music = normalize(music)
48
49news = request.queue()
50radio = smooth_add(normal = music, special = amplify(1.5, news))
51
52if string.length(env["ICECAST_HOST"]) > 0 then
53 output.icecast(host = env["ICECAST_HOST"], mount = '/music.ogg', password = 'hackme', %vorbis(quality = 1), music)
54 output.icecast(host = env["ICECAST_HOST"], mount = '/music.mp3', password = 'hackme', %mp3.vbr(), music)
55 output.icecast(host = env["ICECAST_HOST"], mount = '/music.opus', password = 'hackme', %opus(bitrate = 128), music)
56
57 output.icecast(host = env["ICECAST_HOST"], mount = '/radio.ogg', password = 'hackme', %vorbis(quality = 1), radio)
58 output.icecast(host = env["ICECAST_HOST"], mount = '/radio.mp3', password = 'hackme', %mp3.vbr(), radio)
59 output.icecast(host = env["ICECAST_HOST"], mount = '/radio.opus', password = 'hackme', %opus(bitrate = 128), radio)
60else
61 output(fallible = true, buffer(radio))
62end
63
64interactive.harbor(port = port)
65
66def current(~protocol, ~headers, ~data, uri) =
67 http.response(content_type = "application/json", data = stringify_attrs(
68 !last_metadata
69 ))
70end
71harbor.http.register("/current", port = port, current)
72
73def skip(~protocol, ~headers, ~data, uri) =
74 tracks.skip()
75 http.response(content_type = "application/json", data = stringify_attrs(
76 !last_metadata
77 ))
78end
79harbor.http.register("/skip", method = "POST", port = port, skip)
80
81def all_tracks(~protocol, ~headers, ~data, uri) =
82 http.response(content_type = "application/json", data = json.stringify(
83 all_music.remaining_files()
84 ))
85end
86harbor.http.register("/all_tracks", port = port, all_tracks)
87
88def wish_track(~protocol, ~headers, ~data, uri) =
89 # disallow process:
90 if string.match(pattern = '^process:', data) then
91 http.response(code = 400)
92 else
93 # TODO report errors back
94 wish = request.create(data)
95 wishlist.push(wish)
96 http.response(content_type = "application/json", data = "ok")
97 end
98end
99harbor.http.register("/wish", method = "POST", port = port, wish_track)
100
101def wish_tracklist(~protocol, ~headers, ~data, uri) =
102 http.response(content_type = "application/json", data = json.stringify(
103 queue_contents(wishlist.queue())
104 ))
105end
106harbor.http.register("/wish", port = port, wish_tracklist)
107
108def newsshow(~protocol, ~headers, ~data, uri) =
109 news.push(request.create("http://c.r/news.ogg"))
110 http.response(content_type = "application/json", data = "ok")
111end
112harbor.http.register("/newsshow", method = "POST", port = port, newsshow)