|
|
@@ -2,9 +2,10 @@
|
|
|
|
|
|
var util = require('util'),
|
|
|
url = require('url'),
|
|
|
+ zlib = require('zlib'),
|
|
|
assert = require('assert');
|
|
|
|
|
|
-var http = require('http-get'),
|
|
|
+var request = require('request'),
|
|
|
debug = require('debug')('hls:reader');
|
|
|
|
|
|
try {
|
|
|
@@ -35,17 +36,6 @@ emits:
|
|
|
segment (seqNo, duration, datetime, size?, )
|
|
|
*/
|
|
|
|
|
|
-// ensure function is never run more than once
|
|
|
-function once(fn) {
|
|
|
- var called = false;
|
|
|
- return function() {
|
|
|
- var call = !called;
|
|
|
- called = true;
|
|
|
- if(call) fn.apply(this, arguments);
|
|
|
- else debug('once only callback failed');
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
function getFileStream(srcUrl, options, cb) {
|
|
|
assert(srcUrl.protocol);
|
|
|
|
|
|
@@ -57,26 +47,30 @@ function getFileStream(srcUrl, options, cb) {
|
|
|
if (srcUrl.protocol === 'http:' || srcUrl.protocol === 'https:') {
|
|
|
var headers = options.headers || {};
|
|
|
if (!headers['user-agent']) headers['user-agent'] = DEFAULT_AGENT;
|
|
|
+ if (!headers['accept-encoding']) headers['accept-encoding'] = ['gzip','deflate'];
|
|
|
|
|
|
- // http-get will occasionally call the callback multiple times... :–(
|
|
|
- (options.probe ? http.head : http.get)({url:url.format(srcUrl), stream:true, headers:headers}, once(function(err, res) {
|
|
|
- if (err) return cb(err);
|
|
|
-
|
|
|
- var statusCode = res.code || res.stream.statusCode;
|
|
|
- if (statusCode !== 200) {
|
|
|
- if (res.stream)
|
|
|
- res.stream.destroy();
|
|
|
+ var req = (options.probe ? request.head : request.get)({url:url.format(srcUrl), stream:true, headers:headers});
|
|
|
+ req.on('error', cb);
|
|
|
+ req.on('response', function (res) {
|
|
|
+ if (res.statusCode !== 200) {
|
|
|
+ req.abort();
|
|
|
return cb(new Error('Bad server response code: '+statusCode));
|
|
|
}
|
|
|
+ req.setEncoding = res.setEncoding; // hack to fix setencoding called from carrier
|
|
|
+
|
|
|
+ var stream = req;
|
|
|
+ if (res.headers['content-encoding'] === 'gzip' || res.headers['content-encoding'] === 'deflate') {
|
|
|
+ unzip = zlib.createUnzip();
|
|
|
+ stream = res.pipe(unzip);
|
|
|
+ }
|
|
|
|
|
|
var typeparts = /^(.+?\/.+?)(?:;\w*.*)?$/.exec(res.headers['content-type']) || [null, 'application/octet-stream'],
|
|
|
mimetype = typeparts[1].toLowerCase(),
|
|
|
size = res.headers['content-length'] ? parseInt(res.headers['content-length'], 10) : -1,
|
|
|
modified = res.headers['last-modified'] ? new Date(res.headers['last-modified']) : null;
|
|
|
|
|
|
- res.stream.resume(); // for some reason http-get pauses the stream for the callback
|
|
|
- cb(null, res.stream, {url:res.url || url.format(srcUrl), mime:mimetype, size:size, modified:modified});
|
|
|
- }));
|
|
|
+ cb(null, stream, {url:res.url || url.format(srcUrl), mime:mimetype, size:size, modified:modified});
|
|
|
+ });
|
|
|
} else {
|
|
|
process.nextTick(function() {
|
|
|
cb(new Error('Unsupported protocol: '+srcUrl.protocol));
|
|
|
@@ -244,7 +238,6 @@ function HlsStreamReader(src, options) {
|
|
|
|
|
|
self.readState.stream = null;
|
|
|
|
|
|
- // FIXME: is this required? or already handled by http-get?
|
|
|
if (!err && (totalBytes !== meta.size))
|
|
|
err = new Error('Invalid returned stream length (req='+meta.size+', ret='+totalBytes+')');
|
|
|
|
|
|
@@ -272,12 +265,12 @@ function HlsStreamReader(src, options) {
|
|
|
var stream = self.readState.stream;
|
|
|
if (!stream) return;
|
|
|
|
|
|
- if (typeof stream.destroy == 'function') {
|
|
|
+ if (typeof stream.abort == 'function') {
|
|
|
var duration = self.readState.currentSegment.duration || self.index.target_duration || 10;
|
|
|
self.readState.timer = setTimeout(function() {
|
|
|
if (self.readState.stream) {
|
|
|
debug('timed out waiting for data');
|
|
|
- self.readState.stream.destroy();
|
|
|
+ self.readState.stream.abort();
|
|
|
}
|
|
|
self.readState.timer = null;
|
|
|
}, 1.5*duration*1000);
|