# Logging settings settings.log.file.path := "/tmp/radio.log" settings.log.stdout := true settings.log.level := 2 # Enable Telnet server for admin controls (like skipping) settings.server.telnet := true settings.server.telnet.bind_addr := "0.0.0.0" settings.server.telnet.port := 1234 # Fetch track dynamically from our Python API def get_next() = # Liquidsoap http.get returns the body as a string directly response = http.get("http://127.0.0.1:8080/next") url = string.trim(response) if url == "" then print("WARNING: /next returned empty. Adding silence fallback.") request.create("annotate:duration=5.0:silence") else print("Next track queued: #{url}") request.create(url) end end # Define the source radio = request.dynamic(id="navifm_queue", get_next) # Register a manual telnet command to skip the track since request.dynamic doesn't expose one by default server.register("navifm_queue.skip", fun(_) -> begin source.skip(radio); "Done" end) # Notify backend precisely when a new track starts def on_new_track(meta) = let title = meta["title"] let artist = meta["artist"] let url = "http://127.0.0.1:8080/api/internal/track_changed?title=#{url.encode(title)}&artist=#{url.encode(artist)}" ignore(http.get(url)) end radio.on_track(on_new_track) # Precise static amplification based on LUFS (overridden by liq_amplify metadata) radio = amplify(1., radio) # Smooth crossfade between tracks radio = crossfade(smart=true, duration=4.0, fade_out=2.0, fade_in=2.0, radio) # Ensure the stream doesn't crash if the source is unavailable (apply right before output) radio = mksafe(radio) # Retrieve icecast password from environment variable icecast_pwd = environment.get(default="hackme", "ICECAST_PASSWORD") # Output stream to Icecast output.icecast( %mp3(bitrate=192), host="127.0.0.1", port=8000, password=icecast_pwd, mount="/stream", name="Navi.FM", description="Personal Smart Radio", genre="Various", radio )