Comparing version 0.0.2 to 0.0.3
@@ -1,1 +0,3 @@ | ||
module.exports = require(__dirname + '/lib/start.js'); | ||
"use strict"; | ||
module.exports = require(__dirname + '/lib/start.js'); |
@@ -0,3 +1,5 @@ | ||
"use strict"; | ||
var dgram = require('dgram'); | ||
var tools = require('./rtsphelper'); | ||
var tools = require('./rtspHelper'); | ||
var crypto = require('crypto'); | ||
@@ -7,35 +9,44 @@ | ||
var self = this; | ||
var baseServer = dgram.createSocket('udp4'); | ||
var controlServer = dgram.createSocket('udp4'); | ||
var timingServer = dgram.createSocket('udp4'); | ||
var crypto = require('crypto'); | ||
self.start = function() { | ||
baseServer.bind(rtspServer.audioPort); | ||
controlServer.bind(rtspServer.controlPort); | ||
timingServer.bind(rtspServer.timingPort); | ||
}; | ||
self.baseServer = dgram.createSocket('udp4'); | ||
self.controlServer = dgram.createSocket('udp4'); | ||
self.timingServer = dgram.createSocket('udp4'); | ||
baseServer.on('message', function(msg) { | ||
var meta = msg.slice(0, 12); | ||
var sequenceNumber = meta.slice(2, 4).readUInt16BE(0); | ||
self.baseServer.bind(rtspServer.ports[0]); | ||
self.controlServer.bind(rtspServer.ports[1]); | ||
self.timingServer.bind(rtspServer.ports[2]); | ||
var encryptedAudio = msg.slice(12); | ||
self.baseServer.on('message', function(msg) { | ||
var meta = msg.slice(0, 12); | ||
var sequenceNumber = meta.slice(2, 4).readUInt16BE(0); | ||
var decipher = crypto.createDecipheriv('aes-128-cbc', rtspServer.audioAesKey, rtspServer.audioAesIv); | ||
decipher.setAutoPadding(false); | ||
var encryptedAudio = msg.slice(12); | ||
var audio = decipher.update(encryptedAudio); | ||
var decipher = crypto.createDecipheriv('aes-128-cbc', rtspServer.audioAesKey, rtspServer.audioAesIv); | ||
decipher.setAutoPadding(false); | ||
rtspServer.audioProcessor.process(audio, sequenceNumber); | ||
var audio = decipher.update(encryptedAudio); | ||
}); | ||
controlServer.on('message', function(msg) { | ||
console.log(msg.length + ' BYTES SENT TO CONTROL PORT'); | ||
}); | ||
timingServer.on('message', function(msg) { | ||
console.log(msg.length + ' BYTES SENT TO TIMING PORT'); | ||
}); | ||
rtspServer.audioProcessor.process(audio, sequenceNumber); | ||
}); | ||
self.controlServer.on('message', function(msg) { | ||
var timestamp = msg.readUInt32BE(4); | ||
}); | ||
self.timingServer.on('message', function(msg) { | ||
//console.log(msg.length + ' BYTES SENT TO TIMING PORT'); | ||
}); | ||
}; | ||
self.stop = function() { | ||
self.baseServer.close(); | ||
self.controlServer.close(); | ||
self.timingServer.close(); | ||
} | ||
} | ||
module.exports = rtpServer; | ||
module.exports = rtpServer; |
@@ -0,19 +1,15 @@ | ||
"use strict"; | ||
var net = require('net'); | ||
var tools = require('./rtsphelper'); | ||
var tools = require('./rtspHelper'); | ||
var RtpServer = require('./rtp'); | ||
var AudioProcessor = require('./audioprocessor'); | ||
var AudioProcessor = require('./audioProcessor'); | ||
var errorList = { | ||
400: "BAD REQUEST" | ||
}; | ||
var server = function(options, external) { | ||
var self = this; | ||
var server = function(options) { | ||
var self = this; | ||
self.external = external; | ||
self.options = options; | ||
self.audioPort = options.audioPort; | ||
self.controlPort = options.controlPort; | ||
self.timingPort = options.timingPort; | ||
self.ports = []; | ||
@@ -23,3 +19,3 @@ self.rtp = new RtpServer(self); | ||
self.macAddress = '5F513885F785'; | ||
self.metadata = {}; | ||
// pull method processors | ||
@@ -33,5 +29,5 @@ var methodMapping = require('./rtspmethods')(self); | ||
// debug: dump message | ||
console.log('INSPECTING HEADER @ ' + socket.id.getTime()); | ||
console.log('`--: ' + msg.replace(/\r\n/g, '\r\n`--: ')); | ||
console.log('END HEADER\n\n'); | ||
//console.log('INSPECTING HEADER @ ' + socket.id.getTime()); | ||
//console.log('`--: ' + msg.replace(/\r\n/g, '\r\n`--: ')); | ||
//console.log('END HEADER\n\n'); | ||
@@ -46,7 +42,7 @@ // parse out the direction and header | ||
for (var i = 1; i < lines.length; i++) { | ||
var header = lines[i].split(':'); | ||
var header = [ lines[i].substr(0, lines[i].indexOf(':')), lines[i].substr(lines[i].indexOf(':')+1) ]; | ||
if (header.length != 2) { | ||
response.sendError(socket, 400); | ||
return; | ||
response.sendError(400); | ||
return { "success" : false }; | ||
} | ||
@@ -63,6 +59,6 @@ | ||
if (headers.hasOwnProperty('Content-Length')) { | ||
return { "method" : method, "response" : response, "headers" : headers, hasContent: true, contentLength: headers['Content-Length'] }; | ||
return { "success" : true, "method" : method, "response" : response, "headers" : headers, hasContent: true, contentLength: headers['Content-Length'] }; | ||
} | ||
return { "method" : method, "response" : response, "headers" : headers, hasContent: false, contentLength: 0 }; | ||
return { "success" : true, "method" : method, "response" : response, "headers" : headers, hasContent: false, contentLength: 0 }; | ||
}; | ||
@@ -73,8 +69,10 @@ | ||
var buffer = ''; | ||
var binBuffer = null; // used only for binary content (e.g. dmap) | ||
var hasContent = false; | ||
var remaining = -1; | ||
var terminator = '\r\n\r\n'; | ||
var headerData = null; | ||
socket.id = new Date(); | ||
console.log('OPENED CONNECTION @ ' + socket.id.getTime()); | ||
//console.log('OPENED CONNECTION @ ' + socket.id.getTime()); | ||
socket.on('data', function(c) { | ||
@@ -86,5 +84,6 @@ | ||
remaining -= c.length; | ||
Buffer.concat([ binBuffer, c ]); | ||
//console.log('WAITING ON ' + remaining + ' BYTES OF CONTENT REMAINING (ONGOING)'); | ||
} | ||
// check for termination, so we can pass on a header | ||
@@ -98,3 +97,3 @@ if (buffer.indexOf(terminator) >= 0) { | ||
if (!headerData.hasContent) { | ||
console.log('CALLING ' + headerData.method + ' WITHOUT CONTENT'); | ||
//console.log('CALLING ' + headerData.method + ' WITHOUT CONTENT'); | ||
methodMapping[headerData.method](headerData.response, headerData.headers); | ||
@@ -112,15 +111,16 @@ //console.log('END CALL\n\n'); | ||
// check the buffer to make sure stuff isn't overlooked | ||
binBuffer = c.slice(buffer.indexOf(terminator) + 4); | ||
buffer = msgs[msgs.length - 1] + '\r\n'; // compensate? | ||
remaining -= buffer.length; | ||
console.log('WAITING ON ' + remaining + ' BYTES OF CONTENT REMAINING (INITIAL)'); | ||
console.log('`--: ' + buffer.replace(/\r\n/g, '\r\n`--: ')); | ||
//console.log('WAITING ON ' + remaining + ' BYTES OF CONTENT REMAINING (INITIAL)'); | ||
//console.log('`--: ' + buffer.replace(/\r\n/g, '\r\n`--: ')); | ||
} | ||
} | ||
if (remaining <= 0 && hasContent) { | ||
console.log('CALLING ' + headerData.method + ' WITH FOLLOWING CONTENT'); | ||
console.log('`--: ' + buffer.replace(/\r\n/g, '\r\n`--: ')); | ||
methodMapping[headerData.method](headerData.response, headerData.headers, buffer); | ||
if (remaining <= 0 && hasContent && headerData) { | ||
//console.log('CALLING ' + headerData.method + ' WITH FOLLOWING CONTENT'); | ||
//console.log('`--: ' + buffer.replace(/\r\n/g, '\r\n`--: ')); | ||
methodMapping[headerData.method](headerData.response, headerData.headers, binBuffer); | ||
//console.log('END CALL\n\n'); | ||
binBuffer = null; | ||
buffer = ''; | ||
@@ -132,6 +132,2 @@ hasContent = false; | ||
socket.on('close', function() { | ||
console.log('END CONNECTION'); | ||
}) | ||
}; | ||
@@ -142,2 +138,2 @@ | ||
module.exports.Server = server; | ||
module.exports = server; |
@@ -0,7 +1,10 @@ | ||
"use strict"; | ||
var mdns = require('mdns2'); | ||
var net = require('net'); | ||
var rtsp = require('./rtsp'); | ||
var RtspServer = require('./rtsp'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var airTunesServer = function(outStream, options) { | ||
var NodeTunes = function(outStream, options) { | ||
var self = this; | ||
var options = options || {}; | ||
@@ -19,14 +22,2 @@ | ||
if (!options.audioPort) { | ||
options.audioPort = 53561; | ||
} | ||
if (!options.controlPort) { | ||
options.controlPort = 63379; | ||
} | ||
if (!options.timingPort) { | ||
options.timingPort = 50607; | ||
} | ||
var txtSetup = { | ||
@@ -39,3 +30,3 @@ txtvers: '1', // txt record version? | ||
md: '0', // metadata; 0=text, 1=artwork, 2=progress | ||
pw: 'false', // password enabled | ||
pw: (options.password ? 'true' : 'false'), // password enabled | ||
sr: '44100', // sampling rate (e.g. 44.1KHz) | ||
@@ -54,13 +45,22 @@ ss: '16', // sample size (e.g. 16 bit?) | ||
var server = new rtsp.Server(options); | ||
var netServer = null; | ||
var rtspServer = new RtspServer(options, self); | ||
net.createServer(server.handler).listen(5000, function() { | ||
var ad = mdns.createAdvertisement(mdns.tcp('raop'), 5000, { | ||
name: options.macAddress + '@' + options.serverName, | ||
txtRecord: txtSetup | ||
NodeTunes.prototype.start = function() { | ||
netServer = net.createServer(rtspServer.handler).listen(5000, function() { | ||
var ad = mdns.createAdvertisement(mdns.tcp('raop'), 5000, { | ||
name: options.macAddress + '@' + options.serverName, | ||
txtRecord: txtSetup | ||
}); | ||
}); | ||
console.log('BEGIN BONJOUR ADVERTISING'); | ||
}); | ||
}; | ||
NodeTunes.prototype.stop = function() { | ||
netServer.close(); | ||
}; | ||
}; | ||
NodeTunes.prototype.__proto__ = EventEmitter.prototype; | ||
module.exports = airTunesServer; | ||
module.exports = NodeTunes; |
{ | ||
"name": "nodetunes", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"author": "Stephen Wan <stephen@stephenwan.net>", | ||
@@ -22,3 +22,6 @@ "description": "AirTunes v2 Music Server", | ||
"ursa" : "*", | ||
"ip" : "*" | ||
"ip" : "*", | ||
"priorityqueuejs" : "*", | ||
"portastic" : "*", | ||
"randomstring" : "*" | ||
}, | ||
@@ -25,0 +28,0 @@ "devDependencies" : { |
NodeTunes | ||
============ | ||
========= | ||
@@ -9,2 +9,4 @@ AirTunes v2 implementation in node.js | ||
npm test | ||
``` | ||
``` | ||
See ```test/server.js``` for example usage. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 3 instances in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21988
17
535
11
6
7
4
+ Addedportastic@*
+ Addedpriorityqueuejs@*
+ Addedrandomstring@*
+ Addedbluebird@2.11.0(transitive)
+ Addedcommander@2.20.3(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addedms@2.0.0(transitive)
+ Addedportastic@1.0.1(transitive)
+ Addedpriorityqueuejs@2.0.0(transitive)
+ Addedrandombytes@2.0.3(transitive)
+ Addedrandomstring@1.3.0(transitive)