Skip to content

Instantly share code, notes, and snippets.

@Technoash
Created September 18, 2016 16:16
Show Gist options
  • Select an option

  • Save Technoash/f4ac7da95087ba9ca84b7806ecfbd6ec to your computer and use it in GitHub Desktop.

Select an option

Save Technoash/f4ac7da95087ba9ca84b7806ecfbd6ec to your computer and use it in GitHub Desktop.
var http = require('http');
var fs = require('fs');
var PassThrough = require('stream').PassThrough;
var lame = require('lame');
var spawn = require('child_process').spawn
var random = require("random-js")();
var streams = [];
var playlistDB = [{
title: 'Detrooklyn',
tracks: fs.readdirSync('files')
}];
console.log(playlistDB[0].tracks.length);
function Mixer(){
this.inStream = null;
this.input = new PassThrough();
this.startTime = null;
this.bytesCommited = 0;
this.output = new PassThrough();
this.bps = 176400;
var self = this;
function a(){
if(self.startTime == null) {
self.startTime = Date.now();
self.commit();
}
setTimeout(function(){
self.commit();
a();
}, 4);
}
a()
}
Mixer.prototype.attach = function(stream) {
if(this.inStream !== null) this.inStream.unpipe(this.input);
this.inStream = stream;
this.inStream.pipe(this.input, {end: false});
}
Mixer.prototype.commit = function() {
//var start = Date.now();
var processSize = Math.ceil((((Date.now()-this.startTime)/1000)*this.bps - this.bytesCommited)/8)*8;
var out = this.input.read(processSize);
if(out == null || out.length != processSize) out = Buffer.alloc(processSize);
this.output.write(out);
this.bytesCommited += processSize;
//console.log("took", Date.now()-start, 'did', processSize);
};
function Stream(playlistID){
this.listeners = 0;
this.playlist = playlistDB[playlistID];
this.trackID = 0;
this.mixer = new Mixer();
this.encoder = new lame.Encoder({
// input
channels: 2, // 2 channels (left and right)
bitDepth: 16, // 16-bit samples
sampleRate: 44100, // 44,100 Hz sample rate
// output
bitRate: 192,
outSampleRate: 44100,
mode: lame.STEREO // STEREO (default), JOINTSTEREO, DUALCHANNEL or MONO
});
this.mixer.output.pipe(this.encoder);
this.changeTrack();
this.play();
}
Stream.prototype.changeTrack = function(){
this.trackID = random.integer(0, this.playlist.tracks.length-1);
//this.trackID = Math.floor(Math.random() * this.playlist.tracks.length);
}
Stream.prototype.play = function(){
console.log("playing", this.playlist.tracks[this.trackID]);
var me = this;
var vlcPs = spawn('ffmpeg', ['-i', 'files/'+this.playlist.tracks[this.trackID], '-vn', '-filter', 'volume=-12dB,equalizer=f=35:width_type=q:width=8.93:g=12', '-ar', '44100', '-ac', '2', '-acodec', 'pcm_s16le', '-f', 's16le', '-acodec', 'pcm_s16le', '-']);
me.mixer.attach(vlcPs.stdout);
vlcPs.addListener('close', function(){
console.log('track finished');
me.changeTrack();
me.play();
});
}
http.createServer(function(request, response) {
response.writeHead(200, {
//'Content-Type': 'audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3'
//'Content-Type': 'audio/pcm'
'Content-type': 'audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3'
});
var streamid="007";
if(typeof streams[streamid] == 'undefined'){
streams[streamid] = new Stream(0);
}
var i = 0;
function sendData(data){
if(i % 40 == 0) console.log("encoded update", i, request.connection.remoteAddress);
response.write(data);
i++;
}
streams[streamid].encoder.on('data', sendData);
request.on('close', function(err) {
streams[streamid].encoder.removeListener('data', sendData);
response.end();
});
})
.listen(9000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment