Giter Club home page Giter Club logo

node-airplayhub's Introduction

Description

node-airplayhub is an AirPlay server which accepts streams (using nodetunes) and then streams the audio back out to multiple AirPlay devices with sync support (using node_airtunes).

Installation

1. Pre Reqs

To install this package you will need to install these packages first:

$ apt-get install -y build-essential git libavahi-compat-libdnssd-dev nodejs npm nodejs-legacy

2. Install

$ npm i -g git+https://github.com/noelhibbard/node-airplayhub

3. Config file

The first time you launch node-airplayhub it will generate a config file and automatically populate it with all the AirPlay targets that are advertizing on your network. The default location is ./config.json. If you want to spesify a different location, use the -c or --config option. Here is what the config file looks like:

{
    "servername": "[AirPlay Hub]",
    "webuiport": 8089,
    "debug": false,
    "idletimout": 600,
    "zones": [
        {
            "name": "Room1",
            "host": "127.0.0.1",
            "port": "5000",
            "volume": "50",
            "enabled": false,
            "hidden": false
        },
        {
            "name": "Room2",
            "host": "127.0.0.1",
            "port": "5001",
            "volume": "50",
            "enabled": false,
            "hidden": false
        },
        {
            "name": "Apple TV",
            "host": "192.168.0.21",
            "port": "5000",
            "volume": "50",
            "enabled": false,
            "hidden": true,
            "alias": "TV in Livingroom"
        }
    ]
}
  • servername: The name you will see from your iDevice.
  • webuiport: This is the port number used for the WebUI which is used to select the AirPlay destinations.
  • debug: Highly verbous output to the console.
  • idletimeout: This time is set in seconds. When you disconnect or pause output it starts this timer. when the timer expires it turns off all outputs. This is to prevent you from coming back hours later, say 12AM, and acidetially blasting music on your back porch. Setting this to a 0 will disable the idle timout.
  • zones: This is where you define which AirPlay destinations you want to have available.
  • name: AirPlay destination name.
  • alias: Alias gives a way to override the destination name that is displayed in the WebUI.
  • host: The host name of the AirPlay device.
  • port: Port number of the AirPlay device.
  • volume: This sets the initial volume level of the AirPlay device but it is updated dinamically as you chantge volume in the WebUI.
  • enabled: Whether output is enabled or not. This value is also updated dynamically as you turn outputs on and off.
  • hidden: There may be some devices you never want to use. In that case you can set the zone to hidden.

Place the config file somewhere like this /etc/airplayhub.json

4. Launch

Launch node-airplayhub like this to see the command line options:

$ node-airplayhub --help

Once you start node-airplayhub you can browse to http://[hostname]:[webuiport]/ to select zones and set volume levels.

Service

I also included a systemd service file (node-airplayhub.service) which you can edit it to your liking and then place it in /etc/systemd/system then use this command to enable the service:

$ systemctl enable node-airplayhub

Then this to start the service:

$ service node-airplayhub start

node-airplayhub's People

Contributors

djm300 avatar noelhibbard avatar quadrater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-airplayhub's Issues

Errors Installing on Raspberry Pi

Hi, I am super eager to try out your implementation.

I've been having issues trying to install your project on my raspberry pi. I first installed npm, node, and followed your installation instructions at the top.

  1. Your step #2, I can't even run that on my pi, it just errors out stating that it can't find this repo.
  2. If I git clone your repo, then cd into it, then run npm install I receive an error installing.

Here is the log that is displayed in my terminal.
https://gist.github.com/reidcooper/cc0510a1932753401177173fbfe6486e

Can't install on modern OS (Fedora 32)

Hi,
I'm trying to install this on Fedora 32, but I'm having lots of issues with packages that just don't work together anymore. First I tried with the npm/nodejs that comes with F32 (npm-6.14.4 and nodejs-12.16.3). The error I got with that was:

784 warn notsup unsupported engine for [email protected]: wanted: {"node":"0.12.x" } (current: {"node":"12.16.3","npm":"6.14.4"})

So okay, I downgraded nodejs, installed 0.12.18 from the tarball, and reran. But no, that wasn't sufficient either because a bunch of the deps now require node >= 4. I'm going to try to downgrade my version of Fedora to something with a much older version of Python to see if that helps.

Have you tried installing on a fresh, modern system?

