Broadcasting vinyl over my LAN - ALSA2ChromeCast


Previously, on the Terence Eden Adventures:

The record player has USB output. So I shoved it into a Rock Pi S - an SBC similar to a Raspberry Pi - to broadcast vinyl all over my house via ChromeCast! Here's how.

Detect the audio

Install alsa-utils if they're not already present.

Find your hardware with

BASH BASHarecord -l

One of the outputs should be:

BASH BASHcard 2: Microphone [USB Microphone], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

In this case, we want Hardware Card 2, Device 0. From now on, we'll refer to this as hw:2,0. Yours may be different.

Record a sample from the input. Make sure the record player is playing music!

BASH BASHarecord  --device="hw:2,0" -d 10 -f dat -t wav test.wav

That will record a 10 second WAV file at the best possible audio resolution. Check that it has worked by playing back the WAV on a different computer.

Install Icecast

Icecast is a terrible bit of software with no sensible user documentation or guide. Install it with:

BASH BASHsudo apt install icecast2

It should prompt you for some information. And then it will start in the background automagically. If not, run:

BASH BASH/etc/init.d/icecast2 start

You can edit the default config with:

BASH BASHsudo nano /etc/icecast2/icecast.xml

Here's a minimal config. This The admin username is admin and all the passwords are password - you probably want to change that! The hostname is set to the IP address of the Pi, 192.168.0.123:

 XML<icecast>
    <hostname>192.168.0.123</hostname>
    <location>Earth</location>
    <admin>icemaster@localhost</admin>
    <limits>
        <clients>100</clients>
        <sources>2</sources>
        <queue-size>524288</queue-size>
        <client-timeout>30</client-timeout>
        <header-timeout>15</header-timeout>
        <source-timeout>10</source-timeout>
        <burst-on-connect>1</burst-on-connect>
        <burst-size>65535</burst-size>
    </limits>
    <authentication>
        <source-password>password</source-password>
        <relay-password>password</relay-password>
        <admin-user>admin</admin-user>
        <admin-password>password</admin-password>
    </authentication>
    <listen-socket>
        <port>8000</port>
    </listen-socket>
    <http-headers>
        <header name="Access-Control-Allow-Origin" value="*"/>
    </http-headers>
    <fileserve>1</fileserve>
    <paths>
        <basedir>/usr/share/icecast2</basedir>
        <logdir>/var/log/icecast2</logdir>
        <webroot>/usr/share/icecast2/web</webroot>
        <adminroot>/usr/share/icecast2/admin</adminroot>
        <alias source="/" destination="/status.xsl"/>
    </paths>
    <logging>
        <accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
        <loglevel>3</loglevel>
        <logsize>10000</logsize>
    </logging>
    <security>
        <chroot>0</chroot>
    </security>
</icecast>

To restart after making changes, run:

BASH BASH/etc/init.d/icecast2 restart

If you visit http://your_server_ip:8000 then you should see a boring interface. You can't do anything with it yet.

Install Ice2

Icecast is a server - but you also need a client to broadcast audio to the server. Annoying that Icecast doesn't come with one. And annoying that there's no tutorial to tell you all this.

BASH BASHsudo apt install ice2

I followed this tutorial. Basically, create a file called ice.xml with this in it:

 XML<ices>
    <stream>
        <input>
            <module>alsa</module>
            <param name="rate">48000</param>
            <param name="channels">2</param>
            <param name="device">hw:2,0</param>
        </input>
        <metadata>
            <name>@edent's record player</name>
            <genre>Live Vinyl</genre>
            <description>Listen to what's on my record player</description>
            <url>http://192.168.0.123:8000</url>
        </metadata>
        <instance>
            <hostname>192.168.0.123</hostname>
            <port>8000</port>
            <password>password</password>
            <mount>/vinyl.ogg</mount>
            <yp>1</yp>
            <encode>
                <quality>10</quality>
                <samplerate>48000</samplerate>
                <channels>2</channels>
            </encode>
            <downmix>0</downmix>
        </instance>
    </stream>
    <background>1</background>
    <logpath>.</logpath>
    <logfile>ices.log</logfile>
    <logsize>2048</logsize>
    <loglevel>4</loglevel>
    <consolelog>0</consolelog>
</ices>

Now run ices2 ice.xml - it will run in the background.

The admin page of Icecast should now have something like this: Icecast admin page. You can now play the audio via the HTML5 player on the page - or open the M3U in VLC.

ChromeCast Broadcast

For my home AV set-up, the easiest way to broadcast audio to my amp is to use its built-in ChromeCast Audio.

There are loads of solutions, but the easiest to use was PyChromeCast. Once installed, it can stream audio from IceCast to a ChromeCast. Bit convoluted, but it works!

To discover ChromeCasts on your network, run python3 then enter these commands:

Python 3 Python 3import time
import pychromecast
pychromecast.discovery.discover_chromecasts()

You'll get a list of ChromeCasts on your network. Mine showed:

[('192.168.0.789', 4321, UUID('5632e20d-1030-4885-ad3d-496504b7c820'), 'Pioneer VSX-933', 'Pioneer VSX-933 ABC1234')]

We want the ChromeCast's ID - which is the 4 digit int. Back to Python

Python 3 Python 3pychromecast.get_chromecasts(4321)

You'll get a bit more debug data:

[Chromecast('192.168.0.789', port=4321, device=DeviceStatus(friendly_name='Pioneer VSX-933 ABC1234', model_name='Pioneer VSX-933', manufacturer='Onkyo And Pioneer', uuid=UUID('5632e20d-1030-4885-ad3d-496504b7c820'), cast_type='cast'))]

This supports cast - good!

Now we can send the audio to the ChromeCast

Python 3 Python 3cast = pychromecast.get_chromecasts(4321)[0]
cast.wait()
mc = cast.media_controller
mc.play_media('http://192.168.0.123:8000/vinyl.ogg', 'audio/ogg')

Success! Vinyl ➡️ USB ➡️ ALSA ➡️ IceCast ➡️ Ogg ➡️ Ethernet ➡️ WiFi ➡️ ChromeCast ➡️ Speakers.

Is it worth it?

Depends. Do you like lossy, crackly vinyl, smushed down to OGG, flown across a network, then digitally reprocessed into luscious 5.1 surround sound with a 4.5 second lag?

Meh.


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

6 thoughts on “Broadcasting vinyl over my LAN - ALSA2ChromeCast”

    1. -dsr- says:

      Do yourself a big favor: digitize your vinyl on the best equipment you can borrow, rent or buy. Then put the vinyl away in a cool dry place.

      Then play your music with mpd or anything else you feel like.

      Reply
      1. @edent says:

        No. Vinyl sounds crap. Always has done, always will do. Much better to rip a CD straight down to Opus. I guess you can go FLAC if you're worried that you'll miss out on a tiny bit of detail.

        Reply
  1. Ryan says:

    Hello!

    Thanks for the tutorial! Right now, I'm running my vinyl through Darkice and then Icecast. I would like to be able to access and Chromecast this stream through a radio app like TuneIn. However, when I play the stream, no Chromecast icon appears. Would this tutorial be helpful in making my vinyl Icecast stream discoverable to TuneIn?

    Thanks!

    Reply
  2. Ryan says:

    Thanks so much for the quick response! The odd part is that I'm able to cast to stream from Chrome and using this android app (https://github.com/dupontgu/simple-cast). Are these and using an app like TuneIn unrelated?

    I did ask TuneIn about it and they said it was an issue they are aware of and working on, but part of me feels like they were blowing me off.

    Reply

What links here from around this blog?

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">