Skip to content

Commit

Permalink
Closes #10 (provided option to not depend on icecast and ezstream)
Browse files Browse the repository at this point in the history
  • Loading branch information
Balaji committed Oct 12, 2012
1 parent c312469 commit a8c734b
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
5 changes: 4 additions & 1 deletion example/public/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

$(document).ready(function(){

var using_node_icecast= false;
var using_node_icecast= true;

function loadChannelList(){
$.ajax({
Expand Down Expand Up @@ -116,6 +116,9 @@ $(document).ready(function(){
});
JSCast.on("opened", function(stream_url){
//do any initialization required such as sending url to the listeners.
if (using_node_icecast){
$("#audio_player").attr("src", stream_url);
}
JSCast.start();
});
JSCast.on("start", function(){
Expand Down
3 changes: 2 additions & 1 deletion example/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ var options = {
icecast: {
server: "http://localhost:8000/",
sourcepassword: "hackme"
}
},
use_node_icecast: true
};

var app = express();
Expand Down
84 changes: 84 additions & 0 deletions lib/NodeIcecast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* @description: This implements a node based very basic icecast server
* Manages listeners also. All the listeners have to connect before streaming starts.
*/
var fs = require('fs.extra'),
clone = require('clone'),
spawn = require('child_process').spawn,
util = require('util'),
EventEmitter = require('events').EventEmitter ;

var DEFAULT_INACTIVITY_TIMEOUT= 5*60; // 5 minutes
var ARGS_OGGENC= "-B 16 -C 1 -R 22050 --raw-endianness 1 -";

var NodeIcecast= function(id, config_dir, options){
var self= this;

this._id= id;
this._last_activity_ts= Date.now();

this._url= "/js-cast/"+ id +".ogg";
this._name= options.info.name;
this._description= options.info.description;
this._inactivity_timeout= (options.inactivity_timeout || DEFAULT_INACTIVITY_TIMEOUT)*1000;
this._inactivity_timer= setInterval(this.handleInactivityTimer.bind(this), 5000);//5s
EventEmitter.call(this);
};

util.inherits(NodeIcecast, EventEmitter);

NodeIcecast.prototype.getUrl= function(){
return this._url;
};

NodeIcecast.prototype.getName= function(){
return this._name;
};

NodeIcecast.prototype.getDescription= function(){
return this._description;
};

NodeIcecast.prototype.getId= function(){
return this._id;
};

NodeIcecast.prototype.start= function(){
this._spawnProcesses();
};

NodeIcecast.prototype._spawnProcesses= function(){
var self= this;
var oggenc= spawn("oggenc", ARGS_OGGENC.split(" "));
oggenc.on('exit', function(){
self._oggenc= null;
self.emit("end");
})
this._oggenc= oggenc;
this.emit("start");
};

NodeIcecast.prototype.pipe= function(stream){
stream.pipe(this._oggenc.stdin, {end: false});
};

NodeIcecast.prototype.destroy= function(){
this._oggenc.kill('SIGKILL');
this._oggenc= null;
clearInterval(this._inactivity_timer);
};

NodeIcecast.prototype.addListener= function(listener){
this._oggenc.stdout.pipe(listener, {end: false});
};

NodeIcecast.prototype.handleInactivityTimer= function(){
var inactivity_duration= Date.now() - this._last_activity_ts;
if (inactivity_duration > this._inactivity_timeout){
this.emit("data", "Destroying client due to inactivity timeout:" +inactivity_duration);
this.destroy();
}
};

module.exports= NodeIcecast;

10 changes: 8 additions & 2 deletions lib/SourceClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,26 @@ var SourceClient= function(id, config_dir, options){
}
}

this.config= config;

EventEmitter.call(this);
};

SourceClient.prototype.start= function(){
//in node version 0.6.x chmodsync is not working. This is a workaround for that.
var fd= fs.openSync(this._config_file, "w", 0644);
fs.closeSync(fd);

var self= this;
//create config file for ezstream
saveAsXML("ezstream", config, this._config_file, function(err){
saveAsXML("ezstream", this.config, this._config_file, function(err){
if (err){
self.emit("error", "Error creating ezstream config file.", err);
}
else {
self._spawnProcesses();
}
});
EventEmitter.call(this);
};

util.inherits(SourceClient, EventEmitter);
Expand Down
6 changes: 4 additions & 2 deletions lib/js-cast.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ JSCast.prototype.configure= function(app, config){
}
};
var client;
if (this.use_node_icecast) {
if (self.use_node_icecast) {
console.log("using node icecast");
client= new NodeIcecast(id, self._dir, options);
}
else {
Expand All @@ -64,6 +65,7 @@ JSCast.prototype.configure= function(app, config){
client= new SourceClient(id, self._dir, options);
}
self.addEventListeners(client);
client.start();
var data= {
id: id,
url: client.getUrl(),
Expand All @@ -90,7 +92,7 @@ JSCast.prototype.configure= function(app, config){
}
});

if (this.user_node_icecast){
if (this.use_node_icecast){
var headers = {
"Content-Type": "application/ogg",
"Connection": "close",
Expand Down

0 comments on commit a8c734b

Please sign in to comment.