Skip to content

Instantly share code, notes, and snippets.

@itslukej
Last active April 30, 2017 19:36
Show Gist options
  • Save itslukej/6f91aa2997b22a479fc7d47189ca823f to your computer and use it in GitHub Desktop.
Save itslukej/6f91aa2997b22a479fc7d47189ca823f to your computer and use it in GitHub Desktop.
const Stream = require('stream');
const https = require('https');
const http = require('http');
const URL = require('url');
/**
* Resumable stream via a Stream PassThrough
* @param {string|URL} url Input url
* @param {stream.Transform} [output=stream.PassThrough] Output stream
* @param {Object} [meta] Meta information to pass between stuff
* @returns {stream.Transform}
* @example
* const Speaker = require('speaker');
*
* const speaker = new Speaker({
* channels: 2,
* bitDepth: 16,
* sampleRate: 44100,
* });
*
* require('./')('http://www.music.helsinki.fi/tmt/opetus/uusmedia/esim/a2002011001-e02.wav').pipe(speaker);
*/
function streamIt(url, output = new Stream.PassThrough(), meta = { downloaded: 0, total: 0 }) {
if(output._destroyed) return output;
let input;
output.destroy = function destroy() {
this._destroyed = true;
if(input) {
input.unpipe();
input.destroy();
}
};
const options = typeof url === 'string' ? URL.parse(url) : url;
if(!options.headers) options.headers = {};
(options.protocol === 'https:' ? https : http).get(options, (res) => {
output.resume();
input = res;
if(meta.downloaded === 0) meta.total = Number(input.headers['content-length']);
input.on('data', (chunk) => {
meta.downloaded += Buffer.byteLength(chunk);
});
input.on('end', () => {
if(meta.downloaded < meta.total) {
input.unpipe();
options.headers.Range = `bytes=${meta.downloaded}-`;
streamIt(options, output, meta);
} else {
output.end();
}
});
input.on('error', (err) => {
if(!err) return;
console.log(err);
if(err.message === 'read ECONNRESET') {
output.pause();
return;
}
output.emit('error', err);
});
input.pipe(output, { end: false });
});
return output;
}
module.exports = streamIt;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment