Skip to content

Instantly share code, notes, and snippets.

@whmountains
Created November 10, 2014 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whmountains/bb95194709b269495d16 to your computer and use it in GitHub Desktop.
Save whmountains/bb95194709b269495d16 to your computer and use it in GitHub Desktop.
bug with node-groove
var _ = require('lodash');
var groove = require('groove');
var l = require('../../l/l.js');
var util = require('util');
var events = require('events');
var async = require('async');
var EventEmitter = require('events').EventEmitter;
var Debug = require('debug');
var File = function(file, fileReady) {
this._debug = Debug('groove:File');
this._gf = {};
//assign a short name to the debug function
var d = this._debug;
d('creating new file');
//if the file argument is a string then it must be the path to the file
if (_.isString(file)) {
d('input is string so we\'ll try to to open a file at that path');
d('input=%s', file);
groove.open(file, function(err, file) {
if (!err) {
d("file opened successfully");
//assign groove's file object to an internal property
this._gf = file;
//call the callback
fileReady(null);
}
else {
d('error opening file');
fileReady(err);
}
});
}
//check if the file is already a File object
//(this allows more flexible coding)
else if (file instanceof File) {
d("`file` argument is already a file object so we just return it");
return file;
}
//check if the file is a groove file object
//we already know it isn't an instance of File so any object
//is probably a groove file object
else if ((typeof file === 'object') && (file.filename !== undefined)) {
d("recieved a groove file object so we're just wrapping it");
this._gf = file;
fileReady(null);
}
//we don't recognize the file paremeter
else {
d("unrecognized file object");
//call the callback with the error set as true
fileReady(true);
return false;
}
};
//we still need to wrap all of groove's native file methods
File.prototype.length = function() {
return this._gf.length;
};
var Playlist = function(files, plReady) {
//save `this` so we can access it anywhere within the constructor
var self = this;
self._debug = Debug('groove:Playlist');
//assign a short name to the debug function
var d = this._debug;
d("creating new Playlist object");
//see the File constructor for an idea of what we're doing here
if (files instanceof Playlist) {
d("returning first argument 'cause we were passed a instance of ourself");
plReady(null);
return files;
}
else if (files.gain !== undefined) {
d("wrapping a groove playlist");
self._gpl = files;
}
else {//we have an array/single item of things to make into a playlist
d("we've got an array/single item of things to make into a playlist");
d("creating a groove playlist");
//create the groove playlist
self._gpl = groove.createPlaylist();
//turn the single item into an array if it isn't one already
if (! _.isArray(files)) {
files = [files];
}
d("opening the files");
//asynchronously open all the files that we were passed
async.each(files, function(fileParam, fileReady) {
d("opening", fileParam, "and inserting it into the playlist");
var fileObj = new File(fileParam, function(err) {
if (!err) {
self._gpl.insert(fileObj._gf);
d("success in opening file");
}
else d("failed to open file");
fileReady(err);
});
},function(err) {
if (!err) d("successfully created playlist");
else d("failed to create playlist");
plReady(err); //the playlist is finally ready
});
}
};
//files can be an array or a single file
var Fingerprinter = function(files, allPrinted) {
this._debug = Debug('groove:Fingerprinter');
this._prints = [];
this._returnArray = true;
var d = this._debug;
//ref to the the current state of `this` so we can emit events even from
//inside event handlers of other event emitters
var printerHandle = this;
d("creating new Fingerprinter");
if (! _.isArray(files)) {
d("converting non array `files` argument into an array");
files = [files];
//don't give an array as a result because we weren't passed an array
this._returnArray = false;
}
//call the callback when everything is printed
printerHandle.on('allPrinted', function(prints) {
if (_.isFunction(allPrinted)) {
d("calling callback which was passed as paremeter to constructor");
allPrinted(prints);
}
});
d("pushing actual playlist creation to end of event" +
"queue to allow time for the creation of event listeners");
//give the caller a chance to set up event listeners
process.nextTick(function() {
d("Creating a new playlist the files array.");
//create a new playlist object
this._playlist = new Playlist(files, function(err) {
if (err) {
d("Error creating playlist:", err);
}
else d("Playlist created successfully");
//emit an event indicating that the playlist is ready
printerHandle.emit('playlistReady');
d("Creating a groove fingerprinter and attaching the playlist.");
var printer = groove.createFingerprinter();
printer.attach(this._playlist._gpl);
d("Waiting for the fingerprinter...");
printer.on('info', function() {
d("info event emitted by the fingerprinter");
//get the info
var info = printer.getInfo();
d("info:", info);
//add it to the prints array
this._prints.push(info);
//don't emit the 'printed' event if we've already printed all of the files
//(the printer sometimes emits spurious prints)
if (this._prints.length <= files.length) {
d("emitting printed event with the info we just got");
printerHandle.emit('printed', info);
}
else d("Doing nothing because we've already dealt with all the files.");
//emit the 'allPrinted' event if we're done
if (this._prints.length === files.length) {
d("also emitting 'allPrinted' event because we've printed the last file");
if (this._returnArray === true) {
d("emitting event with array paremeter because we printed multiple files");
printerHandle.emit('allPrinted', _prints);
}
else {
d("Not calling event handlers with array because we were only passed a single file.");
printerHandle.emit('allPrinted', info);
}
}
});
});
});
};
util.inherits(Fingerprinter, EventEmitter);
module.exports.File = File;
module.exports.openFile = function(path, cb) {
return new File(path, cb);
};
module.exports.Playlist = Playlist;
module.exports.newPlaylist = function(files, cb) {
return new Playlist(files, cb);
};
module.exports.Fingerprinter = Fingerprinter;
module.exports.getFingerprint = function(file, allPrinted) {
return new Fingerprinter(file, allPrinted);
};
lodash = require('lodash');
debug = require('debug')('testfile');
groove = require('./groove.js');
debug('starting test');
//no problem opening the file
debug('opening file');
var file = groove.openFile(process.argv[2], function(err) {
debug('opened file');
if (err) debug("err=%s", err);
});
//groove crashes when opening the file from the fingerprinter object
debug('getting fingerprint');
var print = groove.getFingerprint(process.argv[2], function(print) {
debug('got fingerprint');
debug(print);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment