@meframe/core
Version:
Next generation media processing framework based on WebCodecs
1,520 lines (1,519 loc) • 268 kB
JavaScript
var mp4box_all = {};
(function(exports) {
var Log = /* @__PURE__ */ function() {
var start = /* @__PURE__ */ new Date();
var LOG_LEVEL_ERROR = 4;
var LOG_LEVEL_WARNING = 3;
var LOG_LEVEL_INFO = 2;
var LOG_LEVEL_DEBUG = 1;
var log_level = LOG_LEVEL_ERROR;
var logObject = {
setLogLevel: function(level) {
if (level == this.debug) log_level = LOG_LEVEL_DEBUG;
else if (level == this.info) log_level = LOG_LEVEL_INFO;
else if (level == this.warn) log_level = LOG_LEVEL_WARNING;
else if (level == this.error) log_level = LOG_LEVEL_ERROR;
else log_level = LOG_LEVEL_ERROR;
},
debug: function(module, msg) {
if (console.debug === void 0) {
console.debug = console.log;
}
if (LOG_LEVEL_DEBUG >= log_level) {
console.debug("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
}
},
log: function(module, msg) {
this.debug(module.msg);
},
info: function(module, msg) {
if (LOG_LEVEL_INFO >= log_level) {
console.info("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
}
},
warn: function(module, msg) {
if (LOG_LEVEL_WARNING >= log_level) {
console.warn("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
}
},
error: function(module, msg) {
if (LOG_LEVEL_ERROR >= log_level) {
console.error("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
}
}
};
return logObject;
}();
Log.getDurationString = function(duration, _timescale) {
var neg;
function pad(number, length) {
var str = "" + number;
var a = str.split(".");
while (a[0].length < length) {
a[0] = "0" + a[0];
}
return a.join(".");
}
if (duration < 0) {
neg = true;
duration = -duration;
} else {
neg = false;
}
var timescale = _timescale || 1;
var duration_sec = duration / timescale;
var hours = Math.floor(duration_sec / 3600);
duration_sec -= hours * 3600;
var minutes = Math.floor(duration_sec / 60);
duration_sec -= minutes * 60;
var msec = duration_sec * 1e3;
duration_sec = Math.floor(duration_sec);
msec -= duration_sec * 1e3;
msec = Math.floor(msec);
return (neg ? "-" : "") + hours + ":" + pad(minutes, 2) + ":" + pad(duration_sec, 2) + "." + pad(msec, 3);
};
Log.printRanges = function(ranges) {
var length = ranges.length;
if (length > 0) {
var str = "";
for (var i2 = 0; i2 < length; i2++) {
if (i2 > 0) str += ",";
str += "[" + Log.getDurationString(ranges.start(i2)) + "," + Log.getDurationString(ranges.end(i2)) + "]";
}
return str;
} else {
return "(empty)";
}
};
{
exports.Log = Log;
}
var MP4BoxStream = function(arrayBuffer) {
if (arrayBuffer instanceof ArrayBuffer) {
this.buffer = arrayBuffer;
this.dataview = new DataView(arrayBuffer);
} else {
throw "Needs an array buffer";
}
this.position = 0;
};
MP4BoxStream.prototype.getPosition = function() {
return this.position;
};
MP4BoxStream.prototype.getEndPosition = function() {
return this.buffer.byteLength;
};
MP4BoxStream.prototype.getLength = function() {
return this.buffer.byteLength;
};
MP4BoxStream.prototype.seek = function(pos) {
var npos = Math.max(0, Math.min(this.buffer.byteLength, pos));
this.position = isNaN(npos) || !isFinite(npos) ? 0 : npos;
return true;
};
MP4BoxStream.prototype.isEos = function() {
return this.getPosition() >= this.getEndPosition();
};
MP4BoxStream.prototype.readAnyInt = function(size, signed) {
var res = 0;
if (this.position + size <= this.buffer.byteLength) {
switch (size) {
case 1:
if (signed) {
res = this.dataview.getInt8(this.position);
} else {
res = this.dataview.getUint8(this.position);
}
break;
case 2:
if (signed) {
res = this.dataview.getInt16(this.position);
} else {
res = this.dataview.getUint16(this.position);
}
break;
case 3:
if (signed) {
throw "No method for reading signed 24 bits values";
} else {
res = this.dataview.getUint8(this.position) << 16;
res |= this.dataview.getUint8(this.position + 1) << 8;
res |= this.dataview.getUint8(this.position + 2);
}
break;
case 4:
if (signed) {
res = this.dataview.getInt32(this.position);
} else {
res = this.dataview.getUint32(this.position);
}
break;
case 8:
if (signed) {
throw "No method for reading signed 64 bits values";
} else {
res = this.dataview.getUint32(this.position) << 32;
res |= this.dataview.getUint32(this.position + 4);
}
break;
default:
throw "readInt method not implemented for size: " + size;
}
this.position += size;
return res;
} else {
throw "Not enough bytes in buffer";
}
};
MP4BoxStream.prototype.readUint8 = function() {
return this.readAnyInt(1, false);
};
MP4BoxStream.prototype.readUint16 = function() {
return this.readAnyInt(2, false);
};
MP4BoxStream.prototype.readUint24 = function() {
return this.readAnyInt(3, false);
};
MP4BoxStream.prototype.readUint32 = function() {
return this.readAnyInt(4, false);
};
MP4BoxStream.prototype.readUint64 = function() {
return this.readAnyInt(8, false);
};
MP4BoxStream.prototype.readString = function(length) {
if (this.position + length <= this.buffer.byteLength) {
var s = "";
for (var i2 = 0; i2 < length; i2++) {
s += String.fromCharCode(this.readUint8());
}
return s;
} else {
throw "Not enough bytes in buffer";
}
};
MP4BoxStream.prototype.readCString = function() {
var arr = [];
while (true) {
var b = this.readUint8();
if (b !== 0) {
arr.push(b);
} else {
break;
}
}
return String.fromCharCode.apply(null, arr);
};
MP4BoxStream.prototype.readInt8 = function() {
return this.readAnyInt(1, true);
};
MP4BoxStream.prototype.readInt16 = function() {
return this.readAnyInt(2, true);
};
MP4BoxStream.prototype.readInt32 = function() {
return this.readAnyInt(4, true);
};
MP4BoxStream.prototype.readInt64 = function() {
return this.readAnyInt(8, false);
};
MP4BoxStream.prototype.readUint8Array = function(length) {
var arr = new Uint8Array(length);
for (var i2 = 0; i2 < length; i2++) {
arr[i2] = this.readUint8();
}
return arr;
};
MP4BoxStream.prototype.readInt16Array = function(length) {
var arr = new Int16Array(length);
for (var i2 = 0; i2 < length; i2++) {
arr[i2] = this.readInt16();
}
return arr;
};
MP4BoxStream.prototype.readUint16Array = function(length) {
var arr = new Int16Array(length);
for (var i2 = 0; i2 < length; i2++) {
arr[i2] = this.readUint16();
}
return arr;
};
MP4BoxStream.prototype.readUint32Array = function(length) {
var arr = new Uint32Array(length);
for (var i2 = 0; i2 < length; i2++) {
arr[i2] = this.readUint32();
}
return arr;
};
MP4BoxStream.prototype.readInt32Array = function(length) {
var arr = new Int32Array(length);
for (var i2 = 0; i2 < length; i2++) {
arr[i2] = this.readInt32();
}
return arr;
};
{
exports.MP4BoxStream = MP4BoxStream;
}
var DataStream = function(arrayBuffer, byteOffset, endianness) {
this._byteOffset = byteOffset || 0;
if (arrayBuffer instanceof ArrayBuffer) {
this.buffer = arrayBuffer;
} else if (typeof arrayBuffer == "object") {
this.dataView = arrayBuffer;
if (byteOffset) {
this._byteOffset += byteOffset;
}
} else {
this.buffer = new ArrayBuffer(arrayBuffer || 0);
}
this.position = 0;
this.endianness = endianness == null ? DataStream.LITTLE_ENDIAN : endianness;
};
DataStream.prototype = {};
DataStream.prototype.getPosition = function() {
return this.position;
};
DataStream.prototype._realloc = function(extra) {
if (!this._dynamicSize) {
return;
}
var req = this._byteOffset + this.position + extra;
var blen = this._buffer.byteLength;
if (req <= blen) {
if (req > this._byteLength) {
this._byteLength = req;
}
return;
}
if (blen < 1) {
blen = 1;
}
while (req > blen) {
blen *= 2;
}
var buf = new ArrayBuffer(blen);
var src = new Uint8Array(this._buffer);
var dst = new Uint8Array(buf, 0, src.length);
dst.set(src);
this.buffer = buf;
this._byteLength = req;
};
DataStream.prototype._trimAlloc = function() {
if (this._byteLength == this._buffer.byteLength) {
return;
}
var buf = new ArrayBuffer(this._byteLength);
var dst = new Uint8Array(buf);
var src = new Uint8Array(this._buffer, 0, dst.length);
dst.set(src);
this.buffer = buf;
};
DataStream.BIG_ENDIAN = false;
DataStream.LITTLE_ENDIAN = true;
DataStream.prototype._byteLength = 0;
Object.defineProperty(
DataStream.prototype,
"byteLength",
{ get: function() {
return this._byteLength - this._byteOffset;
} }
);
Object.defineProperty(
DataStream.prototype,
"buffer",
{
get: function() {
this._trimAlloc();
return this._buffer;
},
set: function(v) {
this._buffer = v;
this._dataView = new DataView(this._buffer, this._byteOffset);
this._byteLength = this._buffer.byteLength;
}
}
);
Object.defineProperty(
DataStream.prototype,
"byteOffset",
{
get: function() {
return this._byteOffset;
},
set: function(v) {
this._byteOffset = v;
this._dataView = new DataView(this._buffer, this._byteOffset);
this._byteLength = this._buffer.byteLength;
}
}
);
Object.defineProperty(
DataStream.prototype,
"dataView",
{
get: function() {
return this._dataView;
},
set: function(v) {
this._byteOffset = v.byteOffset;
this._buffer = v.buffer;
this._dataView = new DataView(this._buffer, this._byteOffset);
this._byteLength = this._byteOffset + v.byteLength;
}
}
);
DataStream.prototype.seek = function(pos) {
var npos = Math.max(0, Math.min(this.byteLength, pos));
this.position = isNaN(npos) || !isFinite(npos) ? 0 : npos;
};
DataStream.prototype.isEof = function() {
return this.position >= this._byteLength;
};
DataStream.prototype.mapUint8Array = function(length) {
this._realloc(length * 1);
var arr = new Uint8Array(this._buffer, this.byteOffset + this.position, length);
this.position += length * 1;
return arr;
};
DataStream.prototype.readInt32Array = function(length, e) {
length = length == null ? this.byteLength - this.position / 4 : length;
var arr = new Int32Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readInt16Array = function(length, e) {
length = length == null ? this.byteLength - this.position / 2 : length;
var arr = new Int16Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readInt8Array = function(length) {
length = length == null ? this.byteLength - this.position : length;
var arr = new Int8Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readUint32Array = function(length, e) {
length = length == null ? this.byteLength - this.position / 4 : length;
var arr = new Uint32Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readUint16Array = function(length, e) {
length = length == null ? this.byteLength - this.position / 2 : length;
var arr = new Uint16Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readUint8Array = function(length) {
length = length == null ? this.byteLength - this.position : length;
var arr = new Uint8Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readFloat64Array = function(length, e) {
length = length == null ? this.byteLength - this.position / 8 : length;
var arr = new Float64Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readFloat32Array = function(length, e) {
length = length == null ? this.byteLength - this.position / 4 : length;
var arr = new Float32Array(length);
DataStream.memcpy(
arr.buffer,
0,
this.buffer,
this.byteOffset + this.position,
length * arr.BYTES_PER_ELEMENT
);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += arr.byteLength;
return arr;
};
DataStream.prototype.readInt32 = function(e) {
var v = this._dataView.getInt32(this.position, e == null ? this.endianness : e);
this.position += 4;
return v;
};
DataStream.prototype.readInt16 = function(e) {
var v = this._dataView.getInt16(this.position, e == null ? this.endianness : e);
this.position += 2;
return v;
};
DataStream.prototype.readInt8 = function() {
var v = this._dataView.getInt8(this.position);
this.position += 1;
return v;
};
DataStream.prototype.readUint32 = function(e) {
var v = this._dataView.getUint32(this.position, e == null ? this.endianness : e);
this.position += 4;
return v;
};
DataStream.prototype.readUint16 = function(e) {
var v = this._dataView.getUint16(this.position, e == null ? this.endianness : e);
this.position += 2;
return v;
};
DataStream.prototype.readUint8 = function() {
var v = this._dataView.getUint8(this.position);
this.position += 1;
return v;
};
DataStream.prototype.readFloat32 = function(e) {
var v = this._dataView.getFloat32(this.position, e == null ? this.endianness : e);
this.position += 4;
return v;
};
DataStream.prototype.readFloat64 = function(e) {
var v = this._dataView.getFloat64(this.position, e == null ? this.endianness : e);
this.position += 8;
return v;
};
DataStream.endianness = new Int8Array(new Int16Array([1]).buffer)[0] > 0;
DataStream.memcpy = function(dst, dstOffset, src, srcOffset, byteLength) {
var dstU8 = new Uint8Array(dst, dstOffset, byteLength);
var srcU8 = new Uint8Array(src, srcOffset, byteLength);
dstU8.set(srcU8);
};
DataStream.arrayToNative = function(array, arrayIsLittleEndian) {
if (arrayIsLittleEndian == this.endianness) {
return array;
} else {
return this.flipArrayEndianness(array);
}
};
DataStream.nativeToEndian = function(array, littleEndian) {
if (this.endianness == littleEndian) {
return array;
} else {
return this.flipArrayEndianness(array);
}
};
DataStream.flipArrayEndianness = function(array) {
var u8 = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
for (var i2 = 0; i2 < array.byteLength; i2 += array.BYTES_PER_ELEMENT) {
for (var j = i2 + array.BYTES_PER_ELEMENT - 1, k = i2; j > k; j--, k++) {
var tmp = u8[k];
u8[k] = u8[j];
u8[j] = tmp;
}
}
return array;
};
DataStream.prototype.failurePosition = 0;
String.fromCharCodeUint8 = function(uint8arr) {
var arr = [];
for (var i2 = 0; i2 < uint8arr.length; i2++) {
arr[i2] = uint8arr[i2];
}
return String.fromCharCode.apply(null, arr);
};
DataStream.prototype.readString = function(length, encoding) {
if (encoding == null || encoding == "ASCII") {
return String.fromCharCodeUint8.apply(null, [this.mapUint8Array(length == null ? this.byteLength - this.position : length)]);
} else {
return new TextDecoder(encoding).decode(this.mapUint8Array(length));
}
};
DataStream.prototype.readCString = function(length) {
var blen = this.byteLength - this.position;
var u8 = new Uint8Array(this._buffer, this._byteOffset + this.position);
var len = blen;
if (length != null) {
len = Math.min(length, blen);
}
for (var i2 = 0; i2 < len && u8[i2] !== 0; i2++) ;
var s = String.fromCharCodeUint8.apply(null, [this.mapUint8Array(i2)]);
if (length != null) {
this.position += len - i2;
} else if (i2 != blen) {
this.position += 1;
}
return s;
};
var MAX_SIZE = Math.pow(2, 32);
DataStream.prototype.readInt64 = function() {
return this.readInt32() * MAX_SIZE + this.readUint32();
};
DataStream.prototype.readUint64 = function() {
return this.readUint32() * MAX_SIZE + this.readUint32();
};
DataStream.prototype.readInt64 = function() {
return this.readUint32() * MAX_SIZE + this.readUint32();
};
DataStream.prototype.readUint24 = function() {
return (this.readUint8() << 16) + (this.readUint8() << 8) + this.readUint8();
};
{
exports.DataStream = DataStream;
}
DataStream.prototype.save = function(filename) {
var blob = new Blob([this.buffer]);
if (window.URL && URL.createObjectURL) {
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
document.body.appendChild(a);
a.setAttribute("href", url);
a.setAttribute("download", filename);
a.setAttribute("target", "_self");
a.click();
window.URL.revokeObjectURL(url);
} else {
throw "DataStream.save: Can't create object URL.";
}
};
DataStream.prototype._dynamicSize = true;
Object.defineProperty(
DataStream.prototype,
"dynamicSize",
{
get: function() {
return this._dynamicSize;
},
set: function(v) {
if (!v) {
this._trimAlloc();
}
this._dynamicSize = v;
}
}
);
DataStream.prototype.shift = function(offset) {
var buf = new ArrayBuffer(this._byteLength - offset);
var dst = new Uint8Array(buf);
var src = new Uint8Array(this._buffer, offset, dst.length);
dst.set(src);
this.buffer = buf;
this.position -= offset;
};
DataStream.prototype.writeInt32Array = function(arr, e) {
this._realloc(arr.length * 4);
if (arr instanceof Int32Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapInt32Array(arr.length, e);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeInt32(arr[i2], e);
}
}
};
DataStream.prototype.writeInt16Array = function(arr, e) {
this._realloc(arr.length * 2);
if (arr instanceof Int16Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapInt16Array(arr.length, e);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeInt16(arr[i2], e);
}
}
};
DataStream.prototype.writeInt8Array = function(arr) {
this._realloc(arr.length * 1);
if (arr instanceof Int8Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapInt8Array(arr.length);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeInt8(arr[i2]);
}
}
};
DataStream.prototype.writeUint32Array = function(arr, e) {
this._realloc(arr.length * 4);
if (arr instanceof Uint32Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapUint32Array(arr.length, e);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeUint32(arr[i2], e);
}
}
};
DataStream.prototype.writeUint16Array = function(arr, e) {
this._realloc(arr.length * 2);
if (arr instanceof Uint16Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapUint16Array(arr.length, e);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeUint16(arr[i2], e);
}
}
};
DataStream.prototype.writeUint8Array = function(arr) {
this._realloc(arr.length * 1);
if (arr instanceof Uint8Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapUint8Array(arr.length);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeUint8(arr[i2]);
}
}
};
DataStream.prototype.writeFloat64Array = function(arr, e) {
this._realloc(arr.length * 8);
if (arr instanceof Float64Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapFloat64Array(arr.length, e);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeFloat64(arr[i2], e);
}
}
};
DataStream.prototype.writeFloat32Array = function(arr, e) {
this._realloc(arr.length * 4);
if (arr instanceof Float32Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
DataStream.memcpy(
this._buffer,
this.byteOffset + this.position,
arr.buffer,
0,
arr.byteLength
);
this.mapFloat32Array(arr.length, e);
} else {
for (var i2 = 0; i2 < arr.length; i2++) {
this.writeFloat32(arr[i2], e);
}
}
};
DataStream.prototype.writeInt32 = function(v, e) {
this._realloc(4);
this._dataView.setInt32(this.position, v, e == null ? this.endianness : e);
this.position += 4;
};
DataStream.prototype.writeInt16 = function(v, e) {
this._realloc(2);
this._dataView.setInt16(this.position, v, e == null ? this.endianness : e);
this.position += 2;
};
DataStream.prototype.writeInt8 = function(v) {
this._realloc(1);
this._dataView.setInt8(this.position, v);
this.position += 1;
};
DataStream.prototype.writeUint32 = function(v, e) {
this._realloc(4);
this._dataView.setUint32(this.position, v, e == null ? this.endianness : e);
this.position += 4;
};
DataStream.prototype.writeUint16 = function(v, e) {
this._realloc(2);
this._dataView.setUint16(this.position, v, e == null ? this.endianness : e);
this.position += 2;
};
DataStream.prototype.writeUint8 = function(v) {
this._realloc(1);
this._dataView.setUint8(this.position, v);
this.position += 1;
};
DataStream.prototype.writeFloat32 = function(v, e) {
this._realloc(4);
this._dataView.setFloat32(this.position, v, e == null ? this.endianness : e);
this.position += 4;
};
DataStream.prototype.writeFloat64 = function(v, e) {
this._realloc(8);
this._dataView.setFloat64(this.position, v, e == null ? this.endianness : e);
this.position += 8;
};
DataStream.prototype.writeUCS2String = function(str, endianness, lengthOverride) {
if (lengthOverride == null) {
lengthOverride = str.length;
}
for (var i2 = 0; i2 < str.length && i2 < lengthOverride; i2++) {
this.writeUint16(str.charCodeAt(i2), endianness);
}
for (; i2 < lengthOverride; i2++) {
this.writeUint16(0);
}
};
DataStream.prototype.writeString = function(s, encoding, length) {
var i2 = 0;
if (encoding == null || encoding == "ASCII") {
if (length != null) {
var len = Math.min(s.length, length);
for (i2 = 0; i2 < len; i2++) {
this.writeUint8(s.charCodeAt(i2));
}
for (; i2 < length; i2++) {
this.writeUint8(0);
}
} else {
for (i2 = 0; i2 < s.length; i2++) {
this.writeUint8(s.charCodeAt(i2));
}
}
} else {
this.writeUint8Array(new TextEncoder(encoding).encode(s.substring(0, length)));
}
};
DataStream.prototype.writeCString = function(s, length) {
var i2 = 0;
if (length != null) {
var len = Math.min(s.length, length);
for (i2 = 0; i2 < len; i2++) {
this.writeUint8(s.charCodeAt(i2));
}
for (; i2 < length; i2++) {
this.writeUint8(0);
}
} else {
for (i2 = 0; i2 < s.length; i2++) {
this.writeUint8(s.charCodeAt(i2));
}
this.writeUint8(0);
}
};
DataStream.prototype.writeStruct = function(structDefinition, struct) {
for (var i2 = 0; i2 < structDefinition.length; i2 += 2) {
var t = structDefinition[i2 + 1];
this.writeType(t, struct[structDefinition[i2]], struct);
}
};
DataStream.prototype.writeType = function(t, v, struct) {
var tp;
if (typeof t == "function") {
return t(this, v);
} else if (typeof t == "object" && !(t instanceof Array)) {
return t.set(this, v, struct);
}
var lengthOverride = null;
var charset = "ASCII";
var pos = this.position;
if (typeof t == "string" && /:/.test(t)) {
tp = t.split(":");
t = tp[0];
lengthOverride = parseInt(tp[1]);
}
if (typeof t == "string" && /,/.test(t)) {
tp = t.split(",");
t = tp[0];
charset = parseInt(tp[1]);
}
switch (t) {
case "uint8":
this.writeUint8(v);
break;
case "int8":
this.writeInt8(v);
break;
case "uint16":
this.writeUint16(v, this.endianness);
break;
case "int16":
this.writeInt16(v, this.endianness);
break;
case "uint32":
this.writeUint32(v, this.endianness);
break;
case "int32":
this.writeInt32(v, this.endianness);
break;
case "float32":
this.writeFloat32(v, this.endianness);
break;
case "float64":
this.writeFloat64(v, this.endianness);
break;
case "uint16be":
this.writeUint16(v, DataStream.BIG_ENDIAN);
break;
case "int16be":
this.writeInt16(v, DataStream.BIG_ENDIAN);
break;
case "uint32be":
this.writeUint32(v, DataStream.BIG_ENDIAN);
break;
case "int32be":
this.writeInt32(v, DataStream.BIG_ENDIAN);
break;
case "float32be":
this.writeFloat32(v, DataStream.BIG_ENDIAN);
break;
case "float64be":
this.writeFloat64(v, DataStream.BIG_ENDIAN);
break;
case "uint16le":
this.writeUint16(v, DataStream.LITTLE_ENDIAN);
break;
case "int16le":
this.writeInt16(v, DataStream.LITTLE_ENDIAN);
break;
case "uint32le":
this.writeUint32(v, DataStream.LITTLE_ENDIAN);
break;
case "int32le":
this.writeInt32(v, DataStream.LITTLE_ENDIAN);
break;
case "float32le":
this.writeFloat32(v, DataStream.LITTLE_ENDIAN);
break;
case "float64le":
this.writeFloat64(v, DataStream.LITTLE_ENDIAN);
break;
case "cstring":
this.writeCString(v, lengthOverride);
break;
case "string":
this.writeString(v, charset, lengthOverride);
break;
case "u16string":
this.writeUCS2String(v, this.endianness, lengthOverride);
break;
case "u16stringle":
this.writeUCS2String(v, DataStream.LITTLE_ENDIAN, lengthOverride);
break;
case "u16stringbe":
this.writeUCS2String(v, DataStream.BIG_ENDIAN, lengthOverride);
break;
default:
if (t.length == 3) {
var ta = t[1];
for (var i2 = 0; i2 < v.length; i2++) {
this.writeType(ta, v[i2]);
}
break;
} else {
this.writeStruct(t, v);
break;
}
}
if (lengthOverride != null) {
this.position = pos;
this._realloc(lengthOverride);
this.position = pos + lengthOverride;
}
};
DataStream.prototype.writeUint64 = function(v) {
var h = Math.floor(v / MAX_SIZE);
this.writeUint32(h);
this.writeUint32(v & 4294967295);
};
DataStream.prototype.writeUint24 = function(v) {
this.writeUint8((v & 16711680) >> 16);
this.writeUint8((v & 65280) >> 8);
this.writeUint8(v & 255);
};
DataStream.prototype.adjustUint32 = function(position, value) {
var pos = this.position;
this.seek(position);
this.writeUint32(value);
this.seek(pos);
};
DataStream.prototype.mapInt32Array = function(length, e) {
this._realloc(length * 4);
var arr = new Int32Array(this._buffer, this.byteOffset + this.position, length);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += length * 4;
return arr;
};
DataStream.prototype.mapInt16Array = function(length, e) {
this._realloc(length * 2);
var arr = new Int16Array(this._buffer, this.byteOffset + this.position, length);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += length * 2;
return arr;
};
DataStream.prototype.mapInt8Array = function(length) {
this._realloc(length * 1);
var arr = new Int8Array(this._buffer, this.byteOffset + this.position, length);
this.position += length * 1;
return arr;
};
DataStream.prototype.mapUint32Array = function(length, e) {
this._realloc(length * 4);
var arr = new Uint32Array(this._buffer, this.byteOffset + this.position, length);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += length * 4;
return arr;
};
DataStream.prototype.mapUint16Array = function(length, e) {
this._realloc(length * 2);
var arr = new Uint16Array(this._buffer, this.byteOffset + this.position, length);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += length * 2;
return arr;
};
DataStream.prototype.mapFloat64Array = function(length, e) {
this._realloc(length * 8);
var arr = new Float64Array(this._buffer, this.byteOffset + this.position, length);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += length * 8;
return arr;
};
DataStream.prototype.mapFloat32Array = function(length, e) {
this._realloc(length * 4);
var arr = new Float32Array(this._buffer, this.byteOffset + this.position, length);
DataStream.arrayToNative(arr, e == null ? this.endianness : e);
this.position += length * 4;
return arr;
};
var MultiBufferStream = function(buffer) {
this.buffers = [];
this.bufferIndex = -1;
if (buffer) {
this.insertBuffer(buffer);
this.bufferIndex = 0;
}
};
MultiBufferStream.prototype = new DataStream(new ArrayBuffer(), 0, DataStream.BIG_ENDIAN);
MultiBufferStream.prototype.initialized = function() {
var firstBuffer;
if (this.bufferIndex > -1) {
return true;
} else if (this.buffers.length > 0) {
firstBuffer = this.buffers[0];
if (firstBuffer.fileStart === 0) {
this.buffer = firstBuffer;
this.bufferIndex = 0;
Log.debug("MultiBufferStream", "Stream ready for parsing");
return true;
} else {
Log.warn("MultiBufferStream", "The first buffer should have a fileStart of 0");
this.logBufferLevel();
return false;
}
} else {
Log.warn("MultiBufferStream", "No buffer to start parsing from");
this.logBufferLevel();
return false;
}
};
ArrayBuffer.concat = function(buffer1, buffer2) {
Log.debug("ArrayBuffer", "Trying to create a new buffer of size: " + (buffer1.byteLength + buffer2.byteLength));
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(new Uint8Array(buffer1), 0);
tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
return tmp.buffer;
};
MultiBufferStream.prototype.reduceBuffer = function(buffer, offset, newLength) {
var smallB;
smallB = new Uint8Array(newLength);
smallB.set(new Uint8Array(buffer, offset, newLength));
smallB.buffer.fileStart = buffer.fileStart + offset;
smallB.buffer.usedBytes = 0;
return smallB.buffer;
};
MultiBufferStream.prototype.insertBuffer = function(ab) {
var to_add = true;
for (var i2 = 0; i2 < this.buffers.length; i2++) {
var b = this.buffers[i2];
if (ab.fileStart <= b.fileStart) {
if (ab.fileStart === b.fileStart) {
if (ab.byteLength > b.byteLength) {
this.buffers.splice(i2, 1);
i2--;
continue;
} else {
Log.warn("MultiBufferStream", "Buffer (fileStart: " + ab.fileStart + " - Length: " + ab.byteLength + ") already appended, ignoring");
}
} else {
if (ab.fileStart + ab.byteLength <= b.fileStart) ;
else {
ab = this.reduceBuffer(ab, 0, b.fileStart - ab.fileStart);
}
Log.debug("MultiBufferStream", "Appending new buffer (fileStart: " + ab.fileStart + " - Length: " + ab.byteLength + ")");
this.buffers.splice(i2, 0, ab);
if (i2 === 0) {
this.buffer = ab;
}
}
to_add = false;
break;
} else if (ab.fileStart < b.fileStart + b.byteLength) {
var offset = b.fileStart + b.byteLength - ab.fileStart;
var newLength = ab.byteLength - offset;
if (newLength > 0) {
ab = this.reduceBuffer(ab, offset, newLength);
} else {
to_add = false;
break;
}
}
}
if (to_add) {
Log.debug("MultiBufferStream", "Appending new buffer (fileStart: " + ab.fileStart + " - Length: " + ab.byteLength + ")");
this.buffers.push(ab);
if (i2 === 0) {
this.buffer = ab;
}
}
};
MultiBufferStream.prototype.logBufferLevel = function(info) {
var i2;
var buffer;
var used, total;
var ranges = [];
var range;
var bufferedString = "";
used = 0;
total = 0;
for (i2 = 0; i2 < this.buffers.length; i2++) {
buffer = this.buffers[i2];
if (i2 === 0) {
range = {};
ranges.push(range);
range.start = buffer.fileStart;
range.end = buffer.fileStart + buffer.byteLength;
bufferedString += "[" + range.start + "-";
} else if (range.end === buffer.fileStart) {
range.end = buffer.fileStart + buffer.byteLength;
} else {
range = {};
range.start = buffer.fileStart;
bufferedString += ranges[ranges.length - 1].end - 1 + "], [" + range.start + "-";
range.end = buffer.fileStart + buffer.byteLength;
ranges.push(range);
}
used += buffer.usedBytes;
total += buffer.byteLength;
}
if (ranges.length > 0) {
bufferedString += range.end - 1 + "]";
}
var log = info ? Log.info : Log.debug;
if (this.buffers.length === 0) {
log("MultiBufferStream", "No more buffer in memory");
} else {
log("MultiBufferStream", "" + this.buffers.length + " stored buffer(s) (" + used + "/" + total + " bytes), continuous ranges: " + bufferedString);
}
};
MultiBufferStream.prototype.cleanBuffers = function() {
var i2;
var buffer;
for (i2 = 0; i2 < this.buffers.length; i2++) {
buffer = this.buffers[i2];
if (buffer.usedBytes === buffer.byteLength) {
Log.debug("MultiBufferStream", "Removing buffer #" + i2);
this.buffers.splice(i2, 1);
i2--;
}
}
};
MultiBufferStream.prototype.mergeNextBuffer = function() {
var next_buffer;
if (this.bufferIndex + 1 < this.buffers.length) {
next_buffer = this.buffers[this.bufferIndex + 1];
if (next_buffer.fileStart === this.buffer.fileStart + this.buffer.byteLength) {
var oldLength = this.buffer.byteLength;
var oldUsedBytes = this.buffer.usedBytes;
var oldFileStart = this.buffer.fileStart;
this.buffers[this.bufferIndex] = ArrayBuffer.concat(this.buffer, next_buffer);
this.buffer = this.buffers[this.bufferIndex];
this.buffers.splice(this.bufferIndex + 1, 1);
this.buffer.usedBytes = oldUsedBytes;
this.buffer.fileStart = oldFileStart;
Log.debug("ISOFile", "Concatenating buffer for box parsing (length: " + oldLength + "->" + this.buffer.byteLength + ")");
return true;
} else {
return false;
}
} else {
return false;
}
};
MultiBufferStream.prototype.findPosition = function(fromStart, filePosition, markAsUsed) {
var i2;
var abuffer = null;
var index = -1;
if (fromStart === true) {
i2 = 0;
} else {
i2 = this.bufferIndex;
}
while (i2 < this.buffers.length) {
abuffer = this.buffers[i2];
if (abuffer.fileStart <= filePosition) {
index = i2;
if (markAsUsed) {
if (abuffer.fileStart + abuffer.byteLength <= filePosition) {
abuffer.usedBytes = abuffer.byteLength;
} else {
abuffer.usedBytes = filePosition - abuffer.fileStart;
}
this.logBufferLevel();
}
} else {
break;
}
i2++;
}
if (index !== -1) {
abuffer = this.buffers[index];
if (abuffer.fileStart + abuffer.byteLength >= filePosition) {
Log.debug("MultiBufferStream", "Found position in existing buffer #" + index);
return index;
} else {
return -1;
}
} else {
return -1;
}
};
MultiBufferStream.prototype.findEndContiguousBuf = function(inputindex) {
var i2;
var currentBuf;
var nextBuf;
var index = inputindex !== void 0 ? inputindex : this.bufferIndex;
currentBuf = this.buffers[index];
if (this.buffers.length > index + 1) {
for (i2 = index + 1; i2 < this.buffers.length; i2++) {
nextBuf = this.buffers[i2];
if (nextBuf.fileStart === currentBuf.fileStart + currentBuf.byteLength) {
currentBuf = nextBuf;
} else {
break;
}
}
}
return currentBuf.fileStart + currentBuf.byteLength;
};
MultiBufferStream.prototype.getEndFilePositionAfter = function(pos) {
var index = this.findPosition(true, pos, false);
if (index !== -1) {
return this.findEndContiguousBuf(index);
} else {
return pos;
}
};
MultiBufferStream.prototype.addUsedBytes = function(nbBytes) {
this.buffer.usedBytes += nbBytes;
this.logBufferLevel();
};
MultiBufferStream.prototype.setAllUsedBytes = function() {
this.buffer.usedBytes = this.buffer.byteLength;
this.logBufferLevel();
};
MultiBufferStream.prototype.seek = function(filePosition, fromStart, markAsUsed) {
var index;
index = this.findPosition(fromStart, filePosition, markAsUsed);
if (index !== -1) {
this.buffer = this.buffers[index];
this.bufferIndex = index;
this.position = filePosition - this.buffer.fileStart;
Log.debug("MultiBufferStream", "Repositioning parser at buffer position: " + this.position);
return true;
} else {
Log.debug("MultiBufferStream", "Position " + filePosition + " not found in buffered data");
return false;
}
};
MultiBufferStream.prototype.getPosition = function() {
if (this.bufferIndex === -1 || this.buffers[this.bufferIndex] === null) {
throw "Error accessing position in the MultiBufferStream";
}
return this.buffers[this.bufferIndex].fileStart + this.position;
};
MultiBufferStream.prototype.getLength = function() {
return this.byteLength;
};
MultiBufferStream.prototype.getEndPosition = function() {
if (this.bufferIndex === -1 || this.buffers[this.bufferIndex] === null) {
throw "Error accessing position in the MultiBufferStream";
}
return this.buffers[this.bufferIndex].fileStart + this.byteLength;
};
{
exports.MultiBufferStream = MultiBufferStream;
}
var MPEG4DescriptorParser = function() {
var ES_DescrTag = 3;
var DecoderConfigDescrTag = 4;
var DecSpecificInfoTag = 5;
var SLConfigDescrTag = 6;
var descTagToName = [];
descTagToName[ES_DescrTag] = "ES_Descriptor";
descTagToName[DecoderConfigDescrTag] = "DecoderConfigDescriptor";
descTagToName[DecSpecificInfoTag] = "DecoderSpecificInfo";
descTagToName[SLConfigDescrTag] = "SLConfigDescriptor";
this.getDescriptorName = function(tag) {
return descTagToName[tag];
};
var that = this;
var classes = {};
this.parseOneDescriptor = function(stream) {
var size = 0;
var tag;
var desc;
var byteRead;
tag = stream.readUint8();
byteRead = stream.readUint8();
while (byteRead & 128) {
size = (size << 7) + (byteRead & 127);
byteRead = stream.readUint8();
}
size = (size << 7) + (byteRead & 127);
Log.debug("MPEG4DescriptorParser", "Found " + (descTagToName[tag] || "Descriptor " + tag) + ", size " + size + " at position " + stream.getPosition());
if (descTagToName[tag]) {
desc = new classes[descTagToName[tag]](size);
} else {
desc = new classes.Descriptor(size);
}
desc.parse(stream);
return desc;
};
classes.Descriptor = function(_tag, _size) {
this.tag = _tag;
this.size = _size;
this.descs = [];
};
classes.Descriptor.prototype.parse = function(stream) {
this.data = stream.readUint8Array(this.size);
};
classes.Descriptor.prototype.findDescriptor = function(tag) {
for (var i2 = 0; i2 < this.descs.length; i2++) {
if (this.descs[i2].tag == tag) {
return this.descs[i2];
}
}
return null;
};
classes.Descriptor.prototype.parseRemainingDescriptors = function(stream) {
var start = stream.position;
while (stream.position < start + this.size) {
var desc = that.parseOneDescriptor(stream);
this.descs.push(desc);
}
};
classes.ES_Descriptor = function(size) {
classes.Descriptor.call(this, ES_DescrTag, size);
};
classes.ES_Descriptor.prototype = new classes.Descriptor();
classes.ES_Descriptor.prototype.parse = function(stream) {
this.ES_ID = stream.readUint16();
this.flags = stream.readUint8();
this.size -= 3;
if (this.flags & 128) {
this.dependsOn_ES_ID = stream.readUint16();
this.size -= 2;
} else {
this.dependsOn_ES_ID = 0;
}
if (this.flags & 64) {
var l = stream.readUint8();
this.URL = stream.readString(l);
this.size -= l + 1;
} else {
this.URL = "";
}
if (this.flags & 32) {
this.OCR_ES_ID = stream.readUint16();
this.size -= 2;
} else {
this.OCR_ES_ID = 0;
}
this.parseRemainingDescriptors(stream);
};
classes.ES_Descriptor.prototype.getOTI = function(stream) {
var dcd = this.findDescriptor(DecoderConfigDescrTag);
if (dcd) {
return dcd.oti;
} else {
return 0;
}
};
classes.ES_Descriptor.prototype.getAudioConfig = function(stream) {
var dcd = this.findDescriptor(DecoderConfigDescrTag);
if (!dcd) return null;
var dsi = dcd.findDescriptor(DecSpecificInfoTag);
if (dsi && dsi.data) {
var audioObjectType = (dsi.data[0] & 248) >> 3;
if (audioObjectType === 31 && dsi.data.length >= 2) {
audioObjectType = 32 + ((dsi.data[0] & 7) << 3) + ((dsi.data[1] & 224) >> 5);
}
return audioObjectType;
} else {
return null;
}
};
classes.DecoderConfigDescriptor = function(size) {
classes.Descriptor.call(this, DecoderConfigDescrTag, size);
};
classes.DecoderConfigDescriptor.prototype = new classes.Descriptor();
classes.DecoderConfigDescriptor.prototype.parse = function(stream) {
this.oti = stream.readUint8();
this.streamType = stream.readUint8();
this.upStream = (this.streamType >> 1 & 1) !== 0;
this.streamType = this.streamType >>> 2;
this.bufferSize = stream.readUint24();
this.maxBitrate = stream.readUint32();
this.avgBitrate = stream.readUint32();
this.size -= 13;
this.parseRemainingDescriptors(stream);
};
classes.DecoderSpecificInfo = function(size) {
classes.Descriptor.call(this, DecSpecificInfoTag, size);
};
classes.DecoderSpecificInfo.prototype = new classes.Descriptor();
classes.SLConfigDescriptor = function(size) {
classes.Descriptor.call(this, SLConfigDescrTag, size);
};
classes.SLConfigDescriptor.prototype = new classes.Descriptor();
return this;
};
{
exports.MPEG4DescriptorParser = MPEG4DescriptorParser;
}
var BoxParser = {
ERR_INVALID_DATA: -1,
ERR_NOT_ENOUGH_DATA: 0,
OK: 1,
// Boxes to be created with default parsing
BASIC_BOXES: [
{ type: "mdat", name: "MediaDataBox" },
{ type: "idat", name: "ItemDataBox" },
{ type: "free", name: "FreeSpaceBox" },
{ type: "skip", name: "FreeSpaceBox" },
{ type: "meco", name: "AdditionalMetadataContainerBox" },
{ type: "strk", name: "SubTrackBox" }
],
FULL_BOXES: [
{ type: "hmhd", name: "HintMediaHeaderBox" },
{ type: "nmhd", name: "NullMediaHeaderBox" },
{ type: "iods", name: "ObjectDescriptorBox" },
{ type: "xml ", name: "XMLBox" },
{ type: "bxml", name: "BinaryXMLBox" },
{ type: "ipro", name: "ItemProtectionBox" },
{ type: "mere", name: "MetaboxRelationBox" }
],
CONTAINER_BOXES: [
[{ type: "moov", name: "CompressedMovieBox" }, ["trak", "pssh"]],
[{ type: "trak", name: "TrackBox" }],
[{ type: "edts", name: "EditBox" }],
[{ type: "mdia", name: "MediaBox" }],
[{ type: "minf", name: "MediaInformationBox" }],
[{ type: "dinf", name: "DataInformationBox" }],
[{ type: "stbl", name: "SampleTableBox" }, ["sgpd", "sbgp"]],
[{ type: "mvex", name: "MovieExtendsBox" }, ["trex"]],
[{ type: "moof", name: "CompressedMovieFragmentBox" }, ["traf"]],
[{ type: "traf", name: "TrackFragmentBox" }, ["trun", "sgpd", "sbgp"]],
[{ type: "vttc", name: "VTTCueBox" }],
[{ type: "tref", name: "TrackReferenceBox" }],
[{ type: "iref", name: "ItemReferenceBox" }],
[{ type: "mfra", name: "MovieFragmentRandomAccessBox" }, ["tfra"]],
[{ type: "meco", name: "AdditionalMetadataContainerBox" }],
[{ type: "hnti", name: "trackhintinformation" }],
[{ type: "hinf", name: "hintstatisticsbox" }],
[{ type: "strk", name: "SubTrackBox" }],
[{ type: "strd", name: "SubTrackDefinitionBox" }],
[{ type: "sinf", name: "ProtectionSchemeInfoBox" }],
[{ type: "rinf", name: "RestrictedSchemeInfoBox" }],
[{ type: "schi", name: "SchemeInformationBox" }],
[{ type: "trgr", name: "TrackGroupBox" }],
[{ type: "udta", name: "UserDataBox" }, ["kind"]],
[{ type: "iprp", name: "ItemPropertiesBox" }, ["ipma"]],
[{ type: "ipco", name: "ItemPropertyContainerBox" }],
[{ type: "grpl", name: "GroupsListBox" }],
[{ type: "j2kH", name: "J2KHeaderInfoBox" }],
[{ type: "etyp", name: "ExtendedTypeBox" }, ["tyco"]]
],
// Boxes effectively created
boxCodes: [],
fullBoxCodes: [],
containerBoxCodes: [],
sampleEntryCodes: {},
sampleGroupEntryCodes: [],
trackGroupTypes: [],
UUIDBoxes: {},
UUIDs: [],