Files
Zos/Skills/@be/be/node_modules/icecast/lib/reader.js

101 lines
2.4 KiB
JavaScript
Raw Normal View History

/**
* Module dependencies.
*/
var assert = require('assert');
var Parser = require('stream-parser');
var inherits = require('util').inherits;
var debug = require('debug')('icecast:reader');
var Transform = require('stream').Transform;
// for node v0.8.x support, remove after v0.12.x
if (!Transform) Transform = require('readable-stream/transform');
/**
* Module exports.
*/
module.exports = Reader;
/**
* The metabyte must be multiplied by META_BLOCK_SIZE to get the real
* metadata byte-length.
*
* @api private
*/
var META_BLOCK_SIZE = 16;
/**
* Icecast stream reader. This is a duplex stream that emits "metadata" events in
* addition to stripping out the metadata itself from the output data. The result
* is clean (audio and/or video) data coming out of the stream.
*
* @param {Number} metaint the number of bytes in between "metadata" blocks (usually the `Icy-MetaInt` HTTP header).
* @param {Object} opts optional options object
* @api public
*/
function Reader (metaint, opts) {
if (!(this instanceof Reader)) {
return new Reader(metaint, opts);
}
if (!isFinite(metaint)) {
throw new TypeError('Reader requires a "metaint" number');
}
Transform.call(this, opts);
this.metaint = +metaint;
this._passthrough(this.metaint, this._onRawData);
debug('created new Reader instance with "metaint": %d', this.metaint);
}
inherits(Reader, Transform);
/**
* Mixin `Parser`.
*/
Parser(Reader.prototype);
/**
* Called after "metaint" bytes have been passed through.
*
* @api private
*/
Reader.prototype._onRawData = function () {
debug('_onRawData()');
this._bytes(1, this._onMetaByte);
};
/**
* Called when the "metabyte" has been received.
*
* @api private
*/
Reader.prototype._onMetaByte = function (chunk) {
assert(chunk.length === 1);
var length = chunk[0] * META_BLOCK_SIZE;
debug('_onMetaByte: metabyte: %d, metalength: %d', chunk[0], length, chunk);
if (length > 0) {
// we have metadata to parse
this._bytes(length, this._onMetaData);
} else {
// not metadata this time around, back to serving raw data chunks
this._passthrough(this.metaint, this._onRawData);
}
};
/**
* Called once all the metadata has been buffered for this pass.
*
* @api private
*/
Reader.prototype._onMetaData = function (chunk) {
debug('_onMetaData (chunk.length: %d)', chunk.length);
this.emit('metadata', chunk);
this._passthrough(this.metaint, this._onRawData);
};