npm i -g git+https://github.com/noelhibbard/node-airplayhub
npm WARN deprecated [email protected]: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
npm WARN engine [email protected]: wanted: {"node":">=4"} (current: {"node":"0.12.18","npm":"2.15.11"})
npm WARN engine [email protected]: wanted: {"node":">=4.0"} (current: {"node":"0.12.18","npm":"2.15.11"})
npm WARN engine [email protected]: wanted: {"node":">=4"} (current: {"node":"0.12.18","npm":"2.15.11"})
npm WARN engine [email protected]: wanted: {"node":">=4.0"} (current: {"node":"0.12.18","npm":"2.15.11"})
npm WARN deprecated [email protected]: react-tools is deprecated. For more information, visit https://fb.me/react-tools-deprecated
/
> [email protected] install /opt/node-v0.12.18-linux-x64/lib/node_modules/node-airplayhub/node_modules/nodetunes/node_modules/mdns
> node-gyp rebuild

gyp ERR! configure error 
gyp ERR! stack Error: Python executable "/usr/bin/python" is v3.8.3, which is not supported by gyp.
gyp ERR! stack You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.
gyp ERR! stack     at failPythonVersion (/opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:454:14)
gyp ERR! stack     at /opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:443:9
gyp ERR! stack     at ChildProcess.exithandler (child_process.js:745:7)
gyp ERR! stack     at ChildProcess.emit (events.js:110:17)
gyp ERR! stack     at maybeClose (child_process.js:1019:16)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:1091:5)
gyp ERR! System Linux 5.6.6-300.fc32.x86_64
gyp ERR! command "node" "/opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /opt/node-v0.12.18-linux-x64/lib/node_modules/node-airplayhub/node_modules/nodetunes/node_modules/mdns
gyp ERR! node -v v0.12.18
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok 
|
> [email protected] install /opt/node-v0.12.18-linux-x64/lib/node_modules/node-airplayhub/node_modules/nodetunes/node_modules/alac2pcm/node_modules/libalac
> node-gyp rebuild

gyp ERR! configure error 
gyp ERR! stack Error: Python executable "/usr/bin/python" is v3.8.3, which is not supported by gyp.
gyp ERR! stack You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.
gyp ERR! stack     at failPythonVersion (/opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:454:14)
gyp ERR! stack     at /opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:443:9
gyp ERR! stack     at ChildProcess.exithandler (child_process.js:745:7)
gyp ERR! stack     at ChildProcess.emit (events.js:110:17)
gyp ERR! stack     at maybeClose (child_process.js:1019:16)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:1091:5)
gyp ERR! System Linux 5.6.6-300.fc32.x86_64
gyp ERR! command "node" "/opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /opt/node-v0.12.18-linux-x64/lib/node_modules/node-airplayhub/node_modules/nodetunes/node_modules/alac2pcm/node_modules/libalac
gyp ERR! node -v v0.12.18
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok 

> [email protected] install /opt/node-v0.12.18-linux-x64/lib/node_modules/node-airplayhub/node_modules/airtunes
> node-gyp rebuild

gyp ERR! configure error 
gyp ERR! stack Error: Python executable "/usr/bin/python" is v3.8.3, which is not supported by gyp.
gyp ERR! stack You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.
gyp ERR! stack     at failPythonVersion (/opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:454:14)
gyp ERR! stack     at /opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:443:9
gyp ERR! stack     at ChildProcess.exithandler (child_process.js:745:7)
gyp ERR! stack     at ChildProcess.emit (events.js:110:17)
gyp ERR! stack     at maybeClose (child_process.js:1019:16)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:1091:5)
gyp ERR! System Linux 5.6.6-300.fc32.x86_64
gyp ERR! command "node" "/opt/node-v0.12.18-linux-x64/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /opt/node-v0.12.18-linux-x64/lib/node_modules/node-airplayhub/node_modules/airtunes
gyp ERR! node -v v0.12.18
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok 
npm WARN engine [email protected]: wanted: {"node":">=4"} (current: {"node":"0.12.18","npm":"2.15.11"})
npm ERR! Linux 5.6.6-300.fc32.x86_64
npm ERR! argv "/opt/node-v0.12.18-linux-x64/bin/node" "/opt/node-v0.12.18-linux-x64/bin/npm" "i" "-g" "git+https://github.com/noelhibbard/node-airplayhub"
npm ERR! node v0.12.18
npm ERR! npm  v2.15.11
npm ERR! code ELIFECYCLE

npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the airtunes package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs airtunes
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! 
npm ERR!     npm owner ls airtunes
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/airhub/npm-debug.log

Spotify Connect Integration

Hi Noel,

first of all: absolutely outstanding code! Helped me loads! Tried to integrate similar things 1,5 years ago but didn't make it that far, now I had some spare time again and looked your program up and it's exactly what I was looking for.

