BabelPod: Line-In and Bluetooth Input for HomePod
The HomePod has great sound quality, but right now it’s limited to playing audio from Apple Music or AirPlay clients like the iPhone or iPad. But what if you want to play audio from other sources? Ideally the HomePod would have a line-in port, show up as a Bluetooth speaker, and support other streaming services like Spotify. But Apple decided not to include a line-in port, hasn’t yet implemented Bluetooth speaker support in the OS, and hasn’t yet natively supported other streaming services.
Hopefully Apple will eventually address these shortcomings on the HomePod itself, but for now I’ve come up with my own solution. I’ve taken a Raspberry Pi Zero W (a tiny single-board computer that costs $10 on its own or $40 with all of the parts I needed) and written software that takes audio input from line-in or Bluetooth and outputs it wirelessly to the HomePod via Airplay. I call it BabelPod since it acts as a universal translator between audio devices.
BabelPod has a web interface so you can choose the source and destination from any computer or phone. It auto-detects all of the audio input devices that are available.
It shows up just like any standard Bluetooth speaker.
Note that this solution takes some technical skills to get up and running as you’ll see below. But even if you’re not familiar with this stuff it could be a fun project to learn some new skills, and there are a ton of other projects you can build based on the Raspberry Pi.
How well does it work?
There are some gotchas with this solution. Since it’s streaming audio using AirPlay, there is a 2 second delay between when the audio input is received and when it is played on the HomePod, which means BabelPod won’t work well for video or gaming.
Right now there are also some issues where AirPlay will suddenly disconnect, and other stability issues. I’ll try to improve these over time, and I would gladly welcome any submissions on GitHub.
Finally, keep in mind that the output audio quality is limited by the quality of the input. So if you’re using a cheap line-in USB adapter like I am, that may limit the quality (there are better sound cards available like Pisound and Audio Injector, but I haven’t yet tried any of them myself). Also the Bluetooth audio quality is limited by the fact that it is compressed, although it may be possible to change the standard SBC compression to use a higher bitrate or switch to a better compression algorithm like AAC or AptX.
How can I make my own BabelPod?
- You’ll need a Raspberry Pi Zero W ($34.50 for a Budget Pack), or a larger and more expensive but more powerful Raspberry Pi 3. Alternatively, you could run the BabelPod software on another computer (I had it partially working on my Mac), but the software was targeted to work on the Raspberry Pi. If you want 3.5mm line-in and line-out you’ll also want something like this $5 USB audio adapter.
- Setup the hardware and install the OS (I used the “Download and image Raspbian directly” method).
- Connect the Raspberry Pi to your WiFi network.
- (optional) Setup SSH and VNC so you can control the BabelPod without needing to plug it into its own keyboard, mouse, and monitor. This can be done via the Raspberry Pi Configuration app or by adding a ssh file to the root of the SD card so that it knows to enable it on boot (then you can enable VNC via SSH by running “sudo raspi-config”).
- Find the local IP address of your Raspberry Pi (in my case 192.168.1.16):
- Install NodeJS 9. First I needed to remove the old default version of NodeJS:
- The normal way of installing NodeJS on Linux didn’t seem to work because of the particular ARM processor used on the RaspberryPi Zero, so I needed to download the armv6 binary directly and then install using these instructions:
- Add this to the bottom of .profile:
- Load the updated .profile:
- Install the airtunes Node library (I created a fork to work around a bug):
- Install and start BabelPod:
- At this point you should be able to open the BabelPod web UI from a computer or phone on your WiFi network by going to http://[raspberry_pi_ip_address]:3000/ (in my case http://192.168.1.16:3000/). Line-in should be available as an input (in my case it appeared as “USB Audio”), and your HomePod (and other local AirPlay devices) should be available as output (in my case it appeared as “Airplay: Office”).
- There are some more steps if you also want to get Bluetooth input working:
- Add this to main.conf:
- Load the updated main.conf:
- Make the Raspberry Pi discoverable via Bluetooth:
- The BabelPod should now show up as “raspberrypi” when you scan for Bluetooth devices on your phone or computer (this name can be changed by opening bluetoothctl and running “system-alias BabelPod”). When you try to connect the Raspberry Pi needs to be set to trust your device. You can do this from the desktop interface, or from the terminal.
- Now you should be able to connect successfully and choose it as the audio output on your device.
- In the BabelPod web UI you should now be able to select your Bluetooth device as input and output it to your HomePod via AirPlay!
How does BabelPod work?
The BabelPod software consists of a web frontend and backend Node code that pipes together different audio inputs and outputs. A huge thanks to the people who have made those inputs and outputs possible:
- airtunes: used to output to AirPlay speakers like the HomePod.
- mdns-js: used to discover what AirPlay speakers are available on your local network.
- bluetoothctl: This is a Node wrapper of the bluetoothctl tool, which is used to list what Bluetooth input devices are available.
- BlueALSA: This makes Bluetooth audio devices available as an ALSA interface, so that you can use them via arecord and aplay.
- express: The framework used to run the web UI.
- socket.io: Used this to keep the backend and web UI in sync via WebSockets (or long-polling as a fallback).
Also thanks to all of the people who have written guides that helped me figure out how to make this work:
- Adafruit guide to using USB Audio Cards with a Raspberry Pi
- Heiko Eggers’ YouTube video and instructions for how to set up a Raspberry Pi as a Bluetooth audio receiver. In particular this helped me figure out what to put in /etc/bluetooth/main.conf.
- Victor Dibia’s guide to playing and recording Bluetooth audio using BlueALSA.
- Christopher Barnatt’s ExplainingComputers YouTube videos about the Raspberry Pi.
Piping System Audio to Airplay (updated September 3rd, 2018)
vespino asked on GitHub whether it was possible to pipe the Raspberry Pi’s system audio (e.g. from a streaming audio app) to the Airplay speaker, rather than using input from a USB soundcard or Bluetooth. I did some digging and it turns out that this can be done by adding a loopback device like this:
It seems that any audio you output to loopback device 0 is sent to loopback device 1, which you can use as an input. You can set your system audio to output to loopback device 0 like this:
Paste the following (change the card # to whatever one aplay -l
said was your loopback device):
To load this new configuration, you can either restart your system, or just restart the alsa service:
Now when an app (e.g. the browser) on your Raspberry Pi plays audio, it will go to the loopback device. And when you run BabelPod, you should be able to select “Loopback PCM” as the input (I had two show up with the same name, the second one worked for me), and pipe the audio wherever you want (e.g. your Airplay speaker).
Running as a background service on startup (updated September 3rd, 2018)
djehrenr on GitHub described a way to run BabelPod as a background service whenever the Raspberry Pi boots, which makes it a lot more convenient to use.
Paste the following (note that the node path should match whatever is returned by which node
):
Then run the following to set up the service:
The status command should return something like this:
Then you can look at the console output log like this:
What’s Next?
I’d like to make these improvements:
-
Improve audio streaming stability(fixed)
-
Run the BabelPod software as a background process when you power on the Raspberry Pi(fixed, see above)
- Avoid duplicate AirPlay devices
- Auto-trust any Bluetooth device that connects (or maybe require a PIN)
- Support higher-quality Bluetooth audio input
- Try a higher-quality sound card
- Create a nice case that includes the sound card (maybe it could double as a HomePod coaster 😈)
If you’d like to help out I welcome contributions on GitHub.
I’d also like to get BabelPod to run Alexa and Google Assistant. The device will need to use its own microphone rather than the HomePod’s, but the resulting experience should be that you can address the HomePod using any of the three voice assistants (“Hey Siri”, “Alexa”, or “OK Google”) and the right one will kick in and respond to your query. This will allow you to use other streaming services like Spotify.
My ultimate goal is to demonstrate to Apple that their customers want the HomePod to support audio sources outside the Apple ecosystem. So if you build a BabelPod, please spread the word so we can make sure Apple hears the message load and clear. I am hoping that they will enable Bluetooth speaker support with an OS update. I’d also like to see them enable developers (like Spotify) to deploy native apps to the Homepod. This is a real stretch, but it would be much appreciated if future hardware revisions of the HomePod added a line-in port. Native support for those three would have the huge advantage of reducing or eliminating the 2+ second lag that you get with AirPlay, and avoiding the need for a separate device. For now though, I hope that BabelPod will allow more people to enjoy the HomePod.