One Way to stream lossless icecast2 from MIXXX in Linux

I’ve been trying different ways to stream DJ sets from MIXXX and found this method that works providing a lossless FLAC ogg stream to icecast2, with an update of what track is playing.

I’m using Xubuntu 16.04 for this.

It took me a while to get this combination of software working, so I thought I’d post the recipe as a set of rough scripts to show the approach

As the built in MIXXX broadcasting options don’t support this, I set up the “booth” output to go to an ALSA loopback audio device.

I then use arecord piped into aviconv to stream the audio as an Icecast flac stream to the ICECAST2 server. I’m piping from arecord as I couldn’t figure out how to record from the Loopback device direct with aviconv.
I’m using arecord “raw” as arecord defaults to recording WAV which has a max size of 2GB, even when piped.

As this loses the metadata, I use an sqlite3 command to extract the “now playing” info and display it on a web page.
The below two shell fragments can be made into scripts and left running in a screen session on the PC running mixxx.

Broadcast script:

# very simple loop, needs
# sudo modprobe snd-aloop
# run to have the loopback audio set (or set it up in /etc/ ..)
# then set hw:Loopback,0 as the BOOTH output in MIXXX
# you may need to increase the latency to reduce glitching with the additional output.
# set s16 to s32 for 24 bit flac, but thats overkill...
cd /tmp
while true
  arecord -D hw:Loopback,1,0 -f FLOAT_LE -c 2 -r 44100 -t raw | \
   avconv -report \
    -f f32le -sample_rate 44100 -ac 2 -sample_fmt f32le \
    -i pipe: \
    -ar 44100 -ac 2 -b:a 420000 -sample_fmt s16 \
    -bufsize 20480k \
    -c:a flac -compression_level 10 -f ogg \
    -ice_description 'Describe my stream'  \
    -ice_url '' \
    -ice_public 1 \
    -content_type application/ogg \
  sleep 1

As it has lost the metadata during this process, update a now playing text file on the web site by grabbing that info from the MIXXX database…

touch /tmp/nowplaying.txt-prev /tmp/nowplaying.txt
while true
    sqlite3 /home/dj/.mixxx/mixxxdb.sqlite -column -header "select library.artist, library.title, library.album, library.year from library where = (select PlaylistTracks.track_id from PlaylistTracks where id = (select max(id) from PlaylistTracks));" > /tmp/nowplaying.txt
   if ! diff /tmp/nowplaying.txt /tmp/nowplaying.txt-prev > /dev/null
      echo track has changed
      cat /tmp/nowplaying.txt
      date >> /tmp/radio.log
      cat /tmp/nowplaying.txt >> /tmp/radio.log
      scp -q /tmp/nowplaying.txt
      cp /tmp/nowplaying.txt /tmp/nowplaying.txt-prev
   sleep 10

Web page that will display an inline player for the above code:

<!DOCTYPE html>
  <meta http-equiv="Content-Type" content="text/html; charset=utf8" />
  <script type="text/javascript">
    function refresh() {
      var req = new XMLHttpRequest();
      console.log("Grabbing Value");
      req.onreadystatechange = function () {
        if (req.readyState == 4 && req.status == 200) {
          document.getElementById('NowPlayingElement').innerText = req.responseText;
      }"GET", '', true);

    function init() {
      var int = self.setInterval(function () {
      }, 2000);

<body onload="init()">
  <div id="main">
    <div id="updateMe">
      <b>MY RADIO Track Now Playing is:</b>
      <pre><p id="NowPlayingElement"></pre>
<p><audio controls="controls" preload="none"><source src="" type="audio/ogg" />Your browser does not support the audio element.</audio> <!-- END OF THE RADIO HTML5 PLAYER EMBEDDING --></p>

Running example (if the entry level cloud ICECAST2 server doesn’t fall over :slight_smile: is here: … ation.html