XTRadio architecture

Search for a command to run...

We have been using Liquidsoap extensively in a WIP project and used the things we've learned whilst developing the engine for Bassdrive.com :) Brilliant piece of software.
Why? It’s good to know when the next bus is coming, what the weather is like, what’s your next calendar event, etc. it’s also cool to not look at your phone all the time (at least for me it is). How? Enter InkyFrame! A 5.7” E Ink display from Pimoron...

I’ve continued to play around with the K3S Beta cluster from Civo Cloud (you can request to join the beta), the aim was to also try out the new Traefik V2 which was released some time ago. In this post we will: Update the default traefik install on ...

This article is out of date. In this post I wanted to showcase how you can get the traefik dashboard enabled on the default civo cloud kubernetes k3s cluster. (It’s currently in beta, you can request access here). I must add, I’ve only played around ...

Just a small snipet on how to send data to TuneIn’s AirAPI from golang. This way you can update your metadata information directly from your API, if you wish. import ( "fmt" "net/http" "net/url" "time" ) func tuneinAPI(artist string,...
I wanted to write a blog post about XTRadio for a very long time. I finally have the time, so let's start with a short but sweet post which explains how everything works, how it all fits together.
XTRadio is an online radio station which started on 08.08.08. It's a joint venture between my good friend crayon and myself. It started on the Undernet IRC Servers, Silvered was heavily involved as well. It's not the biggest project you'll ever hear about, for us involved, it holds a special place in our hearts. A post detailing the history of the radio should happen in the future!
We play electronic music 24/7.

In the above diagram you can see the full picture, we'll dive deeper into this, let's have two categories:
We play music, dooh! We are not streaming from other websites, we have good old mp3 files. Why not OGG or OPUS? In 2008 it was just easy to set it all up with mp3 and we just stuck to it.
We need to upload, edit and store these MP3 files somehow. In the good old days we just ran an FTP server, upload the files, have the backend read it and we were done. Over time we wanted to more data with each MP3 file, like proper Artist, Title, Source URL, etc.
Enter the Admin interface.
It's a very simple web application, it went through a couple of iterations and even now it's not ready for prime time, but essentially it's used for the following actions:
The most interesting aspect is the file upload. Once you select a file from your computer and you upload it, you have a form which allows you to change the Title, Artist, Source URL. An automatic search to Spotify and Soundcloud is made so we can get the album part for the song. The album art is uploaded to the CDN, stored on disk and a unique file name is returned.
All this information is stored in a MySQL database. We need it later, especially on the website.
The uploaded MP3 file is stored in a folder which is shared with Liquidsoap.
This piece of software is a beast! Super fast, extensible, reliable. Check out more details on liquidsoap.info.
In a nutshell, we grab a bunch of mp3 files and play them with Liquidsoap.
We can do metadata manipulation, encoding, decoding, call APIs on certain events, save stream output, a telnet interface to manipulate song queues, etc.
The first time the Admin interface spins up, it generates a playlist file based on the entries in the mysql database. Here's a few lines from the playlist.txt file:
annotate:artist="Brandy",title="Full Moon (Final DJs Remix)",length="335",image="5004360098.jpg",share="https://soundcloud.com/finaldjs/brandy-full-moon-final-djs":/MUSIC/BACKUP/remix/Brandy_-_Full_Moon_(Final_DJs_Remix).mp3
annotate:artist="London Grammar",title="Wasting My Young Years (Sound Remedy Remix)",length="404",image="6161727760.jpg",share="https://soundcloud.com/soundremedy/wasting-my-young-years-sound":/MUSIC/BACKUP/remix/London_Grammar_-_Wasting_My_Young_Years_(Sound_Remedy_Remix).mp3
annotate:artist="The Black Keys",title="Little Black Submarines (Ageless Remix)",length="302",image="973019753.jpg",share="https://soundcloud.com/ageless84/little-black-submarines":/MUSIC/BACKUP/remix/The_Black_Keys_-_Little_Black_Submarines_(Ageless_Remix).mp3
annotate:artist="Andrew Gentry Remix",title="Poetic Justice (ft. Clams Casino) Remix",length="228",image="3840532694.jpg",share="https://soundcloud.com/andrewgentrymusic/poetic-justice-ft-casino-clams":/MUSIC/BACKUP/remix/Poetic_Justice_(ft._Clams_Casino)_Remix.mp3
annotate:artist="Kyla La Grange",title="Cut Your Teeth (Kygo Remix)",length="396",image="9869146691.jpg",share="https://soundcloud.com/kygo/kyla-la-grange-cut-your":/MUSIC/BACKUP/remix/Cut_Your_Teeth_(Kygo_Remix).mp3
We have the following information in here:
Liquidsoap uses each of this information in various ways, the length is the most important for it, it knows for sure how long a song is, this way it can determine when to auto-queue the next file.
We decode the file we randomly pick from the playlist, grab all the information we can, re-encode the file into 3 bitrates, start playing the file and send an API call to our REST API.
When you connect to listen to the radio, you connect straight to Icecast, you have a choice of various bitrates:
Liquidsoap re-encodes our MP3 files and sends it to the icecast endpoints.
You can find our Liquidsoap script on github.
Having an audio stream is awesome and everything, but on a website you can't just have a a player and that's it. Not that our website is super detailed, but it's not just an audio player.
Our data is available through a public API, anyone can view it here, (the v2 is available here).
The source of the data is from our MySQL database and Liquidsoap. When a song plays, liquidsoap sends an event to the API, this prompts a request to the DB to request the details about the song. In the v2 API we're also getting the upcoming songs, straight from the Liquidsoap telnet interface, details of this code is here.
Based on this we can put together the details on the website, in the end it looks like this

The background color is always random, determined based on the album art.
If anyone is interested in more details, feel free to reach out and we can discuss other aspects. The next article in this series should discuss the infrastructure aspects, how we deployed everything, how we used Civo cloud and kubernetes.
All details about xtradio are available on github on github.com/xtradio.