From fef4681dbc6d135285d04b4429394467b3f3aa8c Mon Sep 17 00:00:00 2001 From: Thomas Watson Steen Date: Sat, 26 Jul 2014 21:12:42 +0200 Subject: [PATCH] Add ways to configure the AirPlay server --- README.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- index.js | 46 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 87 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ef449d4..fe49aaf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,54 @@ -airplay-server -============== +# airplay-server An AirPlay server + +## Installation + +``` +npm install airplay-server +``` + +## Example usage + +```javascript +var airplay = require('airplay-server')('My AirPlay Server'); + +airplay.on('request', function (req, res) { + // do your stuff +}); + +airplay.listen(5000); // start server on port 5000 +``` + +## API + +### Constructor + +Get the constructor by requireing the `airplay-server` node module and +call it. It takes the optional arguments `name`, `options` and +`onRequest`. Either of them can be left out, so calling with only +`options` or only `name` and `onRequest` is ok: + +```javascript +require('airplay-server')(name, options, onRequest); +``` + +Constructor arguments: + +- `name` - name of the AirPlay server (default: 'Node.js') +- `options` - options object (default: {}) +- `onRequest` - callback function called upon each request (default: No listener is added. Remember to manually listen on the `request` event) + +Options: + +- `features` - A features bit-mask (default: all features) + +### Server + +The constructor returns a basic Node.js HTTP server, so remember to call +`.listen()` and optionally add a `request` event listener if one hasn't +been provided as an argument to the constructor. + +## License + +MIT diff --git a/index.js b/index.js index 4eb4027..9937229 100644 --- a/index.js +++ b/index.js @@ -5,11 +5,31 @@ var mdns = require('mdns'); var getmac = require('getmac'); var debug = require('debug')('airplay'); -var airplay = module.exports = function (onRequest) { +var pkg = require('./package.json'); + +var airplay = module.exports = function (name, options, onRequest) { + if (typeof name === 'object') { + options = name; + name = undefined; + } else if (typeof name === 'function') { + onRequest = name; + name = undefined; + } else if (typeof options === 'function') { + onRequest = options; + options = undefined; + } + if (!options) options = {}; + if (!options.name) options.name = name || 'Node.js'; + if (!options.features) options.features = allFeatures; + + airplay.options = options; + var server = http.createServer(onRequest); + server.on('listening', function () { start(server.address().port); }); + return server; }; @@ -28,23 +48,27 @@ var features = airplay.features = { PHOTO_CACHING: 2048 // photo preloading supported }; +var allFeatures = Object.keys(features) + .reduce(function (a, b) { + return features[a] | features[b]; + }); + var start = function (port) { debug('Getting server MAC address'); getmac.getMac(function (err, mac) { if (err) throw err; - var featureMask = '0x' + Object.keys(features).reduce(function (a, b) { return features[a] | features[b]; }).toString(16); + var featureMask = '0x' + airplay.options.features.toString(16); + var model = 'NodeAirPlay' + pkg.version.split('.').slice(0,-1).join(','); + var options = { - name: 'Node.js', + name: airplay.options.name, txtRecord: { - deviceid: mac.toUpperCase(), - features: '0x100029ff', - vv: '1', - rhd: '1.06.5', - pw: '0', - srcvers: '150.33', - rmodel: 'MacBookAir4,2', - model: 'AppleTV3,1' + deviceid: mac.toUpperCase(), // MAC address of the device + features: featureMask, // bitfield of supported features + model: model, // device model + pw: '0', // server is password protected + srcvers: pkg.version // server version } };