Permalink
Browse files

adding basic content serving (no transcoding) from local fs

  • Loading branch information...
1 parent 3ac38d6 commit ff446152d1b984dcb9202d3e970e2379928882f0 @benvanik committed Nov 7, 2011
Showing with 124 additions and 8 deletions.
  1. +2 −1 README.md
  2. +119 −4 content.js
  3. +0 −1 transcoder.js
  4. +3 −2 transcoderlist.js
View
@@ -49,7 +49,8 @@ Setup a new content serving request:
POST /content/setup
{
source: {
- content: string
+ content: string,
+ mimeType: string // 'video/webm'
},
target: {
mimeType: string, // 'video/mp4'
View
@@ -1,7 +1,20 @@
+var fs = require('fs');
+var url = require('url');
+var util = require('util');
+
+var transcoderList = require('./transcoderlist').transcoderList;
+
var Content = function(id, source, target) {
this.id = id;
- this.source = source;
- this.target = target;
+ this.source = {
+ content: source.content,
+ mimeType: source.mimeType || undefined
+ };
+ this.target = {
+ mimeType: target.mimeType || undefined,
+ resolution: target.resolution || undefined,
+ quality: target.quality || undefined
+ };
this.cached_ = false;
this.seekable_ = false;
@@ -22,9 +35,111 @@ Content.prototype.matches = function(source, target) {
};
Content.prototype.get = function(req, res) {
- res.writeHead(200, {
- 'Content-Type': 'text/plain'
+ // Attempt to create a transcoder - may be null
+ var transcoder = transcoderList.createTranscoder(this.source, this.target);
+
+ var sourceUrl = url.parse(this.source.content);
+ switch (sourceUrl.protocol) {
+ case 'file:':
+ if (transcoder) {
+ this.transcodingHttpGet(req, res, sourceUrl, transcoder);
+ } else {
+ this.straightFileGet(req, res, sourceUrl);
+ }
+ return;
+ case 'http:':
+ case 'https:':
+ if (transcoder) {
+ this.transcodingHttpGet(req, res, sourceUrl, transcoder);
+ } else {
+ this.straightHttpGet(req, res, sourceUrl);
+ }
+ return;
+ default:
+ res.writeHead(415, 'Unsupported Media Type');
+ res.end();
+ return;
+ }
+};
+
+Content.prototype.straightFileGet = function(req, res, sourceUrl) {
+ var filename = decodeURI(sourceUrl.pathname);
+ fs.stat(filename, function(err, stats) {
+ if (err) {
+ res.writeHead(404, 'Not Found');
+ res.end();
+ return;
+ }
+
+ // TODO: proper content type
+ var mimeType = 'application/octet-stream';
+
+ var mtime = Date.parse(stats.mtime);
+ var etag = JSON.stringify([stats.ino, stats.size, mtime].join('-'));
+ var headers = {
+ 'Cache-Control': 'max-age=' + (60 * 60 * 24 * 7),
+ 'Date': new(Date)().toUTCString(),
+ 'Last-Modified': new(Date)(stats.mtime).toUTCString(),
+ 'Etag': etag,
+ 'Content-Type': mimeType,
+ 'Accept-Ranges': 'bytes'
+ };
+
+ if (req.headers['if-none-match'] == etag ||
+ Date.parse(req.headers['if-modified-since']) >= mtime) {
+ headers['Content-Length'] = stats.size;
+ res.writeHead(304, headers);
+ res.end();
+ return;
+ } else if (req.method == 'HEAD') {
+ headers['Content-Length'] = stats.size;
+ res.writeHead(200, headers);
+ res.end();
+ return;
+ }
+
+ var start = 0;
+ var end = stats.size;
+ if (req.headers['range']) {
+ var range = req.headers['range'].match(/([0-9]+)-([0-9]+)/);
+ start = parseInt(range[1]);
+ end = parseInt(range[2]);
+ headers['Content-Length'] = end - start;
+ if (start != 0 && end != stats.size) {
+ headers['Content-Range'] = 'bytes ' + start + '-' + end + '/' +
+ stats.size;
+ res.writeHead(206, headers);
+ } else {
+ res.writeHead(200, headers);
+ }
+ } else {
+ headers['Content-Length'] = stats.size;
+ res.writeHead(200, headers);
+ }
+ fs.createReadStream(filename, {
+ flags: 'r',
+ mode: 0666,
+ bufferSize: 64 * 1024
+ }).pipe(res, {
+ end: true
+ });
+ return;
});
+};
+
+Content.prototype.straightHttpGet = function(req, res, sourceUrl) {
+ // proxy
+};
+
+Content.prototype.transcodingFileGet = function(req, res, sourceUrl,
+ transcoder) {
+ res.writeHead(501, 'Not Implemented');
+ res.end();
+};
+
+Content.prototype.transcodingHttpGet = function(req, res, sourceUrl,
+ transcoder) {
+ res.writeHead(501, 'Not Implemented');
res.end();
};
View
@@ -22,6 +22,5 @@ NullTranscoder.canTranscode = function(sourceMimeType, targetMimeType) {
// Order is highest to lowest priority
exports.transcoderTypes = [
- FfmpegTranscoder,
NullTranscoder
];
View
@@ -3,7 +3,6 @@ var transcoderTypes = require('./transcoder').transcoderTypes;
var TranscoderList = function() {
this.transcoderTypes_ = transcoderTypes.slice();
};
-exports.TranscoderList = TranscoderList;
TranscoderList.prototype.find_ = function(sourceMimeType, targetMimeType) {
for (var n = 0; n < this.transcoderTypes_.length; n++) {
@@ -18,9 +17,11 @@ TranscoderList.prototype.find_ = function(sourceMimeType, targetMimeType) {
TranscoderList.prototype.createTranscoder = function(source, target) {
var transcoderType = this.find_(source.mimeType, target.mimeType);
if (!transcoderType) {
- return false;
+ return null;
}
var transcoder = new transcoderType(source, target);
// TODO: verify?
return transcoder;
};
+
+exports.transcoderList = new TranscoderList();

0 comments on commit ff44615

Please sign in to comment.