Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

remote content media info detection

  • Loading branch information...
commit 874b030d9a9f8f40c838b046b7f1e23e383d4143 1 parent 8aefe41
Ben Vanik authored
Showing with 112 additions and 29 deletions.
  1. +16 −1 apps/chrome/src/test.html
  2. +78 −28 lib/content.js
  3. +18 −0 lib/temp.js
17 apps/chrome/src/test.html
View
@@ -99,6 +99,19 @@
play(content);
}
+ function waitUntilContentReady(contentId, callback) {
+ var checkReady = function() {
+ service.getContentStatus(contentId, function(status) {
+ if (status.readyToPlay) {
+ callback();
+ } else {
+ window.setTimeout(checkReady, 100);
+ }
+ });
+ };
+ checkReady();
+ }
+
function testContent(url) {
var source = {
content: url
@@ -110,7 +123,9 @@
};
service.setupContent(source, target, function(response) {
var contentId = response.id;
- play(endpoint + '/content/' + contentId);
+ waitUntilContentReady(contentId, function() {
+ play(endpoint + '/content/' + contentId);
+ });
});
}
106 lib/content.js
View
@@ -1,6 +1,7 @@
var fs = require('fs');
var http = require('http');
var mediainfo = require('./mediainfo');
+var temp = require('./temp');
var url = require('url');
var util = require('util');
@@ -29,6 +30,7 @@ var Content = function(id, source, target) {
this.extractMediaInfo_(function(info) {
console.log(util.inspect(info));
self.source.info = info;
+ self.readyToPlay_ = true;
});
};
exports.Content = Content;
@@ -45,6 +47,71 @@ Content.prototype.matches = function(source, target) {
return sourceMatches && targetMatches;
};
+Content.prototype.createRemoteRequest_ = function(method, headers, callback) {
+ var source = this.source;
+ var sourceUrl = url.parse(source.content);
+
+ // Headers to make the requests look more valid
+ headers['Accept'] = '*/*';
+ headers['Accept-Charset'] = 'ISO-8859-1,utf-8;q=0.7,*;q=0.3';
+ headers['Accept-Encoding'] = 'identity;q=1, *;q=0';
+ headers['Accept-Language'] = 'en-US,en;q=0.8';
+ headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) ' +
+ 'AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.930.0 Safari/535.8';
+
+ // Copy user headers
+ if (source.referer) {
+ headers['Referer'] = source.referer;
+ }
+ if (source.cookie) {
+ headers['Cookie'] = source.cookie;
+ }
+
+ var req = http.request({
+ hostname: sourceUrl.hostname,
+ port: sourceUrl.port,
+ method: method,
+ path: sourceUrl.path,
+ headers: headers,
+ auth: source.auth,
+ }, function(res) {
+ callback(res);
+ });
+
+ return req;
+};
+
+Content.prototype.downloadFile_ = function(url, start, end, callback) {
+ var headers = {
+ 'Range': 'bytes=' + start + '-' + end
+ };
+
+ var tempName = temp.generateName();
+ var tempFile = fs.createWriteStream(tempName);
+ tempFile.on('error', function(e) {
+ util.puts('temp write error: ' + util.inspect(e));
+ callback(null);
+ });
+ tempFile.on('close', function() {
+ callback(tempName);
+ });
+
+ var req = this.createRemoteRequest_('GET', headers, function(res) {
+ res.on('error', function(e) {
+ // TODO: prop back up?
+ util.puts('error in remote request: ' + util.inspect(e));
+ callback(null);
+ });
+ res.pipe(tempFile);
+ });
+ req.on('error', function(e) {
+ // TODO: prop back up?
+ util.puts('error in remote request: ' + util.inspect(e));
+ callback(null);
+ });
+ req.end();
+};
+
Content.prototype.extractMediaInfo_ = function(callback) {
var sourceUrl = url.parse(this.source.content);
switch (sourceUrl.protocol) {
@@ -54,9 +121,13 @@ Content.prototype.extractMediaInfo_ = function(callback) {
return;
case 'http:':
case 'https:':
- // HEAD to get the content type
- // TODO: head, grab the first bit, run mediainfo on it
- callback(null);
+ this.downloadFile_(this.source.content, 0, 64000, function(filename) {
+ if (filename) {
+ mediainfo.extractInfo(filename, callback);
+ } else {
+ callback(null);
+ }
+ });
return;
default:
util.puts('unsupported protocol: ' + sourceUrl.protocol);
@@ -152,37 +223,15 @@ Content.prototype.remoteHttpGet = function(req, res, sourceUrl) {
var source = this.source;
var target = this.target;
- // Some headers added to make the request seem a bit more genuine
- var headers = {
- 'Accept': '*/*',
- 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
- 'Accept-Encoding': 'identity;q=1, *;q=0',
- 'Accept-Language': 'en-US,en;q=0.8',
- 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) ' +
- 'AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.930.0 Safari/535.8'
- };
-
- // Copy user headers
- if (source.referer) {
- headers['Referer'] = source.referer;
- }
- if (source.cookie) {
- headers['Cookie'] = source.cookie;
- }
+ var headers = {};
// Add specific request headers that we want to pass through
if (req.headers['range']) {
headers['Range'] = req.headers['range'];
}
- var remoteReq = http.request({
- hostname: sourceUrl.hostname,
- port: sourceUrl.port,
- method: req.method,
- path: sourceUrl.path,
- headers: headers,
- auth: source.auth,
- }, function(remoteRes) {
+ var remoteReq = this.createRemoteRequest_(
+ req.method, headers, function(remoteRes) {
// Write response headers - write out exactly what we get from the remote
// server (note that they will be all lowercase, but AppleTV accepts that)
var remoteHeaders = remoteRes.headers;
@@ -206,6 +255,7 @@ Content.prototype.remoteHttpGet = function(req, res, sourceUrl) {
remoteReq.on('error', function(e) {
// TODO: prop back up?
util.puts('error in remote request: ' + util.inspect(e));
+ res.end('error');
});
remoteReq.end();
};
18 lib/temp.js
View
@@ -0,0 +1,18 @@
+var fs = require('fs');
+var path = require('path');
+var uuid = require('node-uuid');
+
+var tempPath = (function() {
+ var vars = ['TMPDIR', 'TMP', 'TEMP'];
+ for (var n = 0; n < vars.length; n++) {
+ var path = process.env[vars[n]];
+ if (path) {
+ return fs.realpathSync(path);
+ }
+ }
+ return fs.realpathSync('/tmp');
+})();
+
+exports.generateName = function() {
+ return path.join(tempPath, uuid());
+};
Please sign in to comment.
Something went wrong with that request. Please try again.