One question, I was planning to play Spotify on different Airplay speakers. For this purpose, I was thinking about piping the audio of Spotify directly on the same device (in my case: Raspberry) to your script and therefore multiple speakers. Was thinking about jusing Spotify Connect (https://github.com/Fornoth/spotify-connect-web) for that purpose, could you give me kindly some advice how to achieve it?

Best regards
7rncs

Error when HTC attempts connection

I can get this to work using RAOP pulseaudio as a source. I can 'see' it as a device on my desktop screen and connect to it and it does seem to work well. WHen I try to connect to it with my HTC One M9, though, I get an error and it crashes the program. My guess is HTC is probably not 100% compliant with Apple which is causing the issue. I am guessing a little bit better error trapping may help this to work:

buffer.js:141
    throw new TypeError('must start with number, buffer, array or string');
    ^

TypeError: must start with number, buffer, array or string
    at fromObject (buffer.js:141:11)
    at new Buffer (buffer.js:62:10)
    at Object.decryptAudioData (/usr/local/lib/node_modules/node-airplayhub/node_modules/nodetunes/lib/helper.js:141:27)
    at RtpServer.<anonymous> (/usr/local/lib/node_modules/node-airplayhub/node_modules/nodetunes/lib/rtp.js:32:23)
    at emitTwo (events.js:87:13)
    at Socket.emit (events.js:172:7)
    at UDP.onMessage (dgram.js:480:8)

unable to choose other config file

Unfortunately I'm unable to use the config file option. If I start "node-airplayhub --config /tmp/test.json" it stops with the following error (test.json is readable and valid, I copied it from config.json):


/usr/local/lib/node_modules/node-airplayhub/index.js:21
configPath = path.join(__dirname, argv.config);
^

TypeError: Cannot read property 'join' of undefined
at Object. (/usr/local/lib/node_modules/node-airplayhub/index.js:21:26)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:990:3

Can't get service to work

Hi,

This is exactly what i have been looking for! However, i got the program to work, but i can't get it to run as a service. When trying to enable the service i get the following error: "Failed to execute operation: Bad message". Any thoughts on how to fix that? (i copied node-airplayhub.service to the right directory).

Apple TV 4 sync issue

Hi Noel,

I have been reading through your posts on shairport-sync and your work here, which is excellent by the way and it has been really interesting seeing your journey to this solution, I have a slightly different use case I am trying to solve and would like a bit of inspiration (I am basically trying to make wireless speakers for my apple TV).

So I have 2 shairport-sync end points (Raspberry Pi 3 B each attached to a DAC, AMP and a left/right channel speaker) and I run node-airplayhub on one of them. I can output TV audio to the grouped speakers perfectly synced with each other and about 30-50ms delay from the TV at a guess maybe a bit less. If I play directly to one of the end-points theres no audio/video sync issue.

I was thinking of using forked-daapd to pass to the end points but it's not compatible with more recent versions of tvOS.

Any suggestions appreciated,

Peter

No Audio on AppleTV 4, tvOS 11.1

Hi,
Theres no audio coming from my Apple TV.
I have two raspberries, there its working like a charm.

Any Ideas?
Thanks,
Kilian

my config file:

{
    "servername": "Ganze Wohnung",
    "webuiport": 8089,
    "debug": false,
    "idletimout": 600,
    "zones": [
        {
            "name": "Wohnzimmer",
            "host": "192.168.178.101",
            "port": 5000,
            "volume": "48",
            "enabled": true,
            "hidden": false
        },
        {
            "name": "Schlafzimmer",
            "host": "192.168.178.33",
            "port": 7000,
            "volume": "48",
            "enabled": true,
            "hidden": false
        },
        {
            "name": "Küche",
            "host": "192.168.178.100",
            "port": 5000,
            "volume": "48",
            "enabled": true,
            "hidden": false
        }
    ]
}

Not outputting audio to all devices

After fiddling around with this I have gotten the implementation to work partly, but not fully. I have 3 airplay devices set up but only only one of them outputs audio when playing to them. The two airplay devices that don't output audio work fine when playing directly to them via airplay from an ios device, but are silent when playing through node-airplayhub.

I should note that the the device that works is an apple airport, while the other two devices that I can't get to work are one Asus repeater (w. airplay support) and one Raspberry Pi with shairport-sync.

I tried editing the config file and adding the password for the devices, see below, but that doesn't seem to help either.

        {
            "name": "Badrum",
            "host": "192.168.2.129",
            "port": 5178,
            "volume": "53",
            "enabled": false,
            "hidden": false,
            "password": "passw"
        },

I've also tried looking at the log files under /var/log/ but I haven't been able to find anything there, any suggestions on what could be wrong and how i can get this to work?

Thanks in advance

Avahi, shutdown and volume control

First of all: THANK YOU SO MUCH for sharing this! Up and running on a Raspbian Pi 3 B, one of four cores is busy with < 30 % in average. Running quite stable with 3 target devices.

There are 3 issues left for me:

  1. On startup I get some Warnings:

# node-airplayhub --config=/opt/node-airplayhub/config.json

*** WARNING *** The program 'nodejs' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=nodejs
*** WARNING *** The program 'nodejs' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=nodejs&f=DNSServiceRegister

Do you get the same Warnings? Something to worry about...?

  1. When Music is stopped for some while I cannot restart playback. I did not measure, if this happens after the very exact time. This problem seems to be on the node_airtunes side, since the playback on the iOS device works (song is "running" on iPhone), but there is no output on any target device. Did you notice similar things?

  2. I would like to programm a GUI for the Raspi with following major functions:

  • restart the server process
  • rescan for airplay devices (Port 5000) and set it to "remember"
  • de/activate single target devices
  • adjust volume of all target devices
  • adjust volume of single target devices
    By now there is no change on the target device's volume, if I change the iOS volume. Do you have any hint about...
    => where to catch the actual volume of the input stream (in order to adjust the output volume level)
    => how to modify the volume of the single output streams (I cannot remember for sure, if this worked at any point, anyhow, changig the "volume" or "enabled" values in the config file /opt/node-airplayhub/config.json does not affect the current playback. Changing these values on the webinterface (Port 8089) does affect the playback. Is there a safe way to interact with these values by a 2nd GUI in parallel?

Thank you!

AppleTV 4G stops playing

Hi,

first, this is a great project. Thanks for the time and thanks for sharing.

Sadly, at this point my AppleTV 4G stops playing music within the first 5-10 minutes of switching to airplayhub's virtual speaker. The other speaker (Shairpoint Sync based) still plays music after that.

Furthermore I changed the servername but all devices still show the original [AirPlay Hub] name.

Any hints how I can solve these problems?

Thank you very much

Karsten

crashing shortly after start

pi@automator:~$ node-airplayhub -c ~/airplayhub.conf
*** WARNING *** The program 'nodejs' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=nodejs>
*** WARNING *** The program 'nodejs' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=nodejs&f=DNSServiceRegister>
  nodetunes:server starting nodetunes server ([AirPlay Hub]) +0ms
  nodetunes:server broadcasting mdns advertisement (for port 5000) +314ms
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: read ECONNRESET
    at exports._errnoException (util.js:1022:11)
    at TCP.onread (net.js:569:26)
1 pi@automator:~$ 

not sure what the reason is. I have homebridge running on the same machine which also uses avahi - can that be somehow the reason?

Mitigating Audio Drops

Thanks for this great tool. I've been streaming music from an iPhone to two (or three) destinations: a shairport-sync service running on the same Raspberry PI 3 where airplayhub runs, a new airport express, and an old flip-plug style airport express. In general this works well, with great sync. Some extra delay to start/stop/skip, but that's understandable given the double-buffering. It does seems somewhat sensitive to audio drops and gaps. Interestingly, this seems to have plenty to do with the CPU load on my RPI3. I also run homebridge on the same pi, and in fact have just recently written a home bridge plugin to make individual accessories to control speaker volume and mute. This is working well (except Apple doesn't yet actually support it's "Speaker" accessory), but using homebridge to set volume really increases the rate of the audio drops. If airplayhub is using say 25-30% CPU, and homebridge jumps in with another 25%, that seems to do it. Sometimes drop come from nowhere though. I have some evidence that playing music from a 3rd device (e.g. my laptop) improves this. So possibly the phone is the limiting issue. Is there any way to increase or play with the buffer depth, i.e. incur an extra ~second of buffering to limit these drops?

can't get it to work, presumably because of node-airtunes

I really can't get node-airplayhub to work after I did a fresh & clean install of my server. I installed Debian buster and of course I tried first the versions of nodejs / npm that come with buster. The compilation itself did work, node-airplayhub started and it found all of my speakers. I was able to choose node-airplayhub as my reciever, but the speakers didn't start to play. It seems that node-airtunes is the problem, even the examples coming with the library itself don't work.

I already tried all the other versions of nodejs you can find at https://github.com/nodesource/distributions, but none of them did work. Could you please test your version of node-airplayhub if it works as it should and which versions of nodejs / npm you use? It would be nice if you could upload a running binary version of node-airplayhub together with the matching libraries of nodetunes and node-airtunes. node-airplayhub is a great piece of software and it fits all my needs, it annoys me that I didn't do a backup of it.

Just saying thanks

Didn't know how else to contact you, but I wanted to say thanks for this amazing piece of software. I stumbled across your open issue on shairport-sync, and the problem (and solution!) you described was exactly what I was looking for, too.

It's amazing that all the pieces were essentially right in front of everyone, but it was you who put them together to make something complicated almost trivial. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.