!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.AV=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 3); return this.bitPosition = pos & 7; }; Bitstream.prototype.rewind = function(bits) { var pos; pos = this.bitPosition - bits; this.stream.rewind(Math.abs(pos >> 3)); return this.bitPosition = pos & 7; }; Bitstream.prototype.seek = function(offset) { var curOffset; curOffset = this.offset(); if (offset > curOffset) { return this.advance(offset - curOffset); } else if (offset < curOffset) { return this.rewind(curOffset - offset); } }; Bitstream.prototype.align = function() { if (this.bitPosition !== 0) { this.bitPosition = 0; return this.stream.advance(1); } }; Bitstream.prototype.read = function(bits, signed) { var a, a0, a1, a2, a3, a4, mBits; if (bits === 0) { return 0; } mBits = bits + this.bitPosition; if (mBits <= 8) { a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits); } else if (mBits <= 16) { a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits); } else if (mBits <= 24) { a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits); } else if (mBits <= 32) { a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits); } else if (mBits <= 40) { a0 = this.stream.peekUInt8(0) * 0x0100000000; a1 = this.stream.peekUInt8(1) << 24 >>> 0; a2 = this.stream.peekUInt8(2) << 16; a3 = this.stream.peekUInt8(3) << 8; a4 = this.stream.peekUInt8(4); a = a0 + a1 + a2 + a3 + a4; a %= Math.pow(2, 40 - this.bitPosition); a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits)); } else { throw new Error("Too many bits!"); } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } this.advance(bits); return a; }; Bitstream.prototype.peek = function(bits, signed) { var a, a0, a1, a2, a3, a4, mBits; if (bits === 0) { return 0; } mBits = bits + this.bitPosition; if (mBits <= 8) { a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits); } else if (mBits <= 16) { a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits); } else if (mBits <= 24) { a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits); } else if (mBits <= 32) { a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits); } else if (mBits <= 40) { a0 = this.stream.peekUInt8(0) * 0x0100000000; a1 = this.stream.peekUInt8(1) << 24 >>> 0; a2 = this.stream.peekUInt8(2) << 16; a3 = this.stream.peekUInt8(3) << 8; a4 = this.stream.peekUInt8(4); a = a0 + a1 + a2 + a3 + a4; a %= Math.pow(2, 40 - this.bitPosition); a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits)); } else { throw new Error("Too many bits!"); } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } return a; }; Bitstream.prototype.readLSB = function(bits, signed) { var a, mBits; if (bits === 0) { return 0; } if (bits > 40) { throw new Error("Too many bits!"); } mBits = bits + this.bitPosition; a = (this.stream.peekUInt8(0)) >>> this.bitPosition; if (mBits > 8) { a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition); } if (mBits > 16) { a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition); } if (mBits > 24) { a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0; } if (mBits > 32) { a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition); } if (mBits >= 32) { a %= Math.pow(2, bits); } else { a &= (1 << bits) - 1; } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } this.advance(bits); return a; }; Bitstream.prototype.peekLSB = function(bits, signed) { var a, mBits; if (bits === 0) { return 0; } if (bits > 40) { throw new Error("Too many bits!"); } mBits = bits + this.bitPosition; a = (this.stream.peekUInt8(0)) >>> this.bitPosition; if (mBits > 8) { a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition); } if (mBits > 16) { a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition); } if (mBits > 24) { a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0; } if (mBits > 32) { a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition); } if (mBits >= 32) { a %= Math.pow(2, bits); } else { a &= (1 << bits) - 1; } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } return a; }; return Bitstream; })(); module.exports = Bitstream; },{}],7:[function(_dereq_,module,exports){ (function (global){ var AVBuffer; AVBuffer = (function() { var BlobBuilder, URL; function AVBuffer(input) { var _ref; if (input instanceof Uint8Array) { this.data = input; } else if (input instanceof ArrayBuffer || Array.isArray(input) || typeof input === 'number' || ((_ref = global.Buffer) != null ? _ref.isBuffer(input) : void 0)) { this.data = new Uint8Array(input); } else if (input.buffer instanceof ArrayBuffer) { this.data = new Uint8Array(input.buffer, input.byteOffset, input.length * input.BYTES_PER_ELEMENT); } else if (input instanceof AVBuffer) { this.data = input.data; } else { throw new Error("Constructing buffer with unknown type."); } this.length = this.data.length; this.next = null; this.prev = null; } AVBuffer.allocate = function(size) { return new AVBuffer(size); }; AVBuffer.prototype.copy = function() { return new AVBuffer(new Uint8Array(this.data)); }; AVBuffer.prototype.slice = function(position, length) { if (length == null) { length = this.length; } if (position === 0 && length >= this.length) { return new AVBuffer(this.data); } else { return new AVBuffer(this.data.subarray(position, position + length)); } }; BlobBuilder = global.BlobBuilder || global.MozBlobBuilder || global.WebKitBlobBuilder; URL = global.URL || global.webkitURL || global.mozURL; AVBuffer.makeBlob = function(data, type) { var bb; if (type == null) { type = 'application/octet-stream'; } try { return new Blob([data], { type: type }); } catch (_error) {} if (BlobBuilder != null) { bb = new BlobBuilder; bb.append(data); return bb.getBlob(type); } return null; }; AVBuffer.makeBlobURL = function(data, type) { return URL != null ? URL.createObjectURL(this.makeBlob(data, type)) : void 0; }; AVBuffer.revokeBlobURL = function(url) { return URL != null ? URL.revokeObjectURL(url) : void 0; }; AVBuffer.prototype.toBlob = function() { return AVBuffer.makeBlob(this.data.buffer); }; AVBuffer.prototype.toBlobURL = function() { return AVBuffer.makeBlobURL(this.data.buffer); }; return AVBuffer; })(); module.exports = AVBuffer; }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],8:[function(_dereq_,module,exports){ var BufferList; BufferList = (function() { function BufferList() { this.first = null; this.last = null; this.numBuffers = 0; this.availableBytes = 0; this.availableBuffers = 0; } BufferList.prototype.copy = function() { var result; result = new BufferList; result.first = this.first; result.last = this.last; result.numBuffers = this.numBuffers; result.availableBytes = this.availableBytes; result.availableBuffers = this.availableBuffers; return result; }; BufferList.prototype.append = function(buffer) { var _ref; buffer.prev = this.last; if ((_ref = this.last) != null) { _ref.next = buffer; } this.last = buffer; if (this.first == null) { this.first = buffer; } this.availableBytes += buffer.length; this.availableBuffers++; return this.numBuffers++; }; BufferList.prototype.advance = function() { if (this.first) { this.availableBytes -= this.first.length; this.availableBuffers--; this.first = this.first.next; return this.first != null; } return false; }; BufferList.prototype.rewind = function() { var _ref; if (this.first && !this.first.prev) { return false; } this.first = ((_ref = this.first) != null ? _ref.prev : void 0) || this.last; if (this.first) { this.availableBytes += this.first.length; this.availableBuffers++; } return this.first != null; }; BufferList.prototype.reset = function() { var _results; _results = []; while (this.rewind()) { continue; } return _results; }; return BufferList; })(); module.exports = BufferList; },{}],9:[function(_dereq_,module,exports){ var Base, EventEmitter, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; Base = _dereq_('./base'); EventEmitter = (function(_super) { __extends(EventEmitter, _super); function EventEmitter() { return EventEmitter.__super__.constructor.apply(this, arguments); } EventEmitter.prototype.on = function(event, fn) { var _base; if (this.events == null) { this.events = {}; } if ((_base = this.events)[event] == null) { _base[event] = []; } return this.events[event].push(fn); }; EventEmitter.prototype.off = function(event, fn) { var index, _ref; if (!((_ref = this.events) != null ? _ref[event] : void 0)) { return; } index = this.events[event].indexOf(fn); if (~index) { return this.events[event].splice(index, 1); } }; EventEmitter.prototype.once = function(event, fn) { var cb; return this.on(event, cb = function() { this.off(event, cb); return fn.apply(this, arguments); }); }; EventEmitter.prototype.emit = function() { var args, event, fn, _i, _len, _ref, _ref1; event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; if (!((_ref = this.events) != null ? _ref[event] : void 0)) { return; } _ref1 = this.events[event].slice(); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { fn = _ref1[_i]; fn.apply(this, args); } }; return EventEmitter; })(Base); module.exports = EventEmitter; },{"./base":5}],10:[function(_dereq_,module,exports){ var AVBuffer, BufferList, Stream, UnderflowError; BufferList = _dereq_('./bufferlist'); AVBuffer = _dereq_('./buffer'); UnderflowError = _dereq_('./underflow'); Stream = (function() { var buf, decodeString, float32, float64, float64Fallback, float80, int16, int32, int8, nativeEndian, uint16, uint32, uint8; buf = new ArrayBuffer(16); uint8 = new Uint8Array(buf); int8 = new Int8Array(buf); uint16 = new Uint16Array(buf); int16 = new Int16Array(buf); uint32 = new Uint32Array(buf); int32 = new Int32Array(buf); float32 = new Float32Array(buf); if (typeof Float64Array !== "undefined" && Float64Array !== null) { float64 = new Float64Array(buf); } nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412; function Stream(list) { this.list = list; this.localOffset = 0; this.offset = 0; } Stream.fromBuffer = function(buffer) { var list; list = new BufferList; list.append(buffer); return new Stream(list); }; Stream.prototype.copy = function() { var result; result = new Stream(this.list.copy()); result.localOffset = this.localOffset; result.offset = this.offset; return result; }; Stream.prototype.available = function(bytes) { return bytes <= this.list.availableBytes - this.localOffset; }; Stream.prototype.remainingBytes = function() { return this.list.availableBytes - this.localOffset; }; Stream.prototype.advance = function(bytes) { if (!this.available(bytes)) { throw new UnderflowError(); } this.localOffset += bytes; this.offset += bytes; while (this.list.first && this.localOffset >= this.list.first.length) { this.localOffset -= this.list.first.length; this.list.advance(); } return this; }; Stream.prototype.rewind = function(bytes) { if (bytes > this.offset) { throw new UnderflowError(); } if (!this.list.first) { this.list.rewind(); this.localOffset = this.list.first.length; } this.localOffset -= bytes; this.offset -= bytes; while (this.list.first.prev && this.localOffset < 0) { this.list.rewind(); this.localOffset += this.list.first.length; } return this; }; Stream.prototype.seek = function(position) { if (position > this.offset) { return this.advance(position - this.offset); } else if (position < this.offset) { return this.rewind(this.offset - position); } }; Stream.prototype.readUInt8 = function() { var a; if (!this.available(1)) { throw new UnderflowError(); } a = this.list.first.data[this.localOffset]; this.localOffset += 1; this.offset += 1; if (this.localOffset === this.list.first.length) { this.localOffset = 0; this.list.advance(); } return a; }; Stream.prototype.peekUInt8 = function(offset) { var buffer; if (offset == null) { offset = 0; } if (!this.available(offset + 1)) { throw new UnderflowError(); } offset = this.localOffset + offset; buffer = this.list.first; while (buffer) { if (buffer.length > offset) { return buffer.data[offset]; } offset -= buffer.length; buffer = buffer.next; } return 0; }; Stream.prototype.read = function(bytes, littleEndian) { var i, _i, _j, _ref; if (littleEndian == null) { littleEndian = false; } if (littleEndian === nativeEndian) { for (i = _i = 0; _i < bytes; i = _i += 1) { uint8[i] = this.readUInt8(); } } else { for (i = _j = _ref = bytes - 1; _j >= 0; i = _j += -1) { uint8[i] = this.readUInt8(); } } }; Stream.prototype.peek = function(bytes, offset, littleEndian) { var i, _i, _j; if (littleEndian == null) { littleEndian = false; } if (littleEndian === nativeEndian) { for (i = _i = 0; _i < bytes; i = _i += 1) { uint8[i] = this.peekUInt8(offset + i); } } else { for (i = _j = 0; _j < bytes; i = _j += 1) { uint8[bytes - i - 1] = this.peekUInt8(offset + i); } } }; Stream.prototype.readInt8 = function() { this.read(1); return int8[0]; }; Stream.prototype.peekInt8 = function(offset) { if (offset == null) { offset = 0; } this.peek(1, offset); return int8[0]; }; Stream.prototype.readUInt16 = function(littleEndian) { this.read(2, littleEndian); return uint16[0]; }; Stream.prototype.peekUInt16 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(2, offset, littleEndian); return uint16[0]; }; Stream.prototype.readInt16 = function(littleEndian) { this.read(2, littleEndian); return int16[0]; }; Stream.prototype.peekInt16 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(2, offset, littleEndian); return int16[0]; }; Stream.prototype.readUInt24 = function(littleEndian) { if (littleEndian) { return this.readUInt16(true) + (this.readUInt8() << 16); } else { return (this.readUInt16() << 8) + this.readUInt8(); } }; Stream.prototype.peekUInt24 = function(offset, littleEndian) { if (offset == null) { offset = 0; } if (littleEndian) { return this.peekUInt16(offset, true) + (this.peekUInt8(offset + 2) << 16); } else { return (this.peekUInt16(offset) << 8) + this.peekUInt8(offset + 2); } }; Stream.prototype.readInt24 = function(littleEndian) { if (littleEndian) { return this.readUInt16(true) + (this.readInt8() << 16); } else { return (this.readInt16() << 8) + this.readUInt8(); } }; Stream.prototype.peekInt24 = function(offset, littleEndian) { if (offset == null) { offset = 0; } if (littleEndian) { return this.peekUInt16(offset, true) + (this.peekInt8(offset + 2) << 16); } else { return (this.peekInt16(offset) << 8) + this.peekUInt8(offset + 2); } }; Stream.prototype.readUInt32 = function(littleEndian) { this.read(4, littleEndian); return uint32[0]; }; Stream.prototype.peekUInt32 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(4, offset, littleEndian); return uint32[0]; }; Stream.prototype.readInt32 = function(littleEndian) { this.read(4, littleEndian); return int32[0]; }; Stream.prototype.peekInt32 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(4, offset, littleEndian); return int32[0]; }; Stream.prototype.readFloat32 = function(littleEndian) { this.read(4, littleEndian); return float32[0]; }; Stream.prototype.peekFloat32 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(4, offset, littleEndian); return float32[0]; }; Stream.prototype.readFloat64 = function(littleEndian) { this.read(8, littleEndian); if (float64) { return float64[0]; } else { return float64Fallback(); } }; float64Fallback = function() { var exp, frac, high, low, out, sign; low = uint32[0], high = uint32[1]; if (!high || high === 0x80000000) { return 0.0; } sign = 1 - (high >>> 31) * 2; exp = (high >>> 20) & 0x7ff; frac = high & 0xfffff; if (exp === 0x7ff) { if (frac) { return NaN; } return sign * Infinity; } exp -= 1023; out = (frac | 0x100000) * Math.pow(2, exp - 20); out += low * Math.pow(2, exp - 52); return sign * out; }; Stream.prototype.peekFloat64 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(8, offset, littleEndian); if (float64) { return float64[0]; } else { return float64Fallback(); } }; Stream.prototype.readFloat80 = function(littleEndian) { this.read(10, littleEndian); return float80(); }; float80 = function() { var a0, a1, exp, high, low, out, sign; high = uint32[0], low = uint32[1]; a0 = uint8[9]; a1 = uint8[8]; sign = 1 - (a0 >>> 7) * 2; exp = ((a0 & 0x7F) << 8) | a1; if (exp === 0 && low === 0 && high === 0) { return 0; } if (exp === 0x7fff) { if (low === 0 && high === 0) { return sign * Infinity; } return NaN; } exp -= 16383; out = low * Math.pow(2, exp - 31); out += high * Math.pow(2, exp - 63); return sign * out; }; Stream.prototype.peekFloat80 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(10, offset, littleEndian); return float80(); }; Stream.prototype.readBuffer = function(length) { var i, result, to, _i; result = AVBuffer.allocate(length); to = result.data; for (i = _i = 0; _i < length; i = _i += 1) { to[i] = this.readUInt8(); } return result; }; Stream.prototype.peekBuffer = function(offset, length) { var i, result, to, _i; if (offset == null) { offset = 0; } result = AVBuffer.allocate(length); to = result.data; for (i = _i = 0; _i < length; i = _i += 1) { to[i] = this.peekUInt8(offset + i); } return result; }; Stream.prototype.readSingleBuffer = function(length) { var result; result = this.list.first.slice(this.localOffset, length); this.advance(result.length); return result; }; Stream.prototype.peekSingleBuffer = function(offset, length) { var result; result = this.list.first.slice(this.localOffset + offset, length); return result; }; Stream.prototype.readString = function(length, encoding) { if (encoding == null) { encoding = 'ascii'; } return decodeString.call(this, 0, length, encoding, true); }; Stream.prototype.peekString = function(offset, length, encoding) { if (offset == null) { offset = 0; } if (encoding == null) { encoding = 'ascii'; } return decodeString.call(this, offset, length, encoding, false); }; decodeString = function(offset, length, encoding, advance) { var b1, b2, b3, b4, bom, c, end, littleEndian, nullEnd, pt, result, w1, w2; encoding = encoding.toLowerCase(); nullEnd = length === null ? 0 : -1; if (length == null) { length = Infinity; } end = offset + length; result = ''; switch (encoding) { case 'ascii': case 'latin1': while (offset < end && (c = this.peekUInt8(offset++)) !== nullEnd) { result += String.fromCharCode(c); } break; case 'utf8': case 'utf-8': while (offset < end && (b1 = this.peekUInt8(offset++)) !== nullEnd) { if ((b1 & 0x80) === 0) { result += String.fromCharCode(b1); } else if ((b1 & 0xe0) === 0xc0) { b2 = this.peekUInt8(offset++) & 0x3f; result += String.fromCharCode(((b1 & 0x1f) << 6) | b2); } else if ((b1 & 0xf0) === 0xe0) { b2 = this.peekUInt8(offset++) & 0x3f; b3 = this.peekUInt8(offset++) & 0x3f; result += String.fromCharCode(((b1 & 0x0f) << 12) | (b2 << 6) | b3); } else if ((b1 & 0xf8) === 0xf0) { b2 = this.peekUInt8(offset++) & 0x3f; b3 = this.peekUInt8(offset++) & 0x3f; b4 = this.peekUInt8(offset++) & 0x3f; pt = (((b1 & 0x0f) << 18) | (b2 << 12) | (b3 << 6) | b4) - 0x10000; result += String.fromCharCode(0xd800 + (pt >> 10), 0xdc00 + (pt & 0x3ff)); } } break; case 'utf16-be': case 'utf16be': case 'utf16le': case 'utf16-le': case 'utf16bom': case 'utf16-bom': switch (encoding) { case 'utf16be': case 'utf16-be': littleEndian = false; break; case 'utf16le': case 'utf16-le': littleEndian = true; break; case 'utf16bom': case 'utf16-bom': if (length < 2 || (bom = this.peekUInt16(offset)) === nullEnd) { if (advance) { this.advance(offset += 2); } return result; } littleEndian = bom === 0xfffe; offset += 2; } while (offset < end && (w1 = this.peekUInt16(offset, littleEndian)) !== nullEnd) { offset += 2; if (w1 < 0xd800 || w1 > 0xdfff) { result += String.fromCharCode(w1); } else { if (w1 > 0xdbff) { throw new Error("Invalid utf16 sequence."); } w2 = this.peekUInt16(offset, littleEndian); if (w2 < 0xdc00 || w2 > 0xdfff) { throw new Error("Invalid utf16 sequence."); } result += String.fromCharCode(w1, w2); offset += 2; } } if (w1 === nullEnd) { offset += 2; } break; default: throw new Error("Unknown encoding: " + encoding); } if (advance) { this.advance(offset); } return result; }; return Stream; })(); module.exports = Stream; },{"./buffer":7,"./bufferlist":8,"./underflow":11}],11:[function(_dereq_,module,exports){ var UnderflowError, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; UnderflowError = (function(_super) { __extends(UnderflowError, _super); function UnderflowError() { UnderflowError.__super__.constructor.apply(this, arguments); this.name = 'UnderflowError'; this.stack = new Error().stack; } return UnderflowError; })(Error); module.exports = UnderflowError; },{}],12:[function(_dereq_,module,exports){ var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('./core/events'); BufferList = _dereq_('./core/bufferlist'); Stream = _dereq_('./core/stream'); Bitstream = _dereq_('./core/bitstream'); UnderflowError = _dereq_('./core/underflow'); Decoder = (function(_super) { var codecs; __extends(Decoder, _super); function Decoder(demuxer, format) { var list; this.demuxer = demuxer; this.format = format; list = new BufferList; this.stream = new Stream(list); this.bitstream = new Bitstream(this.stream); this.receivedFinalBuffer = false; this.waiting = false; this.demuxer.on('cookie', (function(_this) { return function(cookie) { var error; try { return _this.setCookie(cookie); } catch (_error) { error = _error; return _this.emit('error', error); } }; })(this)); this.demuxer.on('data', (function(_this) { return function(chunk) { list.append(chunk); if (_this.waiting) { return _this.decode(); } }; })(this)); this.demuxer.on('end', (function(_this) { return function() { _this.receivedFinalBuffer = true; if (_this.waiting) { return _this.decode(); } }; })(this)); this.init(); } Decoder.prototype.init = function() {}; Decoder.prototype.setCookie = function(cookie) {}; Decoder.prototype.readChunk = function() {}; Decoder.prototype.decode = function() { var error, offset, packet; this.waiting = false; offset = this.bitstream.offset(); try { packet = this.readChunk(); } catch (_error) { error = _error; if (!(error instanceof UnderflowError)) { this.emit('error', error); return false; } } if (packet) { this.emit('data', packet); return true; } else if (!this.receivedFinalBuffer) { this.bitstream.seek(offset); this.waiting = true; } else { this.emit('end'); } return false; }; Decoder.prototype.seek = function(timestamp) { var seekPoint; seekPoint = this.demuxer.seek(timestamp); this.stream.seek(seekPoint.offset); return seekPoint.timestamp; }; codecs = {}; Decoder.register = function(id, decoder) { return codecs[id] = decoder; }; Decoder.find = function(id) { return codecs[id] || null; }; return Decoder; })(EventEmitter); module.exports = Decoder; },{"./core/bitstream":6,"./core/bufferlist":8,"./core/events":9,"./core/stream":10,"./core/underflow":11}],13:[function(_dereq_,module,exports){ var Decoder, LPCMDecoder, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Decoder = _dereq_('../decoder'); LPCMDecoder = (function(_super) { __extends(LPCMDecoder, _super); function LPCMDecoder() { this.readChunk = __bind(this.readChunk, this); return LPCMDecoder.__super__.constructor.apply(this, arguments); } Decoder.register('lpcm', LPCMDecoder); LPCMDecoder.prototype.readChunk = function() { var chunkSize, i, littleEndian, output, samples, stream, _i, _j, _k, _l, _m, _n; stream = this.stream; littleEndian = this.format.littleEndian; chunkSize = Math.min(4096, stream.remainingBytes()); samples = chunkSize / (this.format.bitsPerChannel / 8) | 0; if (chunkSize < this.format.bitsPerChannel / 8) { return null; } if (this.format.floatingPoint) { switch (this.format.bitsPerChannel) { case 32: output = new Float32Array(samples); for (i = _i = 0; _i < samples; i = _i += 1) { output[i] = stream.readFloat32(littleEndian); } break; case 64: output = new Float64Array(samples); for (i = _j = 0; _j < samples; i = _j += 1) { output[i] = stream.readFloat64(littleEndian); } break; default: throw new Error('Unsupported bit depth.'); } } else { switch (this.format.bitsPerChannel) { case 8: output = new Int8Array(samples); for (i = _k = 0; _k < samples; i = _k += 1) { output[i] = stream.readInt8(); } break; case 16: output = new Int16Array(samples); for (i = _l = 0; _l < samples; i = _l += 1) { output[i] = stream.readInt16(littleEndian); } break; case 24: output = new Int32Array(samples); for (i = _m = 0; _m < samples; i = _m += 1) { output[i] = stream.readInt24(littleEndian); } break; case 32: output = new Int32Array(samples); for (i = _n = 0; _n < samples; i = _n += 1) { output[i] = stream.readInt32(littleEndian); } break; default: throw new Error('Unsupported bit depth.'); } } return output; }; return LPCMDecoder; })(Decoder); },{"../decoder":12}],14:[function(_dereq_,module,exports){ var Decoder, XLAWDecoder, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Decoder = _dereq_('../decoder'); XLAWDecoder = (function(_super) { var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT; __extends(XLAWDecoder, _super); function XLAWDecoder() { this.readChunk = __bind(this.readChunk, this); return XLAWDecoder.__super__.constructor.apply(this, arguments); } Decoder.register('ulaw', XLAWDecoder); Decoder.register('alaw', XLAWDecoder); SIGN_BIT = 0x80; QUANT_MASK = 0xf; SEG_SHIFT = 4; SEG_MASK = 0x70; BIAS = 0x84; XLAWDecoder.prototype.init = function() { var i, seg, t, table, val, _i, _j; this.format.bitsPerChannel = 16; this.table = table = new Int16Array(256); if (this.format.formatID === 'ulaw') { for (i = _i = 0; _i < 256; i = ++_i) { val = ~i; t = ((val & QUANT_MASK) << 3) + BIAS; t <<= (val & SEG_MASK) >>> SEG_SHIFT; table[i] = val & SIGN_BIT ? BIAS - t : t - BIAS; } } else { for (i = _j = 0; _j < 256; i = ++_j) { val = i ^ 0x55; t = val & QUANT_MASK; seg = (val & SEG_MASK) >>> SEG_SHIFT; if (seg) { t = (t + t + 1 + 32) << (seg + 2); } else { t = (t + t + 1) << 3; } table[i] = val & SIGN_BIT ? t : -t; } } }; XLAWDecoder.prototype.readChunk = function() { var i, output, samples, stream, table, _i; stream = this.stream, table = this.table; samples = Math.min(4096, this.stream.remainingBytes()); if (samples === 0) { return; } output = new Int16Array(samples); for (i = _i = 0; _i < samples; i = _i += 1) { output[i] = table[stream.readUInt8()]; } return output; }; return XLAWDecoder; })(Decoder); },{"../decoder":12}],15:[function(_dereq_,module,exports){ var BufferList, Demuxer, EventEmitter, Stream, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('./core/events'); BufferList = _dereq_('./core/bufferlist'); Stream = _dereq_('./core/stream'); Demuxer = (function(_super) { var formats; __extends(Demuxer, _super); Demuxer.probe = function(buffer) { return false; }; function Demuxer(source, chunk) { var list, received; list = new BufferList; list.append(chunk); this.stream = new Stream(list); received = false; source.on('data', (function(_this) { return function(chunk) { received = true; list.append(chunk); return _this.readChunk(chunk); }; })(this)); source.on('error', (function(_this) { return function(err) { return _this.emit('error', err); }; })(this)); source.on('end', (function(_this) { return function() { if (!received) { _this.readChunk(chunk); } return _this.emit('end'); }; })(this)); this.seekPoints = []; this.init(); } Demuxer.prototype.init = function() {}; Demuxer.prototype.readChunk = function(chunk) {}; Demuxer.prototype.addSeekPoint = function(offset, timestamp) { var index; index = this.searchTimestamp(timestamp); return this.seekPoints.splice(index, 0, { offset: offset, timestamp: timestamp }); }; Demuxer.prototype.searchTimestamp = function(timestamp, backward) { var high, low, mid, time; low = 0; high = this.seekPoints.length; if (high > 0 && this.seekPoints[high - 1].timestamp < timestamp) { return high; } while (low < high) { mid = (low + high) >> 1; time = this.seekPoints[mid].timestamp; if (time < timestamp) { low = mid + 1; } else if (time >= timestamp) { high = mid; } } if (high > this.seekPoints.length) { high = this.seekPoints.length; } return high; }; Demuxer.prototype.seek = function(timestamp) { var index, seekPoint; if (this.format && this.format.framesPerPacket > 0 && this.format.bytesPerPacket > 0) { seekPoint = { timestamp: timestamp, offset: this.format.bytesPerPacket * timestamp / this.format.framesPerPacket }; return seekPoint; } else { index = this.searchTimestamp(timestamp); return this.seekPoints[index]; } }; formats = []; Demuxer.register = function(demuxer) { return formats.push(demuxer); }; Demuxer.find = function(buffer) { var e, format, offset, stream, _i, _len; stream = Stream.fromBuffer(buffer); for (_i = 0, _len = formats.length; _i < _len; _i++) { format = formats[_i]; offset = stream.offset; try { if (format.probe(stream)) { return format; } } catch (_error) { e = _error; } stream.seek(offset); } return null; }; return Demuxer; })(EventEmitter); module.exports = Demuxer; },{"./core/bufferlist":8,"./core/events":9,"./core/stream":10}],16:[function(_dereq_,module,exports){ var AIFFDemuxer, Demuxer, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Demuxer = _dereq_('../demuxer'); AIFFDemuxer = (function(_super) { __extends(AIFFDemuxer, _super); function AIFFDemuxer() { return AIFFDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(AIFFDemuxer); AIFFDemuxer.probe = function(buffer) { var _ref; return buffer.peekString(0, 4) === 'FORM' && ((_ref = buffer.peekString(8, 4)) === 'AIFF' || _ref === 'AIFC'); }; AIFFDemuxer.prototype.readChunk = function() { var buffer, format, offset, _ref; if (!this.readStart && this.stream.available(12)) { if (this.stream.readString(4) !== 'FORM') { return this.emit('error', 'Invalid AIFF.'); } this.fileSize = this.stream.readUInt32(); this.fileType = this.stream.readString(4); this.readStart = true; if ((_ref = this.fileType) !== 'AIFF' && _ref !== 'AIFC') { return this.emit('error', 'Invalid AIFF.'); } } while (this.stream.available(1)) { if (!this.readHeaders && this.stream.available(8)) { this.type = this.stream.readString(4); this.len = this.stream.readUInt32(); } switch (this.type) { case 'COMM': if (!this.stream.available(this.len)) { return; } this.format = { formatID: 'lpcm', channelsPerFrame: this.stream.readUInt16(), sampleCount: this.stream.readUInt32(), bitsPerChannel: this.stream.readUInt16(), sampleRate: this.stream.readFloat80(), framesPerPacket: 1, littleEndian: false, floatingPoint: false }; this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame; if (this.fileType === 'AIFC') { format = this.stream.readString(4); this.format.littleEndian = format === 'sowt' && this.format.bitsPerChannel > 8; this.format.floatingPoint = format === 'fl32' || format === 'fl64'; if (format === 'twos' || format === 'sowt' || format === 'fl32' || format === 'fl64' || format === 'NONE') { format = 'lpcm'; } this.format.formatID = format; this.len -= 4; } this.stream.advance(this.len - 18); this.emit('format', this.format); this.emit('duration', this.format.sampleCount / this.format.sampleRate * 1000 | 0); break; case 'SSND': if (!(this.readSSNDHeader && this.stream.available(4))) { offset = this.stream.readUInt32(); this.stream.advance(4); this.stream.advance(offset); this.readSSNDHeader = true; } buffer = this.stream.readSingleBuffer(this.len); this.len -= buffer.length; this.readHeaders = this.len > 0; this.emit('data', buffer); break; default: if (!this.stream.available(this.len)) { return; } this.stream.advance(this.len); } if (this.type !== 'SSND') { this.readHeaders = false; } } }; return AIFFDemuxer; })(Demuxer); },{"../demuxer":15}],17:[function(_dereq_,module,exports){ var AUDemuxer, Demuxer, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Demuxer = _dereq_('../demuxer'); AUDemuxer = (function(_super) { var bps, formats; __extends(AUDemuxer, _super); function AUDemuxer() { return AUDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(AUDemuxer); AUDemuxer.probe = function(buffer) { return buffer.peekString(0, 4) === '.snd'; }; bps = [8, 8, 16, 24, 32, 32, 64]; bps[26] = 8; formats = { 1: 'ulaw', 27: 'alaw' }; AUDemuxer.prototype.readChunk = function() { var bytes, dataSize, encoding, size; if (!this.readHeader && this.stream.available(24)) { if (this.stream.readString(4) !== '.snd') { return this.emit('error', 'Invalid AU file.'); } size = this.stream.readUInt32(); dataSize = this.stream.readUInt32(); encoding = this.stream.readUInt32(); this.format = { formatID: formats[encoding] || 'lpcm', littleEndian: false, floatingPoint: encoding === 6 || encoding === 7, bitsPerChannel: bps[encoding - 1], sampleRate: this.stream.readUInt32(), channelsPerFrame: this.stream.readUInt32(), framesPerPacket: 1 }; if (this.format.bitsPerChannel == null) { return this.emit('error', 'Unsupported encoding in AU file.'); } this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame; if (dataSize !== 0xffffffff) { bytes = this.format.bitsPerChannel / 8; this.emit('duration', dataSize / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0); } this.emit('format', this.format); this.readHeader = true; } if (this.readHeader) { while (this.stream.available(1)) { this.emit('data', this.stream.readSingleBuffer(this.stream.remainingBytes())); } } }; return AUDemuxer; })(Demuxer); },{"../demuxer":15}],18:[function(_dereq_,module,exports){ var CAFDemuxer, Demuxer, M4ADemuxer, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Demuxer = _dereq_('../demuxer'); M4ADemuxer = _dereq_('./m4a'); CAFDemuxer = (function(_super) { __extends(CAFDemuxer, _super); function CAFDemuxer() { return CAFDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(CAFDemuxer); CAFDemuxer.probe = function(buffer) { return buffer.peekString(0, 4) === 'caff'; }; CAFDemuxer.prototype.readChunk = function() { var buffer, byteOffset, cookie, entries, flags, i, key, metadata, offset, sampleOffset, value, _i, _j, _ref; if (!this.format && this.stream.available(64)) { if (this.stream.readString(4) !== 'caff') { return this.emit('error', "Invalid CAF, does not begin with 'caff'"); } this.stream.advance(4); if (this.stream.readString(4) !== 'desc') { return this.emit('error', "Invalid CAF, 'caff' is not followed by 'desc'"); } if (!(this.stream.readUInt32() === 0 && this.stream.readUInt32() === 32)) { return this.emit('error', "Invalid 'desc' size, should be 32"); } this.format = {}; this.format.sampleRate = this.stream.readFloat64(); this.format.formatID = this.stream.readString(4); flags = this.stream.readUInt32(); if (this.format.formatID === 'lpcm') { this.format.floatingPoint = Boolean(flags & 1); this.format.littleEndian = Boolean(flags & 2); } this.format.bytesPerPacket = this.stream.readUInt32(); this.format.framesPerPacket = this.stream.readUInt32(); this.format.channelsPerFrame = this.stream.readUInt32(); this.format.bitsPerChannel = this.stream.readUInt32(); this.emit('format', this.format); } while (this.stream.available(1)) { if (!this.headerCache) { this.headerCache = { type: this.stream.readString(4), oversize: this.stream.readUInt32() !== 0, size: this.stream.readUInt32() }; if (this.headerCache.oversize) { return this.emit('error', "Holy Shit, an oversized file, not supported in JS"); } } switch (this.headerCache.type) { case 'kuki': if (this.stream.available(this.headerCache.size)) { if (this.format.formatID === 'aac ') { offset = this.stream.offset + this.headerCache.size; if (cookie = M4ADemuxer.readEsds(this.stream)) { this.emit('cookie', cookie); } this.stream.seek(offset); } else { buffer = this.stream.readBuffer(this.headerCache.size); this.emit('cookie', buffer); } this.headerCache = null; } break; case 'pakt': if (this.stream.available(this.headerCache.size)) { if (this.stream.readUInt32() !== 0) { return this.emit('error', 'Sizes greater than 32 bits are not supported.'); } this.numPackets = this.stream.readUInt32(); if (this.stream.readUInt32() !== 0) { return this.emit('error', 'Sizes greater than 32 bits are not supported.'); } this.numFrames = this.stream.readUInt32(); this.primingFrames = this.stream.readUInt32(); this.remainderFrames = this.stream.readUInt32(); this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0); this.sentDuration = true; byteOffset = 0; sampleOffset = 0; for (i = _i = 0, _ref = this.numPackets; _i < _ref; i = _i += 1) { this.addSeekPoint(byteOffset, sampleOffset); byteOffset += this.format.bytesPerPacket || M4ADemuxer.readDescrLen(this.stream); sampleOffset += this.format.framesPerPacket || M4ADemuxer.readDescrLen(this.stream); } this.headerCache = null; } break; case 'info': entries = this.stream.readUInt32(); metadata = {}; for (i = _j = 0; 0 <= entries ? _j < entries : _j > entries; i = 0 <= entries ? ++_j : --_j) { key = this.stream.readString(null); value = this.stream.readString(null); metadata[key] = value; } this.emit('metadata', metadata); this.headerCache = null; break; case 'data': if (!this.sentFirstDataChunk) { this.stream.advance(4); this.headerCache.size -= 4; if (this.format.bytesPerPacket !== 0 && !this.sentDuration) { this.numFrames = this.headerCache.size / this.format.bytesPerPacket; this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0); } this.sentFirstDataChunk = true; } buffer = this.stream.readSingleBuffer(this.headerCache.size); this.headerCache.size -= buffer.length; this.emit('data', buffer); if (this.headerCache.size <= 0) { this.headerCache = null; } break; default: if (this.stream.available(this.headerCache.size)) { this.stream.advance(this.headerCache.size); this.headerCache = null; } } } }; return CAFDemuxer; })(Demuxer); },{"../demuxer":15,"./m4a":19}],19:[function(_dereq_,module,exports){ var Demuxer, M4ADemuxer, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Demuxer = _dereq_('../demuxer'); M4ADemuxer = (function(_super) { var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string; __extends(M4ADemuxer, _super); function M4ADemuxer() { return M4ADemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(M4ADemuxer); TYPES = ['M4A ', 'M4P ', 'M4B ', 'M4V ', 'isom', 'mp42', 'qt ']; M4ADemuxer.probe = function(buffer) { var _ref; return buffer.peekString(4, 4) === 'ftyp' && (_ref = buffer.peekString(8, 4), __indexOf.call(TYPES, _ref) >= 0); }; M4ADemuxer.prototype.init = function() { this.atoms = []; this.offsets = []; this.track = null; return this.tracks = []; }; atoms = {}; containers = {}; atom = function(name, fn) { var c, container, _i, _len, _ref; c = []; _ref = name.split('.').slice(0, -1); for (_i = 0, _len = _ref.length; _i < _len; _i++) { container = _ref[_i]; c.push(container); containers[c.join('.')] = true; } if (atoms[name] == null) { atoms[name] = {}; } return atoms[name].fn = fn; }; after = function(name, fn) { if (atoms[name] == null) { atoms[name] = {}; } return atoms[name].after = fn; }; M4ADemuxer.prototype.readChunk = function() { var handler, path, type; this["break"] = false; while (this.stream.available(1) && !this["break"]) { if (!this.readHeaders) { if (!this.stream.available(8)) { return; } this.len = this.stream.readUInt32() - 8; this.type = this.stream.readString(4); if (this.len === 0) { continue; } this.atoms.push(this.type); this.offsets.push(this.stream.offset + this.len); this.readHeaders = true; } path = this.atoms.join('.'); handler = atoms[path]; if (handler != null ? handler.fn : void 0) { if (!(this.stream.available(this.len) || path === 'mdat')) { return; } handler.fn.call(this); if (path in containers) { this.readHeaders = false; } } else if (path in containers) { this.readHeaders = false; } else { if (!this.stream.available(this.len)) { return; } this.stream.advance(this.len); } while (this.stream.offset >= this.offsets[this.offsets.length - 1]) { handler = atoms[this.atoms.join('.')]; if (handler != null ? handler.after : void 0) { handler.after.call(this); } type = this.atoms.pop(); this.offsets.pop(); this.readHeaders = false; } } }; atom('ftyp', function() { var _ref; if (_ref = this.stream.readString(4), __indexOf.call(TYPES, _ref) < 0) { return this.emit('error', 'Not a valid M4A file.'); } return this.stream.advance(this.len - 4); }); atom('moov.trak', function() { this.track = {}; return this.tracks.push(this.track); }); atom('moov.trak.tkhd', function() { this.stream.advance(4); this.stream.advance(8); this.track.id = this.stream.readUInt32(); return this.stream.advance(this.len - 16); }); atom('moov.trak.mdia.hdlr', function() { this.stream.advance(4); this.stream.advance(4); this.track.type = this.stream.readString(4); this.stream.advance(12); return this.stream.advance(this.len - 24); }); atom('moov.trak.mdia.mdhd', function() { this.stream.advance(4); this.stream.advance(8); this.track.timeScale = this.stream.readUInt32(); this.track.duration = this.stream.readUInt32(); return this.stream.advance(4); }); BITS_PER_CHANNEL = { ulaw: 8, alaw: 8, in24: 24, in32: 32, fl32: 32, fl64: 64 }; atom('moov.trak.mdia.minf.stbl.stsd', function() { var format, numEntries, version, _ref, _ref1; this.stream.advance(4); numEntries = this.stream.readUInt32(); if (this.track.type !== 'soun') { return this.stream.advance(this.len - 8); } if (numEntries !== 1) { return this.emit('error', "Only expecting one entry in sample description atom!"); } this.stream.advance(4); format = this.track.format = {}; format.formatID = this.stream.readString(4); this.stream.advance(6); this.stream.advance(2); version = this.stream.readUInt16(); this.stream.advance(6); format.channelsPerFrame = this.stream.readUInt16(); format.bitsPerChannel = this.stream.readUInt16(); this.stream.advance(4); format.sampleRate = this.stream.readUInt16(); this.stream.advance(2); if (version === 1) { format.framesPerPacket = this.stream.readUInt32(); this.stream.advance(4); format.bytesPerFrame = this.stream.readUInt32(); this.stream.advance(4); } else if (version !== 0) { this.emit('error', 'Unknown version in stsd atom'); } if (BITS_PER_CHANNEL[format.formatID] != null) { format.bitsPerChannel = BITS_PER_CHANNEL[format.formatID]; } format.floatingPoint = (_ref = format.formatID) === 'fl32' || _ref === 'fl64'; format.littleEndian = format.formatID === 'sowt' && format.bitsPerChannel > 8; if ((_ref1 = format.formatID) === 'twos' || _ref1 === 'sowt' || _ref1 === 'in24' || _ref1 === 'in32' || _ref1 === 'fl32' || _ref1 === 'fl64' || _ref1 === 'raw ' || _ref1 === 'NONE') { return format.formatID = 'lpcm'; } }); atom('moov.trak.mdia.minf.stbl.stsd.alac', function() { this.stream.advance(4); return this.track.cookie = this.stream.readBuffer(this.len - 4); }); atom('moov.trak.mdia.minf.stbl.stsd.esds', function() { var offset; offset = this.stream.offset + this.len; this.track.cookie = M4ADemuxer.readEsds(this.stream); return this.stream.seek(offset); }); atom('moov.trak.mdia.minf.stbl.stsd.wave.enda', function() { return this.track.format.littleEndian = !!this.stream.readUInt16(); }); M4ADemuxer.readDescrLen = function(stream) { var c, count, len; len = 0; count = 4; while (count--) { c = stream.readUInt8(); len = (len << 7) | (c & 0x7f); if (!(c & 0x80)) { break; } } return len; }; M4ADemuxer.readEsds = function(stream) { var codec_id, flags, len, tag; stream.advance(4); tag = stream.readUInt8(); len = M4ADemuxer.readDescrLen(stream); if (tag === 0x03) { stream.advance(2); flags = stream.readUInt8(); if (flags & 0x80) { stream.advance(2); } if (flags & 0x40) { stream.advance(stream.readUInt8()); } if (flags & 0x20) { stream.advance(2); } } else { stream.advance(2); } tag = stream.readUInt8(); len = M4ADemuxer.readDescrLen(stream); if (tag === 0x04) { codec_id = stream.readUInt8(); stream.advance(1); stream.advance(3); stream.advance(4); stream.advance(4); tag = stream.readUInt8(); len = M4ADemuxer.readDescrLen(stream); if (tag === 0x05) { return stream.readBuffer(len); } } return null; }; atom('moov.trak.mdia.minf.stbl.stts', function() { var entries, i, _i; this.stream.advance(4); entries = this.stream.readUInt32(); this.track.stts = []; for (i = _i = 0; _i < entries; i = _i += 1) { this.track.stts[i] = { count: this.stream.readUInt32(), duration: this.stream.readUInt32() }; } return this.setupSeekPoints(); }); atom('moov.trak.mdia.minf.stbl.stsc', function() { var entries, i, _i; this.stream.advance(4); entries = this.stream.readUInt32(); this.track.stsc = []; for (i = _i = 0; _i < entries; i = _i += 1) { this.track.stsc[i] = { first: this.stream.readUInt32(), count: this.stream.readUInt32(), id: this.stream.readUInt32() }; } return this.setupSeekPoints(); }); atom('moov.trak.mdia.minf.stbl.stsz', function() { var entries, i, _i; this.stream.advance(4); this.track.sampleSize = this.stream.readUInt32(); entries = this.stream.readUInt32(); if (this.track.sampleSize === 0 && entries > 0) { this.track.sampleSizes = []; for (i = _i = 0; _i < entries; i = _i += 1) { this.track.sampleSizes[i] = this.stream.readUInt32(); } } return this.setupSeekPoints(); }); atom('moov.trak.mdia.minf.stbl.stco', function() { var entries, i, _i; this.stream.advance(4); entries = this.stream.readUInt32(); this.track.chunkOffsets = []; for (i = _i = 0; _i < entries; i = _i += 1) { this.track.chunkOffsets[i] = this.stream.readUInt32(); } return this.setupSeekPoints(); }); atom('moov.trak.tref.chap', function() { var entries, i, _i; entries = this.len >> 2; this.track.chapterTracks = []; for (i = _i = 0; _i < entries; i = _i += 1) { this.track.chapterTracks[i] = this.stream.readUInt32(); } }); M4ADemuxer.prototype.setupSeekPoints = function() { var i, j, offset, position, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp, _i, _j, _len, _ref, _ref1, _results; if (!((this.track.chunkOffsets != null) && (this.track.stsc != null) && (this.track.sampleSize != null) && (this.track.stts != null))) { return; } stscIndex = 0; sttsIndex = 0; sttsIndex = 0; sttsSample = 0; sampleIndex = 0; offset = 0; timestamp = 0; this.track.seekPoints = []; _ref = this.track.chunkOffsets; _results = []; for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { position = _ref[i]; for (j = _j = 0, _ref1 = this.track.stsc[stscIndex].count; _j < _ref1; j = _j += 1) { this.track.seekPoints.push({ offset: offset, position: position, timestamp: timestamp }); size = this.track.sampleSize || this.track.sampleSizes[sampleIndex++]; offset += size; position += size; timestamp += this.track.stts[sttsIndex].duration; if (sttsIndex + 1 < this.track.stts.length && ++sttsSample === this.track.stts[sttsIndex].count) { sttsSample = 0; sttsIndex++; } } if (stscIndex + 1 < this.track.stsc.length && i + 1 === this.track.stsc[stscIndex + 1].first) { _results.push(stscIndex++); } else { _results.push(void 0); } } return _results; }; after('moov', function() { var track, _i, _len, _ref; if (this.mdatOffset != null) { this.stream.seek(this.mdatOffset - 8); } _ref = this.tracks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { track = _ref[_i]; if (!(track.type === 'soun')) { continue; } this.track = track; break; } if (this.track.type !== 'soun') { this.track = null; return this.emit('error', 'No audio tracks in m4a file.'); } this.emit('format', this.track.format); this.emit('duration', this.track.duration / this.track.timeScale * 1000 | 0); if (this.track.cookie) { this.emit('cookie', this.track.cookie); } return this.seekPoints = this.track.seekPoints; }); atom('mdat', function() { var bytes, chunkSize, length, numSamples, offset, sample, size, _i; if (!this.startedData) { if (this.mdatOffset == null) { this.mdatOffset = this.stream.offset; } if (this.tracks.length === 0) { bytes = Math.min(this.stream.remainingBytes(), this.len); this.stream.advance(bytes); this.len -= bytes; return; } this.chunkIndex = 0; this.stscIndex = 0; this.sampleIndex = 0; this.tailOffset = 0; this.tailSamples = 0; this.startedData = true; } if (!this.readChapters) { this.readChapters = this.parseChapters(); if (this["break"] = !this.readChapters) { return; } this.stream.seek(this.mdatOffset); } offset = this.track.chunkOffsets[this.chunkIndex] + this.tailOffset; length = 0; if (!this.stream.available(offset - this.stream.offset)) { this["break"] = true; return; } this.stream.seek(offset); while (this.chunkIndex < this.track.chunkOffsets.length) { numSamples = this.track.stsc[this.stscIndex].count - this.tailSamples; chunkSize = 0; for (sample = _i = 0; _i < numSamples; sample = _i += 1) { size = this.track.sampleSize || this.track.sampleSizes[this.sampleIndex]; if (!this.stream.available(length + size)) { break; } length += size; chunkSize += size; this.sampleIndex++; } if (sample < numSamples) { this.tailOffset += chunkSize; this.tailSamples += sample; break; } else { this.chunkIndex++; this.tailOffset = 0; this.tailSamples = 0; if (this.stscIndex + 1 < this.track.stsc.length && this.chunkIndex + 1 === this.track.stsc[this.stscIndex + 1].first) { this.stscIndex++; } if (offset + length !== this.track.chunkOffsets[this.chunkIndex]) { break; } } } if (length > 0) { this.emit('data', this.stream.readBuffer(length)); return this["break"] = this.chunkIndex === this.track.chunkOffsets.length; } else { return this["break"] = true; } }); M4ADemuxer.prototype.parseChapters = function() { var bom, id, len, nextTimestamp, point, title, track, _i, _len, _ref, _ref1, _ref2, _ref3; if (!(((_ref = this.track.chapterTracks) != null ? _ref.length : void 0) > 0)) { return true; } id = this.track.chapterTracks[0]; _ref1 = this.tracks; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { track = _ref1[_i]; if (track.id === id) { break; } } if (track.id !== id) { this.emit('error', 'Chapter track does not exist.'); } if (this.chapters == null) { this.chapters = []; } while (this.chapters.length < track.seekPoints.length) { point = track.seekPoints[this.chapters.length]; if (!this.stream.available(point.position - this.stream.offset + 32)) { return false; } this.stream.seek(point.position); len = this.stream.readUInt16(); title = null; if (!this.stream.available(len)) { return false; } if (len > 2) { bom = this.stream.peekUInt16(); if (bom === 0xfeff || bom === 0xfffe) { title = this.stream.readString(len, 'utf16-bom'); } } if (title == null) { title = this.stream.readString(len, 'utf8'); } nextTimestamp = (_ref2 = (_ref3 = track.seekPoints[this.chapters.length + 1]) != null ? _ref3.timestamp : void 0) != null ? _ref2 : track.duration; this.chapters.push({ title: title, timestamp: point.timestamp / track.timeScale * 1000 | 0, duration: (nextTimestamp - point.timestamp) / track.timeScale * 1000 | 0 }); } this.emit('chapters', this.chapters); return true; }; atom('moov.udta.meta', function() { this.metadata = {}; return this.stream.advance(4); }); after('moov.udta.meta', function() { return this.emit('metadata', this.metadata); }); meta = function(field, name, fn) { return atom("moov.udta.meta.ilst." + field + ".data", function() { this.stream.advance(8); this.len -= 8; return fn.call(this, name); }); }; string = function(field) { return this.metadata[field] = this.stream.readString(this.len, 'utf8'); }; meta('©alb', 'album', string); meta('©arg', 'arranger', string); meta('©art', 'artist', string); meta('©ART', 'artist', string); meta('aART', 'albumArtist', string); meta('catg', 'category', string); meta('©com', 'composer', string); meta('©cpy', 'copyright', string); meta('cprt', 'copyright', string); meta('©cmt', 'comments', string); meta('©day', 'releaseDate', string); meta('desc', 'description', string); meta('©gen', 'genre', string); meta('©grp', 'grouping', string); meta('©isr', 'ISRC', string); meta('keyw', 'keywords', string); meta('©lab', 'recordLabel', string); meta('ldes', 'longDescription', string); meta('©lyr', 'lyrics', string); meta('©nam', 'title', string); meta('©phg', 'recordingCopyright', string); meta('©prd', 'producer', string); meta('©prf', 'performers', string); meta('purd', 'purchaseDate', string); meta('purl', 'podcastURL', string); meta('©swf', 'songwriter', string); meta('©too', 'encoder', string); meta('©wrt', 'composer', string); meta('covr', 'coverArt', function(field) { return this.metadata[field] = this.stream.readBuffer(this.len); }); genres = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall"]; meta('gnre', 'genre', function(field) { return this.metadata[field] = genres[this.stream.readUInt16() - 1]; }); meta('tmpo', 'tempo', function(field) { return this.metadata[field] = this.stream.readUInt16(); }); meta('rtng', 'rating', function(field) { var rating; rating = this.stream.readUInt8(); return this.metadata[field] = rating === 2 ? 'Clean' : rating !== 0 ? 'Explicit' : 'None'; }); diskTrack = function(field) { this.stream.advance(2); this.metadata[field] = this.stream.readUInt16() + ' of ' + this.stream.readUInt16(); return this.stream.advance(this.len - 6); }; meta('disk', 'diskNumber', diskTrack); meta('trkn', 'trackNumber', diskTrack); bool = function(field) { return this.metadata[field] = this.stream.readUInt8() === 1; }; meta('cpil', 'compilation', bool); meta('pcst', 'podcast', bool); meta('pgap', 'gapless', bool); return M4ADemuxer; })(Demuxer); module.exports = M4ADemuxer; },{"../demuxer":15}],20:[function(_dereq_,module,exports){ var Demuxer, WAVEDemuxer, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Demuxer = _dereq_('../demuxer'); WAVEDemuxer = (function(_super) { var formats; __extends(WAVEDemuxer, _super); function WAVEDemuxer() { return WAVEDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(WAVEDemuxer); WAVEDemuxer.probe = function(buffer) { return buffer.peekString(0, 4) === 'RIFF' && buffer.peekString(8, 4) === 'WAVE'; }; formats = { 0x0001: 'lpcm', 0x0003: 'lpcm', 0x0006: 'alaw', 0x0007: 'ulaw' }; WAVEDemuxer.prototype.readChunk = function() { var buffer, bytes, encoding; if (!this.readStart && this.stream.available(12)) { if (this.stream.readString(4) !== 'RIFF') { return this.emit('error', 'Invalid WAV file.'); } this.fileSize = this.stream.readUInt32(true); this.readStart = true; if (this.stream.readString(4) !== 'WAVE') { return this.emit('error', 'Invalid WAV file.'); } } while (this.stream.available(1)) { if (!this.readHeaders && this.stream.available(8)) { this.type = this.stream.readString(4); this.len = this.stream.readUInt32(true); } switch (this.type) { case 'fmt ': encoding = this.stream.readUInt16(true); if (!(encoding in formats)) { return this.emit('error', 'Unsupported format in WAV file.'); } this.format = { formatID: formats[encoding], floatingPoint: encoding === 0x0003, littleEndian: formats[encoding] === 'lpcm', channelsPerFrame: this.stream.readUInt16(true), sampleRate: this.stream.readUInt32(true), framesPerPacket: 1 }; this.stream.advance(4); this.stream.advance(2); this.format.bitsPerChannel = this.stream.readUInt16(true); this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame; this.emit('format', this.format); this.stream.advance(this.len - 16); break; case 'data': if (!this.sentDuration) { bytes = this.format.bitsPerChannel / 8; this.emit('duration', this.len / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0); this.sentDuration = true; } buffer = this.stream.readSingleBuffer(this.len); this.len -= buffer.length; this.readHeaders = this.len > 0; this.emit('data', buffer); break; default: if (!this.stream.available(this.len)) { return; } this.stream.advance(this.len); } if (this.type !== 'data') { this.readHeaders = false; } } }; return WAVEDemuxer; })(Demuxer); },{"../demuxer":15}],21:[function(_dereq_,module,exports){ var AudioDevice, EventEmitter, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('./core/events'); AudioDevice = (function(_super) { var devices; __extends(AudioDevice, _super); function AudioDevice(sampleRate, channels) { this.sampleRate = sampleRate; this.channels = channels; this.updateTime = __bind(this.updateTime, this); this.playing = false; this.currentTime = 0; this._lastTime = 0; } AudioDevice.prototype.start = function() { if (this.playing) { return; } this.playing = true; if (this.device == null) { this.device = AudioDevice.create(this.sampleRate, this.channels); } if (!this.device) { throw new Error("No supported audio device found."); } this._lastTime = this.device.getDeviceTime(); this._timer = setInterval(this.updateTime, 200); return this.device.on('refill', this.refill = (function(_this) { return function(buffer) { return _this.emit('refill', buffer); }; })(this)); }; AudioDevice.prototype.stop = function() { if (!this.playing) { return; } this.playing = false; this.device.off('refill', this.refill); return clearInterval(this._timer); }; AudioDevice.prototype.destroy = function() { this.stop(); return this.device.destroy(); }; AudioDevice.prototype.seek = function(currentTime) { this.currentTime = currentTime; if (this.playing) { this._lastTime = this.device.getDeviceTime(); } return this.emit('timeUpdate', this.currentTime); }; AudioDevice.prototype.updateTime = function() { var time; time = this.device.getDeviceTime(); this.currentTime += (time - this._lastTime) / this.device.sampleRate * 1000 | 0; this._lastTime = time; return this.emit('timeUpdate', this.currentTime); }; devices = []; AudioDevice.register = function(device) { return devices.push(device); }; AudioDevice.create = function(sampleRate, channels) { var device, _i, _len; for (_i = 0, _len = devices.length; _i < _len; _i++) { device = devices[_i]; if (device.supported) { return new device(sampleRate, channels); } } return null; }; return AudioDevice; })(EventEmitter); module.exports = AudioDevice; },{"./core/events":9}],22:[function(_dereq_,module,exports){ var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('../core/events'); AudioDevice = _dereq_('../device'); AVBuffer = _dereq_('../core/buffer'); MozillaAudioDevice = (function(_super) { var createTimer, destroyTimer; __extends(MozillaAudioDevice, _super); AudioDevice.register(MozillaAudioDevice); MozillaAudioDevice.supported = (typeof Audio !== "undefined" && Audio !== null) && 'mozWriteAudio' in new Audio; function MozillaAudioDevice(sampleRate, channels) { this.sampleRate = sampleRate; this.channels = channels; this.refill = __bind(this.refill, this); this.audio = new Audio; this.audio.mozSetup(this.channels, this.sampleRate); this.writePosition = 0; this.prebufferSize = this.sampleRate / 2; this.tail = null; this.timer = createTimer(this.refill, 100); } MozillaAudioDevice.prototype.refill = function() { var available, buffer, currentPosition, written; if (this.tail) { written = this.audio.mozWriteAudio(this.tail); this.writePosition += written; if (this.writePosition < this.tail.length) { this.tail = this.tail.subarray(written); } else { this.tail = null; } } currentPosition = this.audio.mozCurrentSampleOffset(); available = currentPosition + this.prebufferSize - this.writePosition; if (available > 0) { buffer = new Float32Array(available); this.emit('refill', buffer); written = this.audio.mozWriteAudio(buffer); if (written < buffer.length) { this.tail = buffer.subarray(written); } this.writePosition += written; } }; MozillaAudioDevice.prototype.destroy = function() { return destroyTimer(this.timer); }; MozillaAudioDevice.prototype.getDeviceTime = function() { return this.audio.mozCurrentSampleOffset() / this.channels; }; createTimer = function(fn, interval) { var url, worker; url = AVBuffer.makeBlobURL("setInterval(function() { postMessage('ping'); }, " + interval + ");"); if (url == null) { return setInterval(fn, interval); } worker = new Worker(url); worker.onmessage = fn; worker.url = url; return worker; }; destroyTimer = function(timer) { if (timer.terminate) { timer.terminate(); return URL.revokeObjectURL(timer.url); } else { return clearInterval(timer); } }; return MozillaAudioDevice; })(EventEmitter); },{"../core/buffer":7,"../core/events":9,"../device":21}],23:[function(_dereq_,module,exports){ /* * This resampler is from XAudioJS: https://github.com/grantgalitz/XAudioJS * Planned to be replaced with src.js, eventually: https://github.com/jussi-kalliokoski/src.js */ //JavaScript Audio Resampler (c) 2011 - Grant Galitz function Resampler(fromSampleRate, toSampleRate, channels, outputBufferSize, noReturn) { this.fromSampleRate = fromSampleRate; this.toSampleRate = toSampleRate; this.channels = channels | 0; this.outputBufferSize = outputBufferSize; this.noReturn = !!noReturn; this.initialize(); } Resampler.prototype.initialize = function () { //Perform some checks: if (this.fromSampleRate > 0 && this.toSampleRate > 0 && this.channels > 0) { if (this.fromSampleRate == this.toSampleRate) { //Setup a resampler bypass: this.resampler = this.bypassResampler; //Resampler just returns what was passed through. this.ratioWeight = 1; } else { if (this.fromSampleRate < this.toSampleRate) { /* Use generic linear interpolation if upsampling, as linear interpolation produces a gradient that we want and works fine with two input sample points per output in this case. */ this.compileLinearInterpolationFunction(); this.lastWeight = 1; } else { /* Custom resampler I wrote that doesn't skip samples like standard linear interpolation in high downsampling. This is more accurate than linear interpolation on downsampling. */ this.compileMultiTapFunction(); this.tailExists = false; this.lastWeight = 0; } this.ratioWeight = this.fromSampleRate / this.toSampleRate; this.initializeBuffers(); } } else { throw(new Error("Invalid settings specified for the resampler.")); } }; Resampler.prototype.compileLinearInterpolationFunction = function () { var toCompile = "var bufferLength = buffer.length;\ var outLength = this.outputBufferSize;\ if ((bufferLength % " + this.channels + ") == 0) {\ if (bufferLength > 0) {\ var ratioWeight = this.ratioWeight;\ var weight = this.lastWeight;\ var firstWeight = 0;\ var secondWeight = 0;\ var sourceOffset = 0;\ var outputOffset = 0;\ var outputBuffer = this.outputBuffer;\ for (; weight < 1; weight += ratioWeight) {\ secondWeight = weight % 1;\ firstWeight = 1 - secondWeight;"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "outputBuffer[outputOffset++] = (this.lastOutput[" + channel + "] * firstWeight) + (buffer[" + channel + "] * secondWeight);"; } toCompile += "}\ weight -= 1;\ for (bufferLength -= " + this.channels + ", sourceOffset = Math.floor(weight) * " + this.channels + "; outputOffset < outLength && sourceOffset < bufferLength;) {\ secondWeight = weight % 1;\ firstWeight = 1 - secondWeight;"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "outputBuffer[outputOffset++] = (buffer[sourceOffset" + ((channel > 0) ? (" + " + channel) : "") + "] * firstWeight) + (buffer[sourceOffset + " + (this.channels + channel) + "] * secondWeight);"; } toCompile += "weight += ratioWeight;\ sourceOffset = Math.floor(weight) * " + this.channels + ";\ }"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "this.lastOutput[" + channel + "] = buffer[sourceOffset++];"; } toCompile += "this.lastWeight = weight % 1;\ return this.bufferSlice(outputOffset);\ }\ else {\ return (this.noReturn) ? 0 : [];\ }\ }\ else {\ throw(new Error(\"Buffer was of incorrect sample length.\"));\ }"; this.resampler = Function("buffer", toCompile); }; Resampler.prototype.compileMultiTapFunction = function () { var toCompile = "var bufferLength = buffer.length;\ var outLength = this.outputBufferSize;\ if ((bufferLength % " + this.channels + ") == 0) {\ if (bufferLength > 0) {\ var ratioWeight = this.ratioWeight;\ var weight = 0;"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "var output" + channel + " = 0;" } toCompile += "var actualPosition = 0;\ var amountToNext = 0;\ var alreadyProcessedTail = !this.tailExists;\ this.tailExists = false;\ var outputBuffer = this.outputBuffer;\ var outputOffset = 0;\ var currentPosition = 0;\ do {\ if (alreadyProcessedTail) {\ weight = ratioWeight;"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " = 0;" } toCompile += "}\ else {\ weight = this.lastWeight;"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " = this.lastOutput[" + channel + "];" } toCompile += "alreadyProcessedTail = true;\ }\ while (weight > 0 && actualPosition < bufferLength) {\ amountToNext = 1 + actualPosition - currentPosition;\ if (weight >= amountToNext) {"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " += buffer[actualPosition++] * amountToNext;" } toCompile += "currentPosition = actualPosition;\ weight -= amountToNext;\ }\ else {"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " += buffer[actualPosition" + ((channel > 0) ? (" + " + channel) : "") + "] * weight;" } toCompile += "currentPosition += weight;\ weight = 0;\ break;\ }\ }\ if (weight == 0) {"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "outputBuffer[outputOffset++] = output" + channel + " / ratioWeight;" } toCompile += "}\ else {\ this.lastWeight = weight;"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "this.lastOutput[" + channel + "] = output" + channel + ";" } toCompile += "this.tailExists = true;\ break;\ }\ } while (actualPosition < bufferLength && outputOffset < outLength);\ return this.bufferSlice(outputOffset);\ }\ else {\ return (this.noReturn) ? 0 : [];\ }\ }\ else {\ throw(new Error(\"Buffer was of incorrect sample length.\"));\ }"; this.resampler = Function("buffer", toCompile); }; Resampler.prototype.bypassResampler = function (buffer) { if (this.noReturn) { //Set the buffer passed as our own, as we don't need to resample it: this.outputBuffer = buffer; return buffer.length; } else { //Just return the buffer passsed: return buffer; } }; Resampler.prototype.bufferSlice = function (sliceAmount) { if (this.noReturn) { //If we're going to access the properties directly from this object: return sliceAmount; } else { //Typed array and normal array buffer section referencing: try { return this.outputBuffer.subarray(0, sliceAmount); } catch (error) { try { //Regular array pass: this.outputBuffer.length = sliceAmount; return this.outputBuffer; } catch (error) { //Nightly Firefox 4 used to have the subarray function named as slice: return this.outputBuffer.slice(0, sliceAmount); } } } }; Resampler.prototype.initializeBuffers = function () { //Initialize the internal buffer: try { this.outputBuffer = new Float32Array(this.outputBufferSize); this.lastOutput = new Float32Array(this.channels); } catch (error) { this.outputBuffer = []; this.lastOutput = []; } }; module.exports = Resampler; },{}],24:[function(_dereq_,module,exports){ (function (global){ var AudioDevice, EventEmitter, Resampler, WebAudioDevice, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('../core/events'); AudioDevice = _dereq_('../device'); Resampler = _dereq_('./resampler'); WebAudioDevice = (function(_super) { var AudioContext, createProcessor, sharedContext; __extends(WebAudioDevice, _super); AudioDevice.register(WebAudioDevice); AudioContext = global.AudioContext || global.webkitAudioContext; WebAudioDevice.supported = AudioContext && (typeof AudioContext.prototype[createProcessor = 'createScriptProcessor'] === 'function' || typeof AudioContext.prototype[createProcessor = 'createJavaScriptNode'] === 'function'); sharedContext = null; function WebAudioDevice(sampleRate, channels) { this.sampleRate = sampleRate; this.channels = channels; this.refill = __bind(this.refill, this); this.context = sharedContext != null ? sharedContext : sharedContext = new AudioContext; this.deviceSampleRate = this.context.sampleRate; this.bufferSize = Math.ceil(4096 / (this.deviceSampleRate / this.sampleRate) * this.channels); this.bufferSize += this.bufferSize % this.channels; if (this.deviceSampleRate !== this.sampleRate) { this.resampler = new Resampler(this.sampleRate, this.deviceSampleRate, this.channels, 4096 * this.channels); } this.node = this.context[createProcessor](4096, this.channels, this.channels); this.node.onaudioprocess = this.refill; this.node.connect(this.context.destination); } WebAudioDevice.prototype.refill = function(event) { var channelCount, channels, data, i, n, outputBuffer, _i, _j, _k, _ref; outputBuffer = event.outputBuffer; channelCount = outputBuffer.numberOfChannels; channels = new Array(channelCount); for (i = _i = 0; _i < channelCount; i = _i += 1) { channels[i] = outputBuffer.getChannelData(i); } data = new Float32Array(this.bufferSize); this.emit('refill', data); if (this.resampler) { data = this.resampler.resampler(data); } for (i = _j = 0, _ref = outputBuffer.length; _j < _ref; i = _j += 1) { for (n = _k = 0; _k < channelCount; n = _k += 1) { channels[n][i] = data[i * channelCount + n]; } } }; WebAudioDevice.prototype.destroy = function() { return this.node.disconnect(0); }; WebAudioDevice.prototype.getDeviceTime = function() { return this.context.currentTime * this.sampleRate; }; return WebAudioDevice; })(EventEmitter); }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../core/events":9,"../device":21,"./resampler":23}],25:[function(_dereq_,module,exports){ var Filter; Filter = (function() { function Filter(context, key) { if (context && key) { Object.defineProperty(this, 'value', { get: function() { return context[key]; } }); } } Filter.prototype.process = function(buffer) {}; return Filter; })(); module.exports = Filter; },{}],26:[function(_dereq_,module,exports){ var BalanceFilter, Filter, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Filter = _dereq_('../filter'); BalanceFilter = (function(_super) { __extends(BalanceFilter, _super); function BalanceFilter() { return BalanceFilter.__super__.constructor.apply(this, arguments); } BalanceFilter.prototype.process = function(buffer) { var i, pan, _i, _ref; if (this.value === 0) { return; } pan = Math.max(-50, Math.min(50, this.value)); for (i = _i = 0, _ref = buffer.length; _i < _ref; i = _i += 2) { buffer[i] *= Math.min(1, (50 - pan) / 50); buffer[i + 1] *= Math.min(1, (50 + pan) / 50); } }; return BalanceFilter; })(Filter); module.exports = BalanceFilter; },{"../filter":25}],27:[function(_dereq_,module,exports){ var Filter, VolumeFilter, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Filter = _dereq_('../filter'); VolumeFilter = (function(_super) { __extends(VolumeFilter, _super); function VolumeFilter() { return VolumeFilter.__super__.constructor.apply(this, arguments); } VolumeFilter.prototype.process = function(buffer) { var i, vol, _i, _ref; if (this.value >= 100) { return; } vol = Math.max(0, Math.min(100, this.value)) / 100; for (i = _i = 0, _ref = buffer.length; _i < _ref; i = _i += 1) { buffer[i] *= vol; } }; return VolumeFilter; })(Filter); module.exports = VolumeFilter; },{"../filter":25}],28:[function(_dereq_,module,exports){ var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('./core/events'); Asset = _dereq_('./asset'); VolumeFilter = _dereq_('./filters/volume'); BalanceFilter = _dereq_('./filters/balance'); Queue = _dereq_('./queue'); AudioDevice = _dereq_('./device'); Player = (function(_super) { __extends(Player, _super); function Player(asset) { this.asset = asset; this.startPlaying = __bind(this.startPlaying, this); this.playing = false; this.buffered = 0; this.currentTime = 0; this.duration = 0; this.volume = 100; this.pan = 0; this.metadata = {}; this.filters = [new VolumeFilter(this, 'volume'), new BalanceFilter(this, 'pan')]; this.asset.on('buffer', (function(_this) { return function(buffered) { _this.buffered = buffered; return _this.emit('buffer', _this.buffered); }; })(this)); this.asset.on('decodeStart', (function(_this) { return function() { _this.queue = new Queue(_this.asset); return _this.queue.once('ready', _this.startPlaying); }; })(this)); this.asset.on('format', (function(_this) { return function(format) { _this.format = format; return _this.emit('format', _this.format); }; })(this)); this.asset.on('metadata', (function(_this) { return function(metadata) { _this.metadata = metadata; return _this.emit('metadata', _this.metadata); }; })(this)); this.asset.on('duration', (function(_this) { return function(duration) { _this.duration = duration; return _this.emit('duration', _this.duration); }; })(this)); this.asset.on('error', (function(_this) { return function(error) { return _this.emit('error', error); }; })(this)); } Player.fromURL = function(url) { return new Player(Asset.fromURL(url)); }; Player.fromFile = function(file) { return new Player(Asset.fromFile(file)); }; Player.fromBuffer = function(buffer) { return new Player(Asset.fromBuffer(buffer)); }; Player.prototype.preload = function() { if (!this.asset) { return; } this.startedPreloading = true; return this.asset.start(false); }; Player.prototype.play = function() { var _ref; if (this.playing) { return; } if (!this.startedPreloading) { this.preload(); } this.playing = true; return (_ref = this.device) != null ? _ref.start() : void 0; }; Player.prototype.pause = function() { var _ref; if (!this.playing) { return; } this.playing = false; return (_ref = this.device) != null ? _ref.stop() : void 0; }; Player.prototype.togglePlayback = function() { if (this.playing) { return this.pause(); } else { return this.play(); } }; Player.prototype.stop = function() { var _ref; this.pause(); this.asset.stop(); return (_ref = this.device) != null ? _ref.destroy() : void 0; }; Player.prototype.seek = function(timestamp) { var _ref; if ((_ref = this.device) != null) { _ref.stop(); } this.queue.once('ready', (function(_this) { return function() { var _ref1, _ref2; if ((_ref1 = _this.device) != null) { _ref1.seek(_this.currentTime); } if (_this.playing) { return (_ref2 = _this.device) != null ? _ref2.start() : void 0; } }; })(this)); timestamp = (timestamp / 1000) * this.format.sampleRate; timestamp = this.asset.decoder.seek(timestamp); this.currentTime = timestamp / this.format.sampleRate * 1000 | 0; this.queue.reset(); return this.currentTime; }; Player.prototype.startPlaying = function() { var frame, frameOffset; frame = this.queue.read(); frameOffset = 0; this.device = new AudioDevice(this.format.sampleRate, this.format.channelsPerFrame); this.device.on('timeUpdate', (function(_this) { return function(currentTime) { _this.currentTime = currentTime; return _this.emit('progress', _this.currentTime); }; })(this)); this.refill = (function(_this) { return function(buffer) { var bufferOffset, filter, i, max, _i, _j, _len, _ref; if (!_this.playing) { return; } if (!frame) { frame = _this.queue.read(); frameOffset = 0; } bufferOffset = 0; while (frame && bufferOffset < buffer.length) { max = Math.min(frame.length - frameOffset, buffer.length - bufferOffset); for (i = _i = 0; _i < max; i = _i += 1) { buffer[bufferOffset++] = frame[frameOffset++]; } if (frameOffset === frame.length) { frame = _this.queue.read(); frameOffset = 0; } } _ref = _this.filters; for (_j = 0, _len = _ref.length; _j < _len; _j++) { filter = _ref[_j]; filter.process(buffer); } if (!frame) { if (_this.queue.ended) { _this.currentTime = _this.duration; _this.emit('progress', _this.currentTime); _this.emit('end'); _this.stop(); } else { _this.device.stop(); } } }; })(this); this.device.on('refill', this.refill); if (this.playing) { this.device.start(); } return this.emit('ready'); }; return Player; })(EventEmitter); module.exports = Player; },{"./asset":2,"./core/events":9,"./device":21,"./filters/balance":26,"./filters/volume":27,"./queue":29}],29:[function(_dereq_,module,exports){ var EventEmitter, Queue, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('./core/events'); Queue = (function(_super) { __extends(Queue, _super); function Queue(asset) { this.asset = asset; this.write = __bind(this.write, this); this.readyMark = 64; this.finished = false; this.buffering = true; this.ended = false; this.buffers = []; this.asset.on('data', this.write); this.asset.on('end', (function(_this) { return function() { return _this.ended = true; }; })(this)); this.asset.decodePacket(); } Queue.prototype.write = function(buffer) { if (buffer) { this.buffers.push(buffer); } if (this.buffering) { if (this.buffers.length >= this.readyMark || this.ended) { this.buffering = false; return this.emit('ready'); } else { return this.asset.decodePacket(); } } }; Queue.prototype.read = function() { if (this.buffers.length === 0) { return null; } this.asset.decodePacket(); return this.buffers.shift(); }; Queue.prototype.reset = function() { this.buffers.length = 0; this.buffering = true; return this.asset.decodePacket(); }; return Queue; })(EventEmitter); module.exports = Queue; },{"./core/events":9}],30:[function(_dereq_,module,exports){ var AVBuffer, EventEmitter, FileSource, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('../../core/events'); AVBuffer = _dereq_('../../core/buffer'); FileSource = (function(_super) { __extends(FileSource, _super); function FileSource(file) { this.file = file; if (typeof FileReader === "undefined" || FileReader === null) { return this.emit('error', 'This browser does not have FileReader support.'); } this.offset = 0; this.length = this.file.size; this.chunkSize = 1 << 20; this.file[this.slice = 'slice'] || this.file[this.slice = 'webkitSlice'] || this.file[this.slice = 'mozSlice']; } FileSource.prototype.start = function() { if (this.reader) { if (!this.active) { return this.loop(); } } this.reader = new FileReader; this.active = true; this.reader.onload = (function(_this) { return function(e) { var buf; buf = new AVBuffer(new Uint8Array(e.target.result)); _this.offset += buf.length; _this.emit('data', buf); _this.active = false; if (_this.offset < _this.length) { return _this.loop(); } }; })(this); this.reader.onloadend = (function(_this) { return function() { if (_this.offset === _this.length) { _this.emit('end'); return _this.reader = null; } }; })(this); this.reader.onerror = (function(_this) { return function(e) { return _this.emit('error', e); }; })(this); this.reader.onprogress = (function(_this) { return function(e) { return _this.emit('progress', (_this.offset + e.loaded) / _this.length * 100); }; })(this); return this.loop(); }; FileSource.prototype.loop = function() { var blob, endPos; this.active = true; endPos = Math.min(this.offset + this.chunkSize, this.length); blob = this.file[this.slice](this.offset, endPos); return this.reader.readAsArrayBuffer(blob); }; FileSource.prototype.pause = function() { var _ref; this.active = false; try { return (_ref = this.reader) != null ? _ref.abort() : void 0; } catch (_error) {} }; FileSource.prototype.reset = function() { this.pause(); return this.offset = 0; }; return FileSource; })(EventEmitter); module.exports = FileSource; },{"../../core/buffer":7,"../../core/events":9}],31:[function(_dereq_,module,exports){ var AVBuffer, EventEmitter, HTTPSource, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('../../core/events'); AVBuffer = _dereq_('../../core/buffer'); HTTPSource = (function(_super) { __extends(HTTPSource, _super); function HTTPSource(url) { this.url = url; this.chunkSize = 1 << 20; this.inflight = false; this.reset(); } HTTPSource.prototype.start = function() { if (this.length) { if (!this.inflight) { return this.loop(); } } this.inflight = true; this.xhr = new XMLHttpRequest(); this.xhr.onload = (function(_this) { return function(event) { _this.length = parseInt(_this.xhr.getResponseHeader("Content-Length")); _this.inflight = false; return _this.loop(); }; })(this); this.xhr.onerror = (function(_this) { return function(err) { _this.pause(); return _this.emit('error', err); }; })(this); this.xhr.onabort = (function(_this) { return function(event) { return _this.inflight = false; }; })(this); this.xhr.open("HEAD", this.url, true); return this.xhr.send(null); }; HTTPSource.prototype.loop = function() { var endPos; if (this.inflight || !this.length) { return this.emit('error', 'Something is wrong in HTTPSource.loop'); } this.inflight = true; this.xhr = new XMLHttpRequest(); this.xhr.onload = (function(_this) { return function(event) { var buf, buffer, i, txt, _i, _ref; if (_this.xhr.response) { buf = new Uint8Array(_this.xhr.response); } else { txt = _this.xhr.responseText; buf = new Uint8Array(txt.length); for (i = _i = 0, _ref = txt.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { buf[i] = txt.charCodeAt(i) & 0xff; } } buffer = new AVBuffer(buf); _this.offset += buffer.length; _this.emit('data', buffer); if (_this.offset >= _this.length) { _this.emit('end'); } _this.inflight = false; if (!(_this.offset >= _this.length)) { return _this.loop(); } }; })(this); this.xhr.onprogress = (function(_this) { return function(event) { return _this.emit('progress', (_this.offset + event.loaded) / _this.length * 100); }; })(this); this.xhr.onerror = (function(_this) { return function(err) { _this.emit('error', err); return _this.pause(); }; })(this); this.xhr.onabort = (function(_this) { return function(event) { return _this.inflight = false; }; })(this); this.xhr.open("GET", this.url, true); this.xhr.responseType = "arraybuffer"; endPos = Math.min(this.offset + this.chunkSize, this.length); this.xhr.setRequestHeader("Range", "bytes=" + this.offset + "-" + endPos); this.xhr.overrideMimeType('text/plain; charset=x-user-defined'); return this.xhr.send(null); }; HTTPSource.prototype.pause = function() { var _ref; this.inflight = false; return (_ref = this.xhr) != null ? _ref.abort() : void 0; }; HTTPSource.prototype.reset = function() { this.pause(); return this.offset = 0; }; return HTTPSource; })(EventEmitter); module.exports = HTTPSource; },{"../../core/buffer":7,"../../core/events":9}],32:[function(_dereq_,module,exports){ (function (global){ var AVBuffer, BufferList, BufferSource, EventEmitter, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; EventEmitter = _dereq_('../core/events'); BufferList = _dereq_('../core/bufferlist'); AVBuffer = _dereq_('../core/buffer'); BufferSource = (function(_super) { var clearImmediate, setImmediate; __extends(BufferSource, _super); function BufferSource(input) { this.loop = __bind(this.loop, this); if (input instanceof AV.BufferList) { this.list = input; } else { this.list = new BufferList; this.list.append(new AVBuffer(input)); } this.paused = true; } setImmediate = global.setImmediate || function(fn) { return global.setTimeout(fn, 0); }; clearImmediate = global.clearImmediate || function(timer) { return global.clearTimeout(timer); }; BufferSource.prototype.start = function() { this.paused = false; return this._timer = setImmediate(this.loop); }; BufferSource.prototype.loop = function() { this.emit('progress', (this.list.numBuffers - this.list.availableBuffers + 1) / this.list.numBuffers * 100 | 0); this.emit('data', this.list.first); if (this.list.advance()) { return setImmediate(this.loop); } else { return this.emit('end'); } }; BufferSource.prototype.pause = function() { clearImmediate(this._timer); return this.paused = true; }; BufferSource.prototype.reset = function() { this.pause(); return this.list.rewind(); }; return BufferSource; })(EventEmitter); module.exports = BufferSource; }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../core/buffer":7,"../core/bufferlist":8,"../core/events":9}]},{},[1]) (1) }); //# sourceMappingURL=aurora.js.map