BabelPod is a lightweight Node.js application that captures audio from a selected input device (like a USB mic or line-in) and sends it in real-time to multiple output devices, including:
- AirPlay speakers or receivers (via node_airtunes2)
- Local aplay processes on a Raspberry Pi or similar
- Select input devices (including
arecord-recognized hardware and Bluetooth audio devices). - Stream to multiple outputs in parallel (local or AirPlay).
- Automatic discovery of AirPlay devices via mDNS with support for stereo paired HomePods.
- Bluetooth input support for wireless audio streaming.
- Optional PCM device scanning (can be disabled for better performance on systems that don't use ALSA devices).
- Enhanced mDNS service handling for dynamic IP address changes.
- Simple UI served by Express + Socket.IO.
- Node.js (LTS version recommended)
arecordandaplayinstalled (often inalsa-utilspackage on Linux).- On macOS,
soxor other tools might be needed for capturing audio, but this is primarily tested on Linux. - Optional: For Bluetooth input support, install
bluetoothctland pair your Bluetooth audio devices. - Optional: For PCM device support, ensure your ALSA devices are properly configured. PCM scanning is enabled by default.
- Clone this repository.
- Install dependencies in
babelpodfolder:
cd babelpod
npm installNote for Raspberry Pi Zero/Zero 2 W: If you're running on a low-memory device like the Raspberry Pi Zero or Zero 2 W, you may need to use a lower-memory npm install option:
npm install --omit=dev --omit=peer --omit=optional --no-audit --no-fund --jobs=1 --fetch-retries=5 --fetch-retry-factor=2 --fetch-retry-mintimeout=10000 --fetch-timeout=600000If npm install fails with out-of-memory errors, check your swap space with swapon --show to determine if you're running out of swap space.
- node_airtunes2 must also be installed (the dependency is included in package.json).
If you have trouble building airtunes2, ensure:
- You have a proper C++ build environment (e.g., build-essential on Debian/Ubuntu or Xcode Command Line Tools on macOS).
- Node.js version is not too new to break older C++ code. If you get errors like “C++20 or later required,” you can consider installing an LTS version of Node (e.g., 18 or 20).
BabelPod supports the following environment variables for configuration:
DISABLE_PCM=1: Disable PCM device scanning. By default, PCM scanning is enabled. Set this to1if you don't use ALSA PCM input/output devices and want better performance.BABEL_PORT=3000: Set the HTTP server port (default: 3000).
Example:
DISABLE_PCM=1 node index.js- Start:
node index.js
or if you have nodemon:
nodemon index.js
- Open
http://<your-pi-ip>:3000in a web browser (mobile or desktop). - Select an input device from the dropdown. If using a microphone or USB interface, choose the correct
plughw:{...}. For Bluetooth devices, they will appear as "Bluetooth: [device name]". - Adjust volume and choose outputs. You can select multiple AirPlay or local outputs simultaneously.
To use Bluetooth audio devices as input sources, you'll need to pair them first using bluetoothctl:
- Install Bluetooth tools (if not already installed):
sudo apt-get install bluez- Start bluetoothctl:
bluetoothctl- Enable the Bluetooth agent and scan for devices:
power on
agent on
default-agent
scan on
- Wait for your device to appear in the scan results. You'll see something like:
[NEW] Device AA:BB:CC:DD:EE:FF My Bluetooth Speaker
- Pair with the device using its MAC address:
pair AA:BB:CC:DD:EE:FF
trust AA:BB:CC:DD:EE:FF
connect AA:BB:CC:DD:EE:FF
- Exit bluetoothctl:
exit
Once paired and trusted, the Bluetooth device will appear in BabelPod's input device list as "Bluetooth: [device name]". BabelPod will automatically connect to the device when you select it as an input source.
- Manual arecord test
arecord -D plughw:1,0 -c2 -f S16_LE -r44100 test.wav
- Speak or play audio, then Ctrl+C to stop.
aplay test.wav
- You should hear your recording on local playback. This ensures your input device is working.
- Confirm single AirPlay device with node_airtunes2
cat test.wav | npx airtunes2 --host <AirPlay device IP> --port 7000
- If you hear playback on that AirPlay device, the streaming chain works.
- BabelPod
- Start the server:
node index.js - Go to the UI, pick the same input device used above, select your AirPlay or local device. You should hear real-time audio.
• Use console.log lines or the Node process logs to see activity.
• mDNS scanning logs can be checked if needed: watch for “update” events or data.txt.
• If audio is silent, confirm volumes, passcodes, or if your device demands a pin. Check if any firewall blocks UDP traffic.
BabelPod now includes comprehensive error handling to prevent crashes and provide better visibility:
- UI Error Messages: The web interface displays error and status messages so you can see what's happening without checking server logs.
- Process Error Handling: The server won't crash if
arecordoraplayprocesses fail - errors are logged and reported to the UI. - Network Resilience: AirPlay connection errors and mDNS issues are handled gracefully.
- Graceful Shutdown: Clean shutdown on Ctrl+C (SIGINT) or SIGTERM properly stops all audio processes.
BabelPod can be configured to run automatically as a systemd service on boot. This is especially useful for permanent installations on Raspberry Pi.
- Copy the service file to the systemd directory:
sudo cp babelpod.service /etc/systemd/system/- Edit the service file to match your setup:
sudo nano /etc/systemd/system/babelpod.serviceUpdate the following fields (and others) as needed:
UserandGroup: Change frompito your usernameWorkingDirectory: Set to the full path of your babelpod installationExecStart: Update the path to your babelpod installationXDG_RUNTIME_DIR: Update the UID (1000) to match your user's UID (runid -uto find it)
- Reload systemd to recognize the new service:
sudo systemctl daemon-reload- Enable the service to start on boot:
sudo systemctl enable babelpod- Start the service:
sudo systemctl start babelpod-
Check service status:
sudo systemctl status babelpod
-
View service logs:
sudo journalctl -u babelpod # add -f to follow logs in real-time, which is useful for debugging
See TESTING.md for a comprehensive testing guide including manual test checklists and expected behavior documentation.
Run unit tests with:
npm testPlease open issues or PRs for improvements or bugfixes.
MIT License (See LICENSE.md)