Created
November 5, 2014 22:09
-
-
Save auchenberg/6bbc521fa68398e29e7d to your computer and use it in GitHub Desktop.
nicercast + ffmpeg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var express = require('express'); | |
var http = require('http'); | |
var spawn = require("child_process").spawn; | |
var icecast = require('icecast-stack'); | |
var Throttle = require('throttle'); | |
var ip = require('ip'); | |
var ffmpeg = require('fluent-ffmpeg'); | |
var Server = function(inStream, opts) { | |
var app = express(); | |
this.app = app; | |
this.serverPort = false; | |
app.disable('x-powered-by'); | |
opts.name = opts.name || 'Nicercast'; | |
var outputStream = new require('stream').PassThrough(); //new Throttle(BYTES_PER_SECOND); | |
// // stream playlist (points to other endpoint) | |
var playlistEndpoint = function(req, res) { | |
var addr = ip.address(); | |
res.status(200); | |
res.set('Content-Type', 'audio/x-mpegurl'); | |
res.send('http://' + addr + ':' + this.serverPort + '/listen'); | |
console.log('http://' + addr + ':' + this.serverPort + '/listen'); | |
}.bind(this); | |
app.get('/', playlistEndpoint); | |
app.get('/listen.m3u', playlistEndpoint); | |
app.get('/listen', function(req, res, next) { | |
ffmpeg({ source: inStream, nolog: true }) | |
.on('end', function() { | |
console.log('done processing input stream'); | |
}) | |
.on('error', function(err) { | |
console.log('an error happened: ' + err.message); | |
}) | |
.pipe(outputStream); | |
var acceptsMetadata = req.headers['icy-metadata'] == 1; | |
var parsed = require('url').parse(req.url, true); | |
// generate response header | |
var headers = { | |
"Content-Type": 'audio/mpeg', | |
"Connection" : 'close' | |
}; | |
if (acceptsMetadata) { | |
headers['icy-metaint'] = 8192; | |
} | |
res.writeHead(200, headers); | |
// setup metadata transport | |
if (acceptsMetadata) { | |
res = new icecast.IcecastWriteStack(res, 8192); | |
res.queueMetadata(this.metadata || opts.name); | |
} | |
var prevMetadata = 0; | |
var callback = function(chunk) { | |
if (acceptsMetadata && prevMetadata != this.metadata) { | |
res.queueMetadata(this.metadata || opts.name); | |
prevMetadata = this.metadata; | |
} | |
res.write(chunk); | |
}.bind(this) | |
outputStream.on("data", callback); | |
req.connection.on("close", function() { | |
outputStream.removeListener("data", callback); | |
}); | |
}.bind(this)); | |
} | |
Server.prototype.start = function(port) { | |
this.serverPort = port || 8001; | |
this.server = http.createServer(this.app).listen(this.serverPort); | |
} | |
Server.prototype.setMetadata = function(metadata) { | |
this.metadata = metadata; | |
}; | |
Server.prototype.stop = function() { | |
try { | |
this.server.close(); | |
} catch (err) { | |
} | |
} | |
module.exports = Server; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment