Skip to content
This repository has been archived by the owner on Dec 12, 2022. It is now read-only.

Commit

Permalink
Refactor components into separate files
Browse files Browse the repository at this point in the history
Closes #4
  • Loading branch information
maherbeg committed Feb 9, 2014
1 parent cbc507b commit fda4af2
Show file tree
Hide file tree
Showing 15 changed files with 343 additions and 231 deletions.
12 changes: 12 additions & 0 deletions lib/config/environment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var path = require('path');

module.exports = function(app, express) {
var libRoot = __dirname + '/../';

// TODO Setup .bowerrc
app.use('/components', express.static(path.resolve(libRoot + '../bower_components')));
app.use('/static', express.static(path.resolve(libRoot + '../static')));

app.set('views', path.resolve(libRoot + 'views'));
app.set('view engine', 'jade');
};
14 changes: 14 additions & 0 deletions lib/config/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var fs = require('fs');
var path = require('path');

var requireController = function(controllerName) {
return require('../controllers/' + controllerName);
};

module.exports = function(app) {
app.get('/list', requireController('list-root-directory'));
app.get('/list/*', requireController('list-directory'));

app.get('/send*', requireController('send-file'));
app.get('/stream*', requireController('stream-file'));
};
86 changes: 86 additions & 0 deletions lib/controllers/list-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
var fs = require('fs');
var path = require('path');
var utils = require('../utils');

/**
* Filters out file extensions that are not supported by this application.
* @param {String} filePath
* @param {Function} A filter predicate
*/
var filterDirectoryContents = function(filePath) {
var streamableFileExtensions = utils.constants.streamableFileExtensions;

/**
* A filter predicate for a given file.
* @param {String} file A file to verify is valid.
* @return {Boolean} Whether the file is valid or not.
*/
return function(file) {

if (fs.statSync(path.join(filePath, file)).isDirectory()) {
return true;
}

return streamableFileExtensions.some(function(fileExt) {
return file.search(fileExt + '$') !== -1;
});
};
};

/**
* Maps a directory of files to an object containing metadata about each file.
* @param {String} filePath
* @return {Function} Containing details on each file in a given filePath
*/
var mapDirectoryContentsToDetailsObject = function(filePath) {
/**
* Returns an object with metadata bout a given file.
* @param {String} file
* @return {Object}
*/
return function(file) {
var fileStats = fs.statSync(path.join(filePath, file));

return {
displayName : utils.strings.normalizeFileName(file, fileStats.isDirectory()),
filePath : path.join(filePath, file),
isDirectory : fileStats.isDirectory(),
mediaType : 'tv'
};
};
};

/**
* Splits a directory into its normalized parts.
* @param {String} filePath
* @return {Array} Filepath's split by the directory separator.
*/
var extractDirectoryPaths = function(filePath) {
return filePath.split('/').filter(function(element) {
return !!element;
}) || []
};

var playbackInfo = {};

global.playbackInfoEmitter.on('update', function(pi) {
playbackInfo = pi;
});

module.exports = function(req, res) {
var filePath = req.params[0];

if (!filePath) {
require('list-root-directory')(req, res);
}

var dirContents = fs.readdirSync(filePath)
.filter(filterDirectoryContents(filePath))
.map(mapDirectoryContentsToDetailsObject(filePath));

res.render('list', {
dirContents : dirContents,
dirPaths : extractDirectoryPaths(filePath),
nowPlaying : utils.strings.nowPlayingString(playbackInfo)
});
};
24 changes: 24 additions & 0 deletions lib/controllers/list-root-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var utils = require('../utils');

var playbackInfo = {};

global.playbackInfoEmitter.on('update', function(pi) {
playbackInfo = pi;
});

module.exports = function(req, res) {
var mediaDirectories = global.config['mediaDirectories'];

mediaDirectories = mediaDirectories.map(function(mediaDir) {
return {
displayName : mediaDir,
filePath : mediaDir,
isDirectory : true
};
});

res.render('list', {
dirContents : mediaDirectories,
nowPlaying : utils.strings.nowPlayingString(playbackInfo)
});
};
16 changes: 16 additions & 0 deletions lib/controllers/send-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var utils = require('../utils');

module.exports = function(req, res) {
var playbackInfo = {};

playbackInfo.nowPlaying = req.params[0];
playbackInfo.startTime = req.query.startTime || '00:00:00'
playbackInfo.startTimeSeconds = utils.strings.convertTimeToSeconds(playbackInfo.startTime);

global.playbackInfoEmitter.emit('update', playbackInfo);

res.render('sender', {
mediaUrl : 'http://' + utils.network.ipAddress + ':1338/stream/' + playbackInfo.nowPlaying,
appId : global.config['applicationId']
});
};
34 changes: 34 additions & 0 deletions lib/controllers/stream-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
var fs = require('fs');
var spawn = require('child_process').spawn;

module.exports = function(req, res) {
var fileToStream = req.params[0];
var fsStats = fs.statSync(fileToStream);

res.setHeader('Content-Type', 'video/x-matroska');
res.setHeader('Content-Disposition','inline; filename=' + fileToStream + ';');
res.setHeader('Content-Transfer-Encoding', 'binary');
res.setHeader('Content-Length', fsStats.size);

var videoEncodingType = /(mkv|mp4)$/.test(fileToStream) ? 'copy' : 'libx264';

// TODO pipe playback time
var ffmpeg = spawn('ffmpeg',
['-ss', '00:00:00', '-i', fileToStream, '-c:v', videoEncodingType, '-c:a', 'libfaac', '-ac', '2', '-ab', '192k', '-f', 'matroska', '-']);

var closeFfmpeg = function() {
ffmpeg.stdout.unpipe(res);
ffmpeg.stderr.unpipe(process.stdout);

// SIGINT is apparently not being respected...
ffmpeg.kill('SIGKILL');
};

res.on('close', closeFfmpeg);
res.on('end', closeFfmpeg);

ffmpeg.on('exit', closeFfmpeg);

ffmpeg.stdout.pipe(res);
ffmpeg.stderr.pipe(process.stdout);
};
Loading

0 comments on commit fda4af2

Please sign in to comment.