Use common Linux utilities and a simple server to easily make an internet radio stations that anyone can access.
For several years I’ve been interested in easily making an internet broadcast of live audio or recorded audio without using social media apps (i.e. Instagram/Youtube/Twitch/etc). The most problematic for me thing about broadcasting audio is port forwarding (I’m often on devices that don’t have access to routers). To solve this problem I wrote a simple server that runs in the cloud which can handle any number of realtime broadcasts uploaded using a simple
curl command. This allows you to essentially broadcast radio feeds with a single line.
Publicizing internet streams without port forwarding
For me, the hardest part about making an internet radio is opening it up to the public internet. I don’t have access to port-forwarding in many scenarios where I want to broadcast (i.e. broadcasting from friends places, or from a music device). My solution to the problem of broadcasting audio without port-forwarding was to create a free and public “dummy” server that handles any incoming traffic and forwards to any number of connected clients. This server keeps track of connected clients and routes incoming packets to them, otherwise discarding the packets.
You could then simply use a common utility like
curl to stream data to this server to those peers. This is essentially what Twitch/Youtube/Instagram do, but I designed a server without any social aspects, its just a dumb URL endpoint that can consume and produce audio streams (or any stream).
The server itself lives at broadcast.schollz.com. The code is open-source and available on Github at schollz/broadcast-server. The code is less than 400 lines, and exceedingly simple. You
POST data streams to any endpoint you want, and processing
GET requests to that endpoint just return the data in that stream. There are special flags if you want to advertise or archive your stream.
Now using this really dumb server which just lives on a DigitalOcean droplet you can easily create internet streams from anywhere, with anything, using a variety of methods:
Method 1 of 2: Broadcasting with
ffmpeg (one line of code!)
As I mentioned the above can be done pretty easily with one line. You first need a common Linux utility:
ffmpeg program will do the conversion and read from live input or files. Forwarding the local stream is done by just piping the output of
ffmpeg to the dummy broadcast server (schollz/broadcast).
To make a live internet radio from the input of your computer, you can do it in one line (albeit long line):
ffmpeg -f alsa -i hw:0 -f mp3 - | curl -s -k -H "Transfer-Encoding: chunked" -X POST -T - "https://broadcast.schollz.com/YOURSTATIONNAME.mp3?stream=true&advertise=true"
That one-liner takes input from your default input
hw:0 and streams it into a
POST request to the dummy server making the stream available at
broadcast.schollz.com/YOURSTATIONNAME.mp3. Make sure you wear headphones if you create a stream on the same computer you are listening to the stream (because feedback)!
Creating an internet radio station from a music playlist is also easily done. You need one extra common utility:
cstream which will make sure the stream is sent in realtime, so its not loaded into memory. Here’s a one liner that will take any folder and create a randomly shuffled playlist and stream it to the station:
find ~/Music/ | grep 'wav|mp3|flac' | shuf | sed -e "s/^/file '/" | sed -e "s/$/'/" > /tmp/playlist.txt && ffmpeg -f concat -safe 0 -i /tmp/playlist.txt -f mp3 -ar 44100 -b:a 256k - | cstream -t 32k | curl -s -k -H "Transfer-Encoding: chunked" -X POST -T - "https://broadcast.schollz.com/YOURSTATIONNAME.mp3?stream=true&advertise=true"
In this case we are streaming at 256 kbps, which is 32 KB/s, so
cstream is set to throttle the data to that rate so it transfers in “realtime”.
Method 2 of 2: Broadcasting using
darkice utilities are installed via
apt-get and really powerful when it comes to streaming. I won’t go into much detail with these two, because there are a lot of guides for it at other places. Here is a great guide for doing live radio on a Raspberry Pi.
If you are on Linux, you can also make your entire computer audio part of the stream (i.e. your browser, VLC, etc.). You can do this with JACK. Simply install JACK:
sudo apt install jackd pulseaudio-module-jack
Then start JACK and load the sink/source for pulse audio:
jackd -R -dalsa -dhw:0,0 & pactl load-module module-jack-sink channels=2 pactl load-module module-jack-source channels=2 pacmd set-default-sink jack_out pacmd set-default-source jack_in
darkice with a JACK configuration.
wget https://raw.githubusercontent.com/schollz/broadcast/main/icecast.xml wget https://raw.githubusercontent.com/schollz/broadcast/main/darkice.cfg icecast2 -c icecast.xml & darkice -c darkice.cfg
Now simply connect
darkice into JACK!
jack_connect 'PulseAudio JACK Sink:front-right' darkice:right jack_connect 'PulseAudio JACK Sink:front-left' darkice:left
darkice stream public
Once you have your
icecast2 stream, you can make it public by port forwarding. There are lots of guides for that. But another way you could do it is using the dummy broadcast server I mention above. Simply pipe the output from
POST it to the server!
curl http://localhost:8000/radio.mp3 | curl -H "Transfer-Encoding: chunked" -X POST -T - 'https://broadcast.schollz.com/YOURSTATIONNAME.mp3?stream=true'
That’s it! Now your stream will be available at
I do a lot of projects with the pi-based sound computer called “norns” which lets you define its behavior with scripts and DSP and basically functions as a sample-cutter, polysynth, drum machine, drone box, granulator, etc.
The norns music tool is based in Linux, so the above methods are just as applicable. This means that the norns can be turned into a broadcast station, while retaining all the functionality as a DSP device! Here’s my little script that converts live audio into a broadcast, directly from your house or live music venue (as long as you have WiFi).
The above norns script uses the
icecast2 because it is based around JACK, but it works beautifully despite running on a Raspberry Pi 3+ and simultaneously running a sample-cutter and SuperCollider synthesizers.