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