Web Radio Broadcasters

Hi all, I thought this could be a place to talk about the nitty-gritty of running your own web radio stream, which should be an easier thing to do, but maybe sharing experiences will help inspire new projects!

Here’s my current setup for the http://phonography.radio.af stream – running on an ubuntu server:

I’m running the scripts and apps mostly under a deploy user which has no sudo rights. (Remember to set up a firewall with ufw!)

Icecast is actually serving the stream. Apache is set up to proxy the stream url to /stream/ over port 80 (see config above).

There are two systemd services: one for the liquidsoap script which generates the stream and pipes it to icecast, and one for a little flask app which is being proxied via Apache to /info/ and has a “seed” endpoint, and an SSE endpoint which the client uses for realtime updates.

The liquidsoap script (see above again for the script – I think I included all the relevant scripts and configs except the icecast config, which is basically the standard setup with different auth info) looks for tracks in a phonography.m3u playlist – which is just a list of paths to FLAC files tagged with some metadata.

When a new track starts playing, a callback in liquidsoap runs the python script which doubles as the flask app and passes it the track title and the catalog number – which is just a unique ID I give each track. The python script sets the title and catalognumber in redis, and also publishes it to a pubsub channel in redis. The title and catalognumber are actually pulled from the FLAC files by liquidsoap, there’s no DB in my setup unless you count redis.

The client (a web browser) listens to the SSE channel which gets pushed data from the redis pubsub channel – it uses that to set the now playing info and look up which picture it should show. I just gave all the pictures the same name as the catalognumber to make it simple. (See index.html for the javascript that does this part.)

That’s the handy-wavey overview of the setup. It’s working out pretty well so far for me!

I’m planning to hack in a few extra bits to add artist / bio info for the tracks below the basic track info.

There is some code to tweet each track change as well that I pulled out but I can share that bit as well if anyone is interested. It’s just the most basic usage of the tweepy library for python and gets called when liquidsoap hits the python script.

Clear as mud? I’m happy to explain the setup more, also curious if other folks are operating streams and have tips to share!

11 Likes

Wanted to thank you for posting this. Lines Radio would be an awesome (quixotic?) project, in conjunction with the (nopefully not defunct?) netlabel thread and summary a few years back.

3 Likes

I just saw this article pop up on HN this morning: https://watsonsmith.com.au/building-an-internet-radio-station

It’s pretty light on details but I think it does a decent job of explaining how typical layers in a web radio stack come together – and it illustrates how complex an integrated system like libretime can be. Those pieces can be cherry-picked for a much simpler (and custom) approach but it’s hard to say if installing and getting to know something like libretime is more of a time investment than just getting to know icecast and liquidsoap. Liquidsoap is the brains behind libretime but it is a scripting language.

The article above also reminded me of this much more in depth introduction to one possible web radio setup using icecast and liquidsoap in linux journal: https://www.linuxjournal.com/content/creating-internet-radio-station-icecast-and-liquidsoap

That’s a really good introduction to using the two together and goes into more detail about specific configuration.

From the liquidsoap side, here’s a more complete real world example (powering a my little pony themed web radio station) which the author has been keeping up to date – it’s just the liquidsoap config but it’s very well documented and really helps show off the types of things you can do: https://gist.github.com/GeekBrony/47d2212ed6408be816a2

A simpler but still very powerful example is the liquidsoap “complete case analysis” example: https://www.liquidsoap.info/doc-1.3.7/complete_case.html

So rent a $5 VPS and start broadcasting! :slight_smile:

3 Likes

@dailybells Could this be adapted for live streaming do you think?

Yes, for example in the liquidsoap complete case analysis, the stream is set up to be able to be taken over by a live relay:

full =
  fallback(track_sensitive=false,
           [input.http("http://localhost:8000/live.ogg"),
            radio])

The way I’ve used this in the past is the /live.ogg points to an icecast endpoint which you can connect to with a streaming client like BUTT. If the live stream is available, it will override everything else since the radio here is the playlist-based stack, and is positioned as a fallback for the live stream.

1 Like

Nice. Definitely something I’ve been wanting to pursue more – I have some friends running stations who do live streaming events (including @mrspiral who I’ve just remembered is here). Just haven’t managed to hack out the time to get my own system configured to participate.

Always happy to see things happening on the Linux side.

1 Like

FWIW, liquidsoap is written in OCaml which can also be installed on a mac. So you could run icecast on a remote server and set up liquidsoap on your mac at home as the relay for example – might be a nice way to play around with it at first!

Edit: there’s a brew package for icecast too, so you could just skip the VPS and give it a try on your laptop to start as well.

FWIW, liquidsoap is written in OCaml which can also be installed on a mac. So you could run icecast on a remote server and set up liquidsoap on your mac at home

I don’t have a mac at home. I have a Linux box at home. :wink:

1 Like

Even better!

Sorry, I shouldn’t have assumed – seems like there are a lot of mac users on this forum.

(And if any of them ends up trying icecast or liquidsoap on a mac please report back!)

1 Like

Are there any good live broadcast options for non-coders? I was looking into Icecast and stuff a few weeks back for a broadcast project I’m working on, and just ended up deciding to do it with pre-recorded episodes because everything for live streaming seems so complicated. I’m sure I could figure it out with enough time but I’d really rather spend that time creating the show than learning how to code…

1 Like

The article about Nomad Radio’s setup mentions radio.co and airtime (airtime is the commercial version of libretime) but I’m sure there must be other hosted / paid platforms too.

But maybe get in touch with an existing station you like and propose your project? (Let them deal with the infrastructure.)

(Also I’d love to hear about your project.)

RadioSpiral uses Airtime, which isn’t perfect but has been very solid for us over the years. We relay live musicians all the time as part of our programming.

1 Like

We just (soft) launched a new channel on radio.af: http://sparetire.radio.af/

Freeform selections from TV Pow’s Brent Gutzeit. <3

I can’t stress enough the freedom of using the most simple tools you need… this channel is a refinement, and a simplification. I’m stoked. :slight_smile:

(Nerd details: this is our first nextcloud-driven channel. Brent tags his audio and syncs it to a nextcloud folder and the server watches for changes and recreates playlists etc…)