Socket
Socket
Sign inDemoInstall

codem-isoboxer

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

codem-isoboxer - npm Package Compare versions

Comparing version 0.2.10 to 0.3.0

src/processors/avc1,encv.js

9

CHANGELOG.md

@@ -1,5 +0,10 @@

## codem-isoboxer 0.2.10 (2016/12/022) ##
## codem-isoboxer 0.3.0 (2016/12/23) ##
* Updated `subs` parser to follow the spec more closely (@2bert, @TobbeEdgeware)
* write support (@bbert)
* encrypted boxes support (encv,enca,frma,pssh,schm,sdtp,tenc) (@nicosang)
## codem-isoboxer 0.2.10 (2016/12/02) ##
* Updated `subs` parser to follow the spec more closely (@bbert, @TobbeEdgeware)
## codem-isoboxer 0.2.9 (2016/11/29) ##

@@ -6,0 +11,0 @@

@@ -1,2 +0,2 @@

/*! codem-isoboxer v0.2.10 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */
/*! codem-isoboxer v0.3.0 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */
var ISOBoxer = {};

@@ -8,9 +8,30 @@

ISOBoxer.addBoxParser = function(type, parser) {
ISOBoxer.addBoxProcessor = function(type, parser) {
if (typeof type !== 'string' || typeof parser !== 'function') {
return;
}
ISOBox.prototype._boxParsers[type] = parser;
ISOBox.prototype._boxProcessors[type] = parser;
};
ISOBoxer.createFile = function() {
return new ISOFile();
};
// See ISOBoxer.append() for 'pos' parameter syntax
ISOBoxer.createBox = function(type, parent, pos) {
var newBox = ISOBox.create(type);
if (parent) {
parent.append(newBox, pos);
}
return newBox;
};
// See ISOBoxer.append() for 'pos' parameter syntax
ISOBoxer.createFullBox = function(type, parent, pos) {
var newBox = ISOBoxer.createBox(type, parent, pos);
newBox.version = 0;
newBox.flags = 0;
return newBox;
};
ISOBoxer.Utils = {};

@@ -60,14 +81,97 @@ ISOBoxer.Utils.dataViewToString = function(dataView, encoding) {

ISOBoxer.Utils.utf8ToByteArray = function(string) {
// Only UTF-8 encoding is supported by TextEncoder
var u, i;
if (typeof TextEncoder !== 'undefined') {
u = new TextEncoder().encode(string);
} else {
u = [];
for (i = 0; i < string.length; ++i) {
var c = string.charCodeAt(i);
if (c < 0x80) {
u.push(c);
} else if (c < 0x800) {
u.push(0xC0 | (c >> 6));
u.push(0x80 | (63 & c));
} else if (c < 0x10000) {
u.push(0xE0 | (c >> 12));
u.push(0x80 | (63 & (c >> 6)));
u.push(0x80 | (63 & c));
} else {
u.push(0xF0 | (c >> 18));
u.push(0x80 | (63 & (c >> 12)));
u.push(0x80 | (63 & (c >> 6)));
u.push(0x80 | (63 & c));
}
}
}
return u;
};
// Method to append a box in the list of child boxes
// The 'pos' parameter can be either:
// - (number) a position index at which to insert the new box
// - (string) the type of the box after which to insert the new box
// - (object) the box after which to insert the new box
ISOBoxer.Utils.appendBox = function(parent, box, pos) {
box._offset = parent._cursor.offset;
box._root = (parent._root ? parent._root : parent);
box._raw = parent._raw;
box._parent = parent;
if (pos === -1) {
// The new box is a sub-box of the parent but not added in boxes array,
// for example when the new box is set as an entry (see dref and stsd for example)
return;
}
if (pos === undefined || pos === null) {
parent.boxes.push(box);
return;
}
var index = -1,
type;
if (typeof pos === "number") {
index = pos;
} else {
if (typeof pos === "string") {
type = pos;
} else if (typeof pos === "object" && pos.type) {
type = pos.type;
} else {
parent.boxes.push(box);
return;
}
for (var i = 0; i < parent.boxes.length; i++) {
if (type === parent.boxes[i].type) {
index = i + 1;
break;
}
}
}
parent.boxes.splice(index, 0, box);
};
if (typeof exports !== 'undefined') {
exports.parseBuffer = ISOBoxer.parseBuffer;
exports.addBoxParser = ISOBoxer.addBoxParser;
exports.Utils = ISOBoxer.Utils;
exports.parseBuffer = ISOBoxer.parseBuffer;
exports.addBoxProcessor = ISOBoxer.addBoxProcessor;
exports.createFile = ISOBoxer.createFile;
exports.createBox = ISOBoxer.createBox;
exports.createFullBox = ISOBoxer.createFullBox;
exports.Utils = ISOBoxer.Utils;
}
ISOBoxer.Cursor = function(initialOffset) {
this.offset = (typeof initialOffset == 'undefined' ? 0 : initialOffset);
};
var ISOFile = function(arrayBuffer) {
this._raw = new DataView(arrayBuffer);
this._cursor = new ISOBoxer.Cursor();
this.boxes = [];
if (arrayBuffer) {
this._raw = new DataView(arrayBuffer);
}
};

@@ -107,2 +211,50 @@

};
ISOFile.prototype.write = function() {
var length = 0,
i;
for (i = 0; i < this.boxes.length; i++) {
length += this.boxes[i].getLength(false);
}
var bytes = new Uint8Array(length);
this._rawo = new DataView(bytes.buffer);
this.bytes = bytes;
this._cursor.offset = 0;
for (i = 0; i < this.boxes.length; i++) {
this.boxes[i].write();
}
return bytes.buffer;
};
ISOFile.prototype.append = function(box, pos) {
ISOBoxer.Utils.appendBox(this, box, pos);
};
/*ISOFile.prototype.create = function(type, parent, previousType) {
var newBox = ISOBox.create(type, parent),
inserted = false;
if (previousType) {
for (var i = 0; i < parent.boxes.length; i++) {
if (previousType === parent.boxes[i].type) {
parent.boxes.splice(i + 1, 0, newBox);
inserted = true;
break;
}
}
}
if (!inserted) {
parent.boxes.push(newBox);
}
return newBox;
};*/
var ISOBox = function() {

@@ -123,13 +275,139 @@ this._cursor = new ISOBoxer.Cursor();

ISOBox.create = function(type) {
var newBox = new ISOBox();
newBox.type = type;
newBox.boxes = [];
return newBox;
};
ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca'];
ISOBox.prototype._boxProcessors = {};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Generic read/write functions
ISOBox.prototype._procField = function (name, type, size) {
if (this._parsing) {
this[name] = this._readField(type, size);
}
else {
this._writeField(type, size, this[name]);
}
};
ISOBox.prototype._procFieldArray = function (name, length, type, size) {
var i;
if (this._parsing) {
this[name] = [];
for (i = 0; i < length; i++) {
this[name][i] = this._readField(type, size);
}
}
else {
for (i = 0; i < this[name].length; i++) {
this._writeField(type, size, this[name][i]);
}
}
};
ISOBox.prototype._procFullBox = function() {
this._procField('version', 'uint', 8);
this._procField('flags', 'uint', 24);
};
ISOBox.prototype._procEntries = function(name, length, fn) {
var i;
if (this._parsing) {
this[name] = [];
for (i = 0; i < length; i++) {
this[name].push({});
fn.call(this, this[name][i]);
}
}
else {
for (i = 0; i < length; i++) {
fn.call(this, this[name][i]);
}
}
};
ISOBox.prototype._procSubEntries = function(entry, name, length, fn) {
var i;
if (this._parsing) {
entry[name] = [];
for (i = 0; i < length; i++) {
entry[name].push({});
fn.call(this, entry[name][i]);
}
}
else {
for (i = 0; i < length; i++) {
fn.call(this, entry[name][i]);
}
}
};
ISOBox.prototype._procEntryField = function (entry, name, type, size) {
if (this._parsing) {
entry[name] = this._readField(type, size);
}
else {
this._writeField(type, size, entry[name]);
}
};
ISOBox.prototype._procSubBoxes = function(name, length) {
var i;
if (this._parsing) {
this[name] = [];
for (i = 0; i < length; i++) {
this[name].push(ISOBox.parse(this));
}
}
else {
for (i = 0; i < length; i++) {
if (this._rawo) {
this[name][i].write();
} else {
this.size += this[name][i].getLength();
}
}
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Read/parse functions
ISOBox.prototype._readField = function(type, size) {
switch (type) {
case 'uint':
return this._readUint(size);
case 'int':
return this._readInt(size);
case 'template':
return this._readTemplate(size);
case 'string':
return (size === -1) ? this._readTerminatedString() : this._readString(size);
case 'data':
return this._readData(size);
case 'utf8':
return this._readUTF8String();
default:
return -1;
}
};
ISOBox.prototype._readInt = function(size) {
var result = null;
var result = null,
offset = this._cursor.offset - this._raw.byteOffset;
switch(size) {
case 8:
result = this._raw.getInt8(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getInt8(offset);
break;
case 16:
result = this._raw.getInt16(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getInt16(offset);
break;
case 32:
result = this._raw.getInt32(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getInt32(offset);
break;

@@ -139,4 +417,4 @@ case 64:

// This will give unexpected results for integers >= 2^53
var s1 = this._raw.getInt32(this._cursor.offset - this._raw.byteOffset);
var s2 = this._raw.getInt32(this._cursor.offset - this._raw.byteOffset + 4);
var s1 = this._raw.getInt32(offset);
var s2 = this._raw.getInt32(offset + 4);
result = (s1 * Math.pow(2,32)) + s2;

@@ -151,17 +429,18 @@ break;

var result = null,
offset = this._cursor.offset - this._raw.byteOffset,
s1, s2;
switch(size) {
case 8:
result = this._raw.getUint8(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getUint8(offset);
break;
case 16:
result = this._raw.getUint16(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getUint16(offset);
break;
case 24:
s1 = this._raw.getUint16(this._cursor.offset - this._raw.byteOffset);
s2 = this._raw.getUint8(this._cursor.offset - this._raw.byteOffset + 2);
s1 = this._raw.getUint16(offset);
s2 = this._raw.getUint8(offset + 2);
result = (s1 << 8) + s2;
break;
case 32:
result = this._raw.getUint32(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getUint32(offset);
break;

@@ -171,4 +450,4 @@ case 64:

// This will give unexpected results for integers >= 2^53
s1 = this._raw.getUint32(this._cursor.offset - this._raw.byteOffset);
s2 = this._raw.getUint32(this._cursor.offset - this._raw.byteOffset + 4);
s1 = this._raw.getUint32(offset);
s2 = this._raw.getUint32(offset + 4);
result = (s1 * Math.pow(2,32)) + s2;

@@ -190,2 +469,8 @@ break;

ISOBox.prototype._readTemplate = function(size) {
var pre = this._readUint(size / 2);
var post = this._readUint(size / 2);
return pre + (post / Math.pow(2, size / 2));
};
ISOBox.prototype._readTerminatedString = function() {

@@ -201,8 +486,2 @@ var str = '';

ISOBox.prototype._readTemplate = function(size) {
var pre = this._readUint(size / 2);
var post = this._readUint(size / 2);
return pre + (post / Math.pow(2, size / 2));
};
ISOBox.prototype._readData = function(size) {

@@ -215,3 +494,9 @@ var length = (size > 0) ? size : (this._raw.byteLength - (this._cursor.offset - this._offset));

ISOBox.prototype._readUTF8String = function() {
var data = this._readData();
return ISOBoxer.Utils.dataViewToString(data);
};
ISOBox.prototype._parseBox = function() {
this._parsing = true;
this._cursor.offset = this._offset;

@@ -225,7 +510,7 @@

this.size = this._readUint(32);
this.type = this._readString(4);
this._procField('size', 'uint', 32);
this._procField('type', 'string', 4);
if (this.size == 1) { this.largesize = this._readUint(64); }
if (this.type == 'uuid') { this.usertype = this._readString(16); }
if (this.size === 1) { this._procField('largesize', 'uint', 64); }
if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); }

@@ -255,6 +540,10 @@ switch(this.size) {

if (!this._incomplete) {
if (this._boxProcessors[this.type]) {
this._boxProcessors[this.type].call(this);
}
if (this._boxContainers.indexOf(this.type) !== -1) {
this._parseContainerBox();
} else if (this._boxParsers[this.type]) {
this._boxParsers[this.type].call(this);
} else{
// Unknown box => read and store box content
this._data = this._readData();
}

@@ -276,456 +565,618 @@ }

ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc'];
///////////////////////////////////////////////////////////////////////////////////////////////////
// Write functions
ISOBox.prototype._boxParsers = {};
ISOBox.prototype.append = function(box, pos) {
ISOBoxer.Utils.appendBox(this, box, pos);
};
ISOBox.prototype.getLength = function() {
this._parsing = false;
this._rawo = null;
this.size = 0;
this._procField('size', 'uint', 32);
this._procField('type', 'string', 4);
if (this.size === 1) { this._procField('largesize', 'uint', 64); }
if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); }
if (this._boxProcessors[this.type]) {
this._boxProcessors[this.type].call(this);
}
if (this._boxContainers.indexOf(this.type) !== -1) {
for (var i = 0; i < this.boxes.length; i++) {
this.size += this.boxes[i].getLength();
}
}
if (this._data) {
this._writeData(this._data);
}
return this.size;
};
ISOBox.prototype.write = function() {
this._parsing = false;
this._cursor.offset = this._parent._cursor.offset;
switch(this.size) {
case 0:
this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, (this.parent._rawo.byteLength - this._cursor.offset));
break;
case 1:
this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.largesize);
break;
default:
this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.size);
}
this._procField('size', 'uint', 32);
this._procField('type', 'string', 4);
if (this.size === 1) { this._procField('largesize', 'uint', 64); }
if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); }
if (this._boxProcessors[this.type]) {
this._boxProcessors[this.type].call(this);
}
if (this._boxContainers.indexOf(this.type) !== -1) {
for (var i = 0; i < this.boxes.length; i++) {
this.boxes[i].write();
}
}
if (this._data) {
this._writeData(this._data);
}
this._parent._cursor.offset += this.size;
return this.size;
};
ISOBox.prototype._writeInt = function(size, value) {
if (this._rawo) {
var offset = this._cursor.offset - this._rawo.byteOffset;
switch(size) {
case 8:
this._rawo.setInt8(offset, value);
break;
case 16:
this._rawo.setInt16(offset, value);
break;
case 32:
this._rawo.setInt32(offset, value);
break;
case 64:
// Warning: JavaScript cannot handle 64-bit integers natively.
// This will give unexpected results for integers >= 2^53
var s1 = Math.round(value / Math.pow(2,32));
var s2 = value - (s1 * Math.pow(2,32));
this._rawo.setUint32(offset, s1);
this._rawo.setUint32(offset + 4, s2);
break;
}
this._cursor.offset += (size >> 3);
} else {
this.size += (size >> 3);
}
};
ISOBox.prototype._writeUint = function(size, value) {
if (this._rawo) {
var offset = this._cursor.offset - this._rawo.byteOffset,
s1, s2;
switch(size) {
case 8:
this._rawo.setUint8(offset, value);
break;
case 16:
this._rawo.setUint16(offset, value);
break;
case 24:
s1 = (value & 0xFFFF00) >> 8;
s2 = (value & 0x0000FF);
this._rawo.setUint16(offset, s1);
this._rawo.setUint8(offset + 2, s2);
break;
case 32:
this._rawo.setUint32(offset, value);
break;
case 64:
// Warning: JavaScript cannot handle 64-bit integers natively.
// This will give unexpected results for integers >= 2^53
s1 = Math.round(value / Math.pow(2,32));
s2 = value - (s1 * Math.pow(2,32));
this._rawo.setUint32(offset, s1);
this._rawo.setUint32(offset + 4, s2);
break;
}
this._cursor.offset += (size >> 3);
} else {
this.size += (size >> 3);
}
};
ISOBox.prototype._writeString = function(size, str) {
for (var c = 0; c < size; c++) {
this._writeUint(8, str.charCodeAt(c));
}
};
ISOBox.prototype._writeTerminatedString = function(str) {
if (str.length === 0) {
return;
}
for (var c = 0; c < str.length; c++) {
this._writeUint(8, str.charCodeAt(c));
}
this._writeUint(8, 0);
};
ISOBox.prototype._writeTemplate = function(size, value) {
var pre = Math.round(value);
var post = (value - pre) * Math.pow(2, size / 2);
this._writeUint(size / 2, pre);
this._writeUint(size / 2, post);
};
ISOBox.prototype._writeData = function(data) {
if (data instanceof Array) {
data = new DataView(Uint8Array.from(data).buffer);
}
if (data instanceof Uint8Array) {
data = new DataView(data.buffer);
}
if (this._rawo) {
var offset = this._cursor.offset - this._rawo.byteOffset;
for (var i = 0; i < data.byteLength; i++) {
this._rawo.setUint8(offset + i, data.getUint8(i));
}
this._cursor.offset += data.byteLength;
} else {
this.size += data.byteLength;
}
};
ISOBox.prototype._writeUTF8String = function(string) {
var u = ISOBoxer.Utils.utf8ToByteArray(string);
if (this._rawo) {
var dataView = new DataView(this._rawo.buffer, this._cursor.offset, u.length);
for (var i = 0; i < u.length; i++) {
dataView.setUint8(i, u[i]);
}
} else {
this.size += u.length;
}
};
ISOBox.prototype._writeField = function(type, size, value) {
switch (type) {
case 'uint':
this._writeUint(size, value);
break;
case 'int':
this._writeInt(size, value);
break;
case 'template':
this._writeTemplate(size, value);
break;
case 'string':
if (size == -1) {
this._writeTerminatedString(value);
} else {
this._writeString(size, value);
}
break;
case 'data':
this._writeData(value);
break;
case 'utf8':
this._writeUTF8String(value);
break;
default:
break;
}
};
// ISO/IEC 14496-15:2014 - avc1 box
ISOBox.prototype._boxParsers['avc1'] = function() {
ISOBox.prototype._boxProcessors['avc1'] = ISOBox.prototype._boxProcessors['encv'] = function() {
// SampleEntry fields
this.reserved1 = [
this._readUint(8),
this._readUint(8),
this._readUint(8),
this._readUint(8),
this._readUint(8),
this._readUint(8)
];
this.data_reference_index = this._readUint(16);
this._procFieldArray('reserved1', 6, 'uint', 8);
this._procField('data_reference_index', 'uint', 16);
// VisualSampleEntry fields
this.pre_defined1 = this._readUint(16);
this.reserved2 = this._readUint(16);
this.pre_defined2 = [
this._readUint(32),
this._readUint(32),
this._readUint(32)
];
this.width = this._readUint(16);
this.height = this._readUint(16);
this.horizresolution = this._readTemplate(32);
this.vertresolution = this._readTemplate(32);
this.reserved3 = this._readUint(32);
this.frame_count = this._readUint(16);
var length = this._readUint(8);
this.compressorname = this._readString(length);
for (var i = 0; i < (31 - length); i++) {
this._readUint(8);
}
this.depth = this._readUint(16);
this.pre_defined3 = this._readInt(16);
this._procField('pre_defined1', 'uint', 16);
this._procField('reserved2', 'uint', 16);
this._procFieldArray('pre_defined2', 3, 'uint', 32);
this._procField('width', 'uint', 16);
this._procField('height', 'uint', 16);
this._procField('horizresolution', 'template', 32);
this._procField('vertresolution', 'template', 32);
this._procField('reserved3', 'uint', 32);
this._procField('frame_count', 'uint', 16);
this._procFieldArray('compressorname', 32,'uint', 8);
this._procField('depth', 'uint', 16);
this._procField('pre_defined3', 'int', 16);
// AVCSampleEntry fields
this.config = this._readData();
this._procField('config', 'data', -1);
};
// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box
ISOBox.prototype._boxParsers['dref'] = function() {
this._parseFullBox();
this.entry_count = this._readUint(32);
this.entries = [];
for (var i = 0; i < this.entry_count ; i++){
this.entries.push(ISOBox.parse(this));
}
ISOBox.prototype._boxProcessors['dref'] = function() {
this._procFullBox();
this._procField('entry_count', 'uint', 32);
this._procSubBoxes('entries', this.entry_count);
};
// ISO/IEC 14496-12:2012 - 8.6.6 Edit List Box
ISOBox.prototype._boxParsers['elst'] = function() {
this._parseFullBox();
this.entry_count = this._readUint(32);
this.entries = [];
ISOBox.prototype._boxProcessors['elst'] = function() {
this._procFullBox();
this._procField('entry_count', 'uint', 32);
this._procEntries('entries', this.entry_count, function(entry) {
this._procEntryField(entry, 'segment_duration', 'uint', (this.version === 1) ? 64 : 32);
this._procEntryField(entry, 'media_time', 'int', (this.version === 1) ? 64 : 32);
this._procEntryField(entry, 'media_rate_integer', 'int', 16);
this._procEntryField(entry, 'media_rate_fraction', 'int', 16);
});
};
for (var i=1; i <= this.entry_count; i++) {
var entry = {};
if (this.version == 1) {
entry.segment_duration = this._readUint(64);
entry.media_time = this._readInt(64);
} else {
entry.segment_duration = this._readUint(32);
entry.media_time = this._readInt(32);
}
entry.media_rate_integer = this._readInt(16);
entry.media_rate_fraction = this._readInt(16);
this.entries.push(entry);
}
};
// ISO/IEC 23009-1:2014 - 5.10.3.3 Event Message Box
ISOBox.prototype._boxParsers['emsg'] = function() {
this._parseFullBox();
this.scheme_id_uri = this._readTerminatedString();
this.value = this._readTerminatedString();
this.timescale = this._readUint(32);
this.presentation_time_delta = this._readUint(32);
this.event_duration = this._readUint(32);
this.id = this._readUint(32);
this.message_data = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset));
ISOBox.prototype._boxProcessors['emsg'] = function() {
this._procFullBox();
this._procField('scheme_id_uri', 'string', -1);
this._procField('value', 'string', -1);
this._procField('timescale', 'uint', 32);
this._procField('presentation_time_delta', 'uint', 32);
this._procField('event_duration', 'uint', 32);
this._procField('id', 'uint', 32);
this._procField('message_data', 'data', -1);
};
// ISO/IEC 14496-12:2012 - 8.1.2 Free Space Box
ISOBox.prototype._boxParsers['free'] = ISOBox.prototype._boxParsers['skip'] = function() {
this.data = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset));
ISOBox.prototype._boxProcessors['free'] = ISOBox.prototype._boxProcessors['skip'] = function() {
this._procField('data', 'data', -1);
};
// ISO/IEC 14496-12:2012 - 8.12.2 Original Format Box
ISOBox.prototype._boxProcessors['frma'] = function() {
this._procField('data_format', 'uint', 32);
};
// ISO/IEC 14496-12:2012 - 4.3 File Type Box / 8.16.2 Segment Type Box
ISOBox.prototype._boxParsers['ftyp'] = ISOBox.prototype._boxParsers['styp'] = function() {
this.major_brand = this._readString(4);
this.minor_version = this._readUint(32);
this.compatible_brands = [];
while (this._cursor.offset - this._raw.byteOffset < this._raw.byteLength) {
this.compatible_brands.push(this._readString(4));
ISOBox.prototype._boxProcessors['ftyp'] =
ISOBox.prototype._boxProcessors['styp'] = function() {
this._procField('major_brand', 'string', 4);
this._procField('minor_version', 'uint', 32);
var nbCompatibleBrands = -1;
if (this._parsing) {
nbCompatibleBrands = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset)) / 4;
}
this._procFieldArray('compatible_brands', nbCompatibleBrands, 'string', 4);
};
// ISO/IEC 14496-12:2012 - 8.4.3 Handler Reference Box
ISOBox.prototype._boxParsers['hdlr'] = function() {
this._parseFullBox();
this.pre_defined = this._readUint(32);
this.handler_type = this._readString(4);
this.reserved = [this._readUint(32), this._readUint(32), this._readUint(32)];
this.name = this._readTerminatedString();
ISOBox.prototype._boxProcessors['hdlr'] = function() {
this._procFullBox();
this._procField('pre_defined', 'uint', 32);
this._procField('handler_type', 'string', 4);
this._procFieldArray('reserved', 3, 'uint', 32);
this._procField('name', 'string', -1);
};
// ISO/IEC 14496-12:2012 - 8.1.1 Media Data Box
ISOBox.prototype._boxParsers['mdat'] = function() {
this.data = this._readData();
ISOBox.prototype._boxProcessors['mdat'] = function() {
this._procField('data', 'data', -1);
};
// ISO/IEC 14496-12:2012 - 8.4.2 Media Header Box
ISOBox.prototype._boxParsers['mdhd'] = function() {
this._parseFullBox();
if (this.version == 1) {
this.creation_time = this._readUint(64);
this.modification_time = this._readUint(64);
this.timescale = this._readUint(32);
this.duration = this._readUint(64);
} else {
this.creation_time = this._readUint(32);
this.modification_time = this._readUint(32);
this.timescale = this._readUint(32);
this.duration = this._readUint(32);
ISOBox.prototype._boxProcessors['mdhd'] = function() {
this._procFullBox();
this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32);
this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32);
this._procField('timescale', 'uint', 32);
this._procField('duration', 'uint', (this.version == 1) ? 64 : 32);
if (!this._parsing && typeof this.language === 'string') {
// In case of writing and language has been set as a string, then convert it into char codes array
this.language = ((this.language.charCodeAt(0) - 0x60) << 10) |
((this.language.charCodeAt(1) - 0x60) << 5) |
((this.language.charCodeAt(2) - 0x60));
}
var language = this._readUint(16);
this.pad = (language >> 15);
this.language = String.fromCharCode(
((language >> 10) & 0x1F) + 0x60,
((language >> 5) & 0x1F) + 0x60,
(language & 0x1F) + 0x60
);
this.pre_defined = this._readUint(16);
this._procField('language', 'uint', 16);
if (this._parsing) {
this.language = String.fromCharCode(((this.language >> 10) & 0x1F) + 0x60,
((this.language >> 5) & 0x1F) + 0x60,
(this.language & 0x1F) + 0x60);
}
this._procField('pre_defined', 'uint', 16);
};
// ISO/IEC 14496-12:2012 - 8.8.2 Movie Extends Header Box
ISOBox.prototype._boxParsers['mehd'] = function() {
this._parseFullBox();
ISOBox.prototype._boxProcessors['mehd'] = function() {
this._procFullBox();
this._procField('fragment_duration', 'uint', (this.version == 1) ? 64 : 32);
};
if (this.version == 1) {
this.fragment_duration = this._readUint(64);
} else { // version==0
this.fragment_duration = this._readUint(32);
}
};
// ISO/IEC 14496-12:2012 - 8.8.5 Movie Fragment Header Box
ISOBox.prototype._boxParsers['mfhd'] = function() {
this._parseFullBox();
this.sequence_number = this._readUint(32);
ISOBox.prototype._boxProcessors['mfhd'] = function() {
this._procFullBox();
this._procField('sequence_number', 'uint', 32);
};
// ISO/IEC 14496-12:2012 - 8.8.11 Movie Fragment Random Access Box
ISOBox.prototype._boxParsers['mfro'] = function() {
this._parseFullBox();
this.mfra_size = this._readUint(32); // Called mfra_size to distinguish from the normal "size" attribute of a box
ISOBox.prototype._boxProcessors['mfro'] = function() {
this._procFullBox();
this._procField('mfra_size', 'uint', 32); // Called mfra_size to distinguish from the normal "size" attribute of a box
};
// ISO/IEC 14496-12:2012 - 8.5.2.2 mp4a box (use AudioSampleEntry definition and naming)
ISOBox.prototype._boxParsers['mp4a'] = function() {
ISOBox.prototype._boxProcessors['mp4a'] = ISOBox.prototype._boxProcessors['enca'] = function() {
// SampleEntry fields
this.reserved1 = [
this._readUint(8),
this._readUint(8),
this._readUint(8),
this._readUint(8),
this._readUint(8),
this._readUint(8)
];
this.data_reference_index = this._readUint(16);
this._procFieldArray('reserved1', 6, 'uint', 8);
this._procField('data_reference_index', 'uint', 16);
// AudioSampleEntry fields
this.reserved2 = [this._readUint(32), this._readUint(32)];
this.channelcount = this._readUint(16);
this.samplesize = this._readUint(16);
this.pre_defined = this._readUint(16);
this.reserved3 = this._readUint(16);
this.samplerate = this._readTemplate(32);
this._procFieldArray('reserved2', 2, 'uint', 32);
this._procField('channelcount', 'uint', 16);
this._procField('samplesize', 'uint', 16);
this._procField('pre_defined', 'uint', 16);
this._procField('reserved3', 'uint', 16);
this._procField('samplerate', 'template', 32);
// ESDescriptor fields
this.esds = this._readData();
this._procField('esds', 'data', -1);
};
// ISO/IEC 14496-12:2012 - 8.2.2 Movie Header Box
ISOBox.prototype._boxParsers['mvhd'] = function() {
this._parseFullBox();
var i;
ISOBox.prototype._boxProcessors['mvhd'] = function() {
this._procFullBox();
this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32);
this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32);
this._procField('timescale', 'uint', 32);
this._procField('duration', 'uint', (this.version == 1) ? 64 : 32);
this._procField('rate', 'template', 32);
this._procField('volume', 'template', 16);
this._procField('reserved1', 'uint', 16);
this._procFieldArray('reserved2', 2, 'uint', 32);
this._procFieldArray('matrix', 9, 'template', 32);
this._procFieldArray('pre_defined', 6,'uint', 32);
this._procField('next_track_ID', 'uint', 32);
};
if (this.version == 1) {
this.creation_time = this._readUint(64);
this.modification_time = this._readUint(64);
this.timescale = this._readUint(32);
this.duration = this._readUint(64);
} else {
this.creation_time = this._readUint(32);
this.modification_time = this._readUint(32);
this.timescale = this._readUint(32);
this.duration = this._readUint(32);
}
this.rate = this._readTemplate(32);
this.volume = this._readTemplate(16);
this.reserved1 = this._readUint(16);
this.reserved2 = [ this._readUint(32), this._readUint(32) ];
this.matrix = [];
for (i=0; i<9; i++) {
this.matrix.push(this._readTemplate(32));
}
this.pre_defined = [];
for (i=0; i<6; i++) {
this.pre_defined.push(this._readUint(32));
}
this.next_track_ID = this._readUint(32);
};
// ISO/IEC 14496-30:2014 - WebVTT Cue Payload Box.
ISOBox.prototype._boxParsers['payl'] = function() {
var cue_text_raw = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset));
this.cue_text = ISOBoxer.Utils.dataViewToString(cue_text_raw);
ISOBox.prototype._boxProcessors['payl'] = function() {
this._procField('cue_text', 'utf8');
};
// ISO/IEC 14496-12:2012 - 8.16.3 Segment Index Box
ISOBox.prototype._boxParsers['sidx'] = function() {
this._parseFullBox();
this.reference_ID = this._readUint(32);
this.timescale = this._readUint(32);
if (this.version === 0) {
this.earliest_presentation_time = this._readUint(32);
this.first_offset = this._readUint(32);
} else {
this.earliest_presentation_time = this._readUint(64);
this.first_offset = this._readUint(64);
}
this.reserved = this._readUint(16);
this.reference_count = this._readUint(16);
this.references = [];
for (var i=0; i<this.reference_count; i++) {
var ref = {};
var reference = this._readUint(32);
ref.reference_type = (reference >> 31) & 0x1;
ref.referenced_size = reference & 0x7FFFFFFF;
ref.subsegment_duration = this._readUint(32);
var sap = this._readUint(32);
ref.starts_with_SAP = (sap >> 31) & 0x1;
ref.SAP_type = (sap >> 28) & 0x7;
ref.SAP_delta_time = sap & 0xFFFFFFF;
this.references.push(ref);
}
//ISO/IEC 23001-7:2011 - 8.1 Protection System Specific Header Box
ISOBox.prototype._boxProcessors['pssh'] = function() {
this._procFullBox();
this._procFieldArray('SystemID', 16, 'uint', 8);
this._procField('DataSize', 'uint', 32);
this._procFieldArray('Data', this.DataSize, 'uint', 8);
};
// ISO/IEC 14496-12:2012 - 8.4.5.3 Sound Media Header Box
ISOBox.prototype._boxParsers['smhd'] = function() {
this._parseFullBox();
// ISO/IEC 14496-12:2012 - 8.12.5 Scheme Type Box
ISOBox.prototype._boxProcessors['schm'] = function() {
this._procFullBox();
this._procField('scheme_type', 'uint', 32);
this._procField('scheme_version', 'uint', 32);
this.balance = this._readTemplate(16);
this.reserved = this._readUint(16);
if (this.flags & 0x000001) {
this._procField('scheme_uri', 'string', -1);
}
};
// ISO/IEC 14496-12:2012 - 8.6.4.1 sdtp box
ISOBox.prototype._boxProcessors['sdtp'] = function() {
this._procFullBox();
// ISO/IEC 14496-12:2012 - 8.16.4 Subsegment Index Box
ISOBox.prototype._boxParsers['ssix'] = function() {
this._parseFullBox();
this.subsegment_count = this._readUint(32);
this.subsegments = [];
var sample_count = -1;
if (this._parsing) {
sample_count = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset));
}
for (var i=0; i<this.subsegment_count; i++) {
var subsegment = {};
subsegment.ranges_count = this._readUint(32);
subsegment.ranges = [];
this._procFieldArray('sample_dependency_table', sample_count, 'uint', 8);
};
for (var j=0; j<subsegment.ranges_count; j++) {
var range = {};
range.level = this._readUint(8);
range.range_size = this._readUint(24);
subsegment.ranges.push(range);
// ISO/IEC 14496-12:2012 - 8.16.3 Segment Index Box
ISOBox.prototype._boxProcessors['sidx'] = function() {
this._procFullBox();
this._procField('reference_ID', 'uint', 32);
this._procField('timescale', 'uint', 32);
this._procField('earliest_presentation_time', 'uint', (this.version == 1) ? 64 : 32);
this._procField('first_offset', 'uint', (this.version == 1) ? 64 : 32);
this._procField('reserved', 'uint', 16);
this._procField('reference_count', 'uint', 16);
this._procEntries('references', this.reference_count, function(entry) {
if (!this._parsing) {
entry.reference = (entry.reference_type & 0x00000001) << 31;
entry.reference |= (entry.referenced_size & 0x7FFFFFFF);
entry.sap = (entry.starts_with_SAP & 0x00000001) << 31;
entry.sap |= (entry.SAP_type & 0x00000003) << 28;
entry.sap |= (entry.SAP_delta_time & 0x0FFFFFFF);
}
this.subsegments.push(subsegment);
}
this._procEntryField(entry, 'reference', 'uint', 32);
this._procEntryField(entry, 'subsegment_duration', 'uint', 32);
this._procEntryField(entry, 'sap', 'uint', 32);
if (this._parsing) {
entry.reference_type = (entry.reference >> 31) & 0x00000001;
entry.referenced_size = entry.reference & 0x7FFFFFFF;
entry.starts_with_SAP = (entry.sap >> 31) & 0x00000001;
entry.SAP_type = (entry.sap >> 28) & 0x00000007;
entry.SAP_delta_time = (entry.sap & 0x0FFFFFFF);
}
});
};
// ISO/IEC 14496-12:2012 - 8.5.2 Sample Description Box
ISOBox.prototype._boxParsers['stsd'] = function() {
this._parseFullBox();
this.entry_count = this._readUint(32);
this.entries = [];
for (var i = 0; i < this.entry_count ; i++){
this.entries.push(ISOBox.parse(this));
}
// ISO/IEC 14496-12:2012 - 8.4.5.3 Sound Media Header Box
ISOBox.prototype._boxProcessors['smhd'] = function() {
this._procFullBox();
this._procField('balance', 'uint', 16);
this._procField('reserved', 'uint', 16);
};
// ISO/IEC 14496-12:2015 - 8.7.7 Sub-Sample Information Box
ISOBox.prototype._boxParsers['subs'] = function () {
this._parseFullBox();
this.entry_count = this._readUint(32);
this.entries = [];
for (var i = 0; i < this.entry_count; i++) {
var entry = {};
entry.sample_delta = this._readUint(32);
entry.subsample_count = this._readUint(16);
entry.subsamples = [];
for (var j = 0; j < entry.subsample_count; j++) {
var subsample = {};
if (this.version & 0x1) {
subsample.subsample_size = this._readUint(32);
} else {
subsample.subsample_size = this._readUint(16);
}
subsample.subsample_priority = this._readUint(8);
subsample.discardable = this._readUint(8);
subsample.codec_specific_parameters = this._readUint(32);
entry.subsamples.push(subsample);
}
this.entries.push(entry);
}
// ISO/IEC 14496-12:2012 - 8.16.4 Subsegment Index Box
ISOBox.prototype._boxProcessors['ssix'] = function() {
this._procFullBox();
this._procField('subsegment_count', 'uint', 32);
this._procEntries('subsegments', this.subsegment_count, function(subsegment) {
this._procEntryField(subsegment, 'ranges_count', 'uint', 32);
this._procSubEntries(subsegment, 'ranges', subsegment.ranges_count, function(range) {
this._procEntryField(range, 'level', 'uint', 8);
this._procEntryField(range, 'range_size', 'uint', 24);
});
});
};
// ISO/IEC 14496-12:2012 - 8.8.12 Track Fragmnent Decode Time
ISOBox.prototype._boxParsers['tfdt'] = function() {
this._parseFullBox();
if (this.version == 1) {
this.baseMediaDecodeTime = this._readUint(64);
} else {
this.baseMediaDecodeTime = this._readUint(32);
}
// ISO/IEC 14496-12:2012 - 8.5.2 Sample Description Box
ISOBox.prototype._boxProcessors['stsd'] = function() {
this._procFullBox();
this._procField('entry_count', 'uint', 32);
this._procSubBoxes('entries', this.entry_count);
};
// ISO/IEC 14496-12:2012 - 8.8.7 Track Fragment Header Box
ISOBox.prototype._boxParsers['tfhd'] = function() {
this._parseFullBox();
this.track_ID = this._readUint(32);
if (this.flags & 0x1) this.base_data_offset = this._readUint(64);
if (this.flags & 0x2) this.sample_description_offset = this._readUint(32);
if (this.flags & 0x8) this.default_sample_duration = this._readUint(32);
if (this.flags & 0x10) this.default_sample_size = this._readUint(32);
if (this.flags & 0x20) this.default_sample_flags = this._readUint(32);
// ISO/IEC 14496-12:2015 - 8.7.7 Sub-Sample Information Box
ISOBox.prototype._boxProcessors['subs'] = function () {
this._procFullBox();
this._procField('entry_count', 'uint', 32);
this._procEntries('entries', this.entry_count, function(entry) {
this._procEntryField(entry, 'sample_delta', 'uint', 32);
this._procEntryField(entry, 'subsample_count', 'uint', 16);
this._procSubEntries(entry, 'subsamples', entry.subsample_count, function(subsample) {
this._procEntryField(subsample, 'subsample_size', 'uint', (this.version === 1) ? 32 : 16);
this._procEntryField(subsample, 'subsample_priority', 'uint', 8);
this._procEntryField(subsample, 'discardable', 'uint', 8);
this._procEntryField(subsample, 'codec_specific_parameters', 'uint', 32);
});
});
};
// ISO/IEC 14496-12:2012 - 8.8.10 Track Fragment Random Access Box
ISOBox.prototype._boxParsers['tfra'] = function() {
this._parseFullBox();
this.track_ID = this._readUint(32);
this._packed = this._readUint(32);
this.reserved = this._packed >>> 6;
//ISO/IEC 23001-7:2011 - 8.2 Track Encryption Box
ISOBox.prototype._boxProcessors['tenc'] = function() {
this._procFullBox();
this.length_size_of_traf_num = (this._packed && 0xFFFF00000000) >>> 4;
this.length_size_of_trun_num = (this._packed && 0xFFFF0000) >>> 2;
this.length_size_of_sample_num = this._packed && 0xFF;
this._procField('default_IsEncrypted', 'uint', 24);
this._procField('default_IV_size', 'uint', 8);
this._procFieldArray('default_KID', 16, 'uint', 8);
};
this.number_of_entry = this._readUint(32);
// ISO/IEC 14496-12:2012 - 8.8.12 Track Fragmnent Decode Time
ISOBox.prototype._boxProcessors['tfdt'] = function() {
this._procFullBox();
this._procField('baseMediaDecodeTime', 'uint', (this.version == 1) ? 64 : 32);
};
this.entries = [];
// ISO/IEC 14496-12:2012 - 8.8.7 Track Fragment Header Box
ISOBox.prototype._boxProcessors['tfhd'] = function() {
this._procFullBox();
this._procField('track_ID', 'uint', 32);
if (this.flags & 0x01) this._procField('base_data_offset', 'uint', 64);
if (this.flags & 0x02) this._procField('sample_description_offset', 'uint', 32);
if (this.flags & 0x08) this._procField('default_sample_duration', 'uint', 32);
if (this.flags & 0x10) this._procField('default_sample_size', 'uint', 32);
if (this.flags & 0x20) this._procField('default_sample_flags', 'uint', 32);
};
for (var i = 0; i < this.number_of_entry ; i++){
var entry = {};
if(this.version==1){
entry.time = this._readUint(64);
entry.moof_offset = this._readUint(64);
}else{
entry.time = this._readUint(32);
entry.moof_offset = this._readUint(32);
}
entry.traf_number = this._readUint((this.length_size_of_traf_num + 1) * 8);
entry.trun_number = this._readUint((this.length_size_of_trun_num + 1) * 8);
entry.sample_number = this._readUint((this.length_size_of_sample_num + 1) * 8);
this.entries.push(entry);
// ISO/IEC 14496-12:2012 - 8.8.10 Track Fragment Random Access Box
ISOBox.prototype._boxProcessors['tfra'] = function() {
this._procFullBox();
this._procField('track_ID', 'uint', 32);
if (!this._parsing) {
this.reserved = 0;
this.reserved |= (this.length_size_of_traf_num & 0x00000030) << 4;
this.reserved |= (this.length_size_of_trun_num & 0x0000000C) << 2;
this.reserved |= (this.length_size_of_sample_num & 0x00000003);
}
this._procField('reserved', 'uint', 32);
if (this._parsing) {
this.length_size_of_traf_num = (this.reserved & 0x00000030) >> 4;
this.length_size_of_trun_num = (this.reserved & 0x0000000C) >> 2;
this.length_size_of_sample_num = (this.reserved & 0x00000003);
}
this._procField('number_of_entry', 'uint', 32);
this._procEntries('entries', this.number_of_entry, function(entry) {
this._procEntryField(entry, 'time', 'uint', (this.version === 1) ? 64 : 32);
this._procEntryField(entry, 'moof_offset', 'uint', (this.version === 1) ? 64 : 32);
this._procEntryField(entry, 'traf_number', 'uint', (this.length_size_of_traf_num + 1) * 8);
this._procEntryField(entry, 'trun_number', 'uint', (this.length_size_of_trun_num + 1) * 8);
this._procEntryField(entry, 'sample_number', 'uint', (this.length_size_of_sample_num + 1) * 8);
});
};
// ISO/IEC 14496-12:2012 - 8.3.2 Track Header Box
ISOBox.prototype._boxParsers['tkhd'] = function() {
this._parseFullBox();
ISOBox.prototype._boxProcessors['tkhd'] = function() {
this._procFullBox();
this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32);
this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32);
this._procField('track_ID', 'uint', 32);
this._procField('reserved1', 'uint', 32);
this._procField('duration', 'uint', (this.version == 1) ? 64 : 32);
this._procFieldArray('reserved2', 2, 'uint', 32);
this._procField('layer', 'uint', 16);
this._procField('alternate_group', 'uint', 16);
this._procField('volume', 'template', 16);
this._procField('reserved3', 'uint', 16);
this._procFieldArray('matrix', 9, 'template', 32);
this._procField('width', 'template', 32);
this._procField('height', 'template', 32);
};
if (this.version == 1) {
this.creation_time = this._readUint(64);
this.modification_time = this._readUint(64);
this.track_ID = this._readUint(32);
this.reserved1 = this._readUint(32);
this.duration = this._readUint(64);
} else {
this.creation_time = this._readUint(32);
this.modification_time = this._readUint(32);
this.track_ID = this._readUint(32);
this.reserved1 = this._readUint(32);
this.duration = this._readUint(32);
}
this.reserved2 = [
this._readUint(32),
this._readUint(32)
];
this.layer = this._readUint(16);
this.alternate_group = this._readUint(16);
this.volume = this._readTemplate(16);
this.reserved3 = this._readUint(16);
this.matrix = [];
for (var i=0; i<9; i++) {
this.matrix.push(this._readTemplate(32));
}
this.width = this._readTemplate(32);
this.height = this._readTemplate(32);
// ISO/IEC 14496-12:2012 - 8.8.3 Track Extends Box
ISOBox.prototype._boxProcessors['trex'] = function() {
this._procFullBox();
this._procField('track_ID', 'uint', 32);
this._procField('default_sample_description_index', 'uint', 32);
this._procField('default_sample_duration', 'uint', 32);
this._procField('default_sample_size', 'uint', 32);
this._procField('default_sample_flags', 'uint', 32);
};
// ISO/IEC 14496-12:2012 - 8.8.3 Track Extends Box
ISOBox.prototype._boxParsers['trex'] = function() {
this._parseFullBox();
this.track_ID = this._readUint(32);
this.default_sample_description_index = this._readUint(32);
this.default_sample_duration = this._readUint(32);
this.default_sample_size = this._readUint(32);
this.default_sample_flags = this._readUint(32);
};
// ISO/IEC 14496-12:2012 - 8.8.8 Track Run Box
// Note: the 'trun' box has a direct relation to the 'tfhd' box for defaults.
// These defaults are not set explicitly here, but are left to resolve for the user.
ISOBox.prototype._boxParsers['trun'] = function() {
this._parseFullBox();
this.sample_count = this._readUint(32);
if (this.flags & 0x1) this.data_offset = this._readInt(32);
if (this.flags & 0x4) this.first_sample_flags = this._readUint(32);
this.samples = [];
for (var i=0; i<this.sample_count; i++) {
var sample = {};
if (this.flags & 0x100) sample.sample_duration = this._readUint(32);
if (this.flags & 0x200) sample.sample_size = this._readUint(32);
if (this.flags & 0x400) sample.sample_flags = this._readUint(32);
if (this.flags & 0x800) {
if (this.version === 0) {
sample.sample_composition_time_offset = this._readUint(32);
} else {
sample.sample_composition_time_offset = this._readInt(32);
}
}
this.samples.push(sample);
}
ISOBox.prototype._boxProcessors['trun'] = function() {
this._procFullBox();
this._procField('sample_count', 'uint', 32);
if (this.flags & 0x1) this._procField('data_offset', 'int', 32);
if (this.flags & 0x4) this._procField('first_sample_flags', 'uint', 32);
this._procEntries('samples', this.sample_count, function(sample) {
if (this.flags & 0x100) this._procEntryField(sample, 'sample_duration', 'uint', 32);
if (this.flags & 0x200) this._procEntryField(sample, 'sample_size', 'uint', 32);
if (this.flags & 0x400) this._procEntryField(sample, 'sample_flags', 'uint', 32);
if (this.flags & 0x800) this._procEntryField(sample, 'sample_composition_time_offset', (this.version === 1) ? 'int' : 'uint', 32);
});
};
// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box
ISOBox.prototype._boxParsers['url '] = ISOBox.prototype._boxParsers['urn '] = function() {
this._parseFullBox();
ISOBox.prototype._boxProcessors['url '] = ISOBox.prototype._boxProcessors['urn '] = function() {
this._procFullBox();
if (this.type === 'urn ') {
this.name = this._readTerminatedString();
this._procField('name', 'string', -1);
}
this.location = this._readTerminatedString();
this._procField('location', 'string', -1);
};
// ISO/IEC 14496-30:2014 - WebVTT Source Label Box
ISOBox.prototype._boxParsers['vlab'] = function() {
var source_label_raw = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset));
this.source_label = ISOBoxer.Utils.dataViewToString(source_label_raw);
ISOBox.prototype._boxProcessors['vlab'] = function() {
this._procField('source_label', 'utf8');
};
// ISO/IEC 14496-12:2012 - 8.4.5.2 Video Media Header Box
ISOBox.prototype._boxParsers['vmhd'] = function() {
this._parseFullBox();
this.graphicsmode = this._readUint(16);
this.opcolor = [this._readUint(16), this._readUint(16), this._readUint(16)];
ISOBox.prototype._boxProcessors['vmhd'] = function() {
this._procFullBox();
this._procField('graphicsmode', 'uint', 16);
this._procFieldArray('opcolor', 3, 'uint', 16);
};
// ISO/IEC 14496-30:2014 - WebVTT Configuration Box
ISOBox.prototype._boxParsers['vttC'] = function() {
var config_raw = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset));
this.config = ISOBoxer.Utils.dataViewToString(config_raw);
ISOBox.prototype._boxProcessors['vttC'] = function() {
this._procField('config', 'utf8');
};
// ISO/IEC 14496-30:2014 - WebVTT Empty Sample Box
ISOBox.prototype._boxParsers['vtte'] = function() {
ISOBox.prototype._boxProcessors['vtte'] = function() {
// Nothing should happen here.
};

@@ -1,2 +0,2 @@

/*! codem-isoboxer v0.2.10 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */
var ISOBoxer={};ISOBoxer.parseBuffer=function(a){return new ISOFile(a).parse()},ISOBoxer.addBoxParser=function(a,b){"string"==typeof a&&"function"==typeof b&&(ISOBox.prototype._boxParsers[a]=b)},ISOBoxer.Utils={},ISOBoxer.Utils.dataViewToString=function(a,b){var c=b||"utf-8";if("undefined"!=typeof TextDecoder)return new TextDecoder(c).decode(a);var d=[],e=0;if("utf-8"===c)for(;e<a.byteLength;){var f=a.getUint8(e++);f<128||(f<224?(f=(31&f)<<6,f|=63&a.getUint8(e++)):f<240?(f=(15&f)<<12,f|=(63&a.getUint8(e++))<<6,f|=63&a.getUint8(e++)):(f=(7&f)<<18,f|=(63&a.getUint8(e++))<<12,f|=(63&a.getUint8(e++))<<6,f|=63&a.getUint8(e++))),d.push(String.fromCharCode(f))}else for(;e<a.byteLength;)d.push(String.fromCharCode(a.getUint8(e++)));return d.join("")},"undefined"!=typeof exports&&(exports.parseBuffer=ISOBoxer.parseBuffer,exports.addBoxParser=ISOBoxer.addBoxParser,exports.Utils=ISOBoxer.Utils),ISOBoxer.Cursor=function(a){this.offset="undefined"==typeof a?0:a};var ISOFile=function(a){this._raw=new DataView(a),this._cursor=new ISOBoxer.Cursor,this.boxes=[]};ISOFile.prototype.fetch=function(a){var b=this.fetchAll(a,!0);return b.length?b[0]:null},ISOFile.prototype.fetchAll=function(a,b){var c=[];return ISOFile._sweep.call(this,a,c,b),c},ISOFile.prototype.parse=function(){for(this._cursor.offset=0,this.boxes=[];this._cursor.offset<this._raw.byteLength;){var a=ISOBox.parse(this);if("undefined"==typeof a.type)break;this.boxes.push(a)}return this},ISOFile._sweep=function(a,b,c){this.type&&this.type==a&&b.push(this);for(var d in this.boxes){if(b.length&&c)return;ISOFile._sweep.call(this.boxes[d],a,b,c)}};var ISOBox=function(){this._cursor=new ISOBoxer.Cursor};ISOBox.parse=function(a){var b=new ISOBox;return b._offset=a._cursor.offset,b._root=a._root?a._root:a,b._raw=a._raw,b._parent=a,b._parseBox(),a._cursor.offset=b._raw.byteOffset+b._raw.byteLength,b},ISOBox.prototype._readInt=function(a){var b=null;switch(a){case 8:b=this._raw.getInt8(this._cursor.offset-this._raw.byteOffset);break;case 16:b=this._raw.getInt16(this._cursor.offset-this._raw.byteOffset);break;case 32:b=this._raw.getInt32(this._cursor.offset-this._raw.byteOffset);break;case 64:var c=this._raw.getInt32(this._cursor.offset-this._raw.byteOffset),d=this._raw.getInt32(this._cursor.offset-this._raw.byteOffset+4);b=c*Math.pow(2,32)+d}return this._cursor.offset+=a>>3,b},ISOBox.prototype._readUint=function(a){var b,c,d=null;switch(a){case 8:d=this._raw.getUint8(this._cursor.offset-this._raw.byteOffset);break;case 16:d=this._raw.getUint16(this._cursor.offset-this._raw.byteOffset);break;case 24:b=this._raw.getUint16(this._cursor.offset-this._raw.byteOffset),c=this._raw.getUint8(this._cursor.offset-this._raw.byteOffset+2),d=(b<<8)+c;break;case 32:d=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset);break;case 64:b=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset),c=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset+4),d=b*Math.pow(2,32)+c}return this._cursor.offset+=a>>3,d},ISOBox.prototype._readString=function(a){for(var b="",c=0;c<a;c++){var d=this._readUint(8);b+=String.fromCharCode(d)}return b},ISOBox.prototype._readTerminatedString=function(){for(var a="";this._cursor.offset-this._offset<this._raw.byteLength;){var b=this._readUint(8);if(0===b)break;a+=String.fromCharCode(b)}return a},ISOBox.prototype._readTemplate=function(a){var b=this._readUint(a/2),c=this._readUint(a/2);return b+c/Math.pow(2,a/2)},ISOBox.prototype._readData=function(a){var b=a>0?a:this._raw.byteLength-(this._cursor.offset-this._offset),c=new DataView(this._raw.buffer,this._cursor.offset,b);return this._cursor.offset+=b,c},ISOBox.prototype._parseBox=function(){if(this._cursor.offset=this._offset,this._offset+8>this._raw.buffer.byteLength)return void(this._root._incomplete=!0);switch(this.size=this._readUint(32),this.type=this._readString(4),1==this.size&&(this.largesize=this._readUint(64)),"uuid"==this.type&&(this.usertype=this._readString(16)),this.size){case 0:this._raw=new DataView(this._raw.buffer,this._offset,this._raw.byteLength-this._cursor.offset);break;case 1:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.largesize);break;default:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.size)}this._incomplete||(this._boxContainers.indexOf(this.type)!==-1?this._parseContainerBox():this._boxParsers[this.type]&&this._boxParsers[this.type].call(this))},ISOBox.prototype._parseFullBox=function(){this.version=this._readUint(8),this.flags=this._readUint(24)},ISOBox.prototype._parseContainerBox=function(){for(this.boxes=[];this._cursor.offset-this._raw.byteOffset<this._raw.byteLength;)this.boxes.push(ISOBox.parse(this))},ISOBox.prototype._boxContainers=["dinf","edts","mdia","meco","mfra","minf","moof","moov","mvex","stbl","strk","traf","trak","tref","udta","vttc"],ISOBox.prototype._boxParsers={},ISOBox.prototype._boxParsers.avc1=function(){this.reserved1=[this._readUint(8),this._readUint(8),this._readUint(8),this._readUint(8),this._readUint(8),this._readUint(8)],this.data_reference_index=this._readUint(16),this.pre_defined1=this._readUint(16),this.reserved2=this._readUint(16),this.pre_defined2=[this._readUint(32),this._readUint(32),this._readUint(32)],this.width=this._readUint(16),this.height=this._readUint(16),this.horizresolution=this._readTemplate(32),this.vertresolution=this._readTemplate(32),this.reserved3=this._readUint(32),this.frame_count=this._readUint(16);var a=this._readUint(8);this.compressorname=this._readString(a);for(var b=0;b<31-a;b++)this._readUint(8);this.depth=this._readUint(16),this.pre_defined3=this._readInt(16),this.config=this._readData()},ISOBox.prototype._boxParsers.dref=function(){this._parseFullBox(),this.entry_count=this._readUint(32),this.entries=[];for(var a=0;a<this.entry_count;a++)this.entries.push(ISOBox.parse(this))},ISOBox.prototype._boxParsers.elst=function(){this._parseFullBox(),this.entry_count=this._readUint(32),this.entries=[];for(var a=1;a<=this.entry_count;a++){var b={};1==this.version?(b.segment_duration=this._readUint(64),b.media_time=this._readInt(64)):(b.segment_duration=this._readUint(32),b.media_time=this._readInt(32)),b.media_rate_integer=this._readInt(16),b.media_rate_fraction=this._readInt(16),this.entries.push(b)}},ISOBox.prototype._boxParsers.emsg=function(){this._parseFullBox(),this.scheme_id_uri=this._readTerminatedString(),this.value=this._readTerminatedString(),this.timescale=this._readUint(32),this.presentation_time_delta=this._readUint(32),this.event_duration=this._readUint(32),this.id=this._readUint(32),this.message_data=new DataView(this._raw.buffer,this._cursor.offset,this._raw.byteLength-(this._cursor.offset-this._offset))},ISOBox.prototype._boxParsers.free=ISOBox.prototype._boxParsers.skip=function(){this.data=new DataView(this._raw.buffer,this._cursor.offset,this._raw.byteLength-(this._cursor.offset-this._offset))},ISOBox.prototype._boxParsers.ftyp=ISOBox.prototype._boxParsers.styp=function(){for(this.major_brand=this._readString(4),this.minor_version=this._readUint(32),this.compatible_brands=[];this._cursor.offset-this._raw.byteOffset<this._raw.byteLength;)this.compatible_brands.push(this._readString(4))},ISOBox.prototype._boxParsers.hdlr=function(){this._parseFullBox(),this.pre_defined=this._readUint(32),this.handler_type=this._readString(4),this.reserved=[this._readUint(32),this._readUint(32),this._readUint(32)],this.name=this._readTerminatedString()},ISOBox.prototype._boxParsers.mdat=function(){this.data=this._readData()},ISOBox.prototype._boxParsers.mdhd=function(){this._parseFullBox(),1==this.version?(this.creation_time=this._readUint(64),this.modification_time=this._readUint(64),this.timescale=this._readUint(32),this.duration=this._readUint(64)):(this.creation_time=this._readUint(32),this.modification_time=this._readUint(32),this.timescale=this._readUint(32),this.duration=this._readUint(32));var a=this._readUint(16);this.pad=a>>15,this.language=String.fromCharCode((a>>10&31)+96,(a>>5&31)+96,(31&a)+96),this.pre_defined=this._readUint(16)},ISOBox.prototype._boxParsers.mehd=function(){this._parseFullBox(),1==this.version?this.fragment_duration=this._readUint(64):this.fragment_duration=this._readUint(32)},ISOBox.prototype._boxParsers.mfhd=function(){this._parseFullBox(),this.sequence_number=this._readUint(32)},ISOBox.prototype._boxParsers.mfro=function(){this._parseFullBox(),this.mfra_size=this._readUint(32)},ISOBox.prototype._boxParsers.mp4a=function(){this.reserved1=[this._readUint(8),this._readUint(8),this._readUint(8),this._readUint(8),this._readUint(8),this._readUint(8)],this.data_reference_index=this._readUint(16),this.reserved2=[this._readUint(32),this._readUint(32)],this.channelcount=this._readUint(16),this.samplesize=this._readUint(16),this.pre_defined=this._readUint(16),this.reserved3=this._readUint(16),this.samplerate=this._readTemplate(32),this.esds=this._readData()},ISOBox.prototype._boxParsers.mvhd=function(){this._parseFullBox();var a;for(1==this.version?(this.creation_time=this._readUint(64),this.modification_time=this._readUint(64),this.timescale=this._readUint(32),this.duration=this._readUint(64)):(this.creation_time=this._readUint(32),this.modification_time=this._readUint(32),this.timescale=this._readUint(32),this.duration=this._readUint(32)),this.rate=this._readTemplate(32),this.volume=this._readTemplate(16),this.reserved1=this._readUint(16),this.reserved2=[this._readUint(32),this._readUint(32)],this.matrix=[],a=0;a<9;a++)this.matrix.push(this._readTemplate(32));for(this.pre_defined=[],a=0;a<6;a++)this.pre_defined.push(this._readUint(32));this.next_track_ID=this._readUint(32)},ISOBox.prototype._boxParsers.payl=function(){var a=new DataView(this._raw.buffer,this._cursor.offset,this._raw.byteLength-(this._cursor.offset-this._offset));this.cue_text=ISOBoxer.Utils.dataViewToString(a)},ISOBox.prototype._boxParsers.sidx=function(){this._parseFullBox(),this.reference_ID=this._readUint(32),this.timescale=this._readUint(32),0===this.version?(this.earliest_presentation_time=this._readUint(32),this.first_offset=this._readUint(32)):(this.earliest_presentation_time=this._readUint(64),this.first_offset=this._readUint(64)),this.reserved=this._readUint(16),this.reference_count=this._readUint(16),this.references=[];for(var a=0;a<this.reference_count;a++){var b={},c=this._readUint(32);b.reference_type=c>>31&1,b.referenced_size=2147483647&c,b.subsegment_duration=this._readUint(32);var d=this._readUint(32);b.starts_with_SAP=d>>31&1,b.SAP_type=d>>28&7,b.SAP_delta_time=268435455&d,this.references.push(b)}},ISOBox.prototype._boxParsers.smhd=function(){this._parseFullBox(),this.balance=this._readTemplate(16),this.reserved=this._readUint(16)},ISOBox.prototype._boxParsers.ssix=function(){this._parseFullBox(),this.subsegment_count=this._readUint(32),this.subsegments=[];for(var a=0;a<this.subsegment_count;a++){var b={};b.ranges_count=this._readUint(32),b.ranges=[];for(var c=0;c<b.ranges_count;c++){var d={};d.level=this._readUint(8),d.range_size=this._readUint(24),b.ranges.push(d)}this.subsegments.push(b)}},ISOBox.prototype._boxParsers.stsd=function(){this._parseFullBox(),this.entry_count=this._readUint(32),this.entries=[];for(var a=0;a<this.entry_count;a++)this.entries.push(ISOBox.parse(this))},ISOBox.prototype._boxParsers.subs=function(){this._parseFullBox(),this.entry_count=this._readUint(32),this.entries=[];for(var a=0;a<this.entry_count;a++){var b={};b.sample_delta=this._readUint(32),b.subsample_count=this._readUint(16),b.subsamples=[];for(var c=0;c<b.subsample_count;c++){var d={};1&this.version?d.subsample_size=this._readUint(32):d.subsample_size=this._readUint(16),d.subsample_priority=this._readUint(8),d.discardable=this._readUint(8),d.codec_specific_parameters=this._readUint(32),b.subsamples.push(d)}this.entries.push(b)}},ISOBox.prototype._boxParsers.tfdt=function(){this._parseFullBox(),1==this.version?this.baseMediaDecodeTime=this._readUint(64):this.baseMediaDecodeTime=this._readUint(32)},ISOBox.prototype._boxParsers.tfhd=function(){this._parseFullBox(),this.track_ID=this._readUint(32),1&this.flags&&(this.base_data_offset=this._readUint(64)),2&this.flags&&(this.sample_description_offset=this._readUint(32)),8&this.flags&&(this.default_sample_duration=this._readUint(32)),16&this.flags&&(this.default_sample_size=this._readUint(32)),32&this.flags&&(this.default_sample_flags=this._readUint(32))},ISOBox.prototype._boxParsers.tfra=function(){this._parseFullBox(),this.track_ID=this._readUint(32),this._packed=this._readUint(32),this.reserved=this._packed>>>6,this.length_size_of_traf_num=(this._packed&&0xffff00000000)>>>4,this.length_size_of_trun_num=(this._packed&&4294901760)>>>2,this.length_size_of_sample_num=this._packed&&255,this.number_of_entry=this._readUint(32),this.entries=[];for(var a=0;a<this.number_of_entry;a++){var b={};1==this.version?(b.time=this._readUint(64),b.moof_offset=this._readUint(64)):(b.time=this._readUint(32),b.moof_offset=this._readUint(32)),b.traf_number=this._readUint(8*(this.length_size_of_traf_num+1)),b.trun_number=this._readUint(8*(this.length_size_of_trun_num+1)),b.sample_number=this._readUint(8*(this.length_size_of_sample_num+1)),this.entries.push(b)}},ISOBox.prototype._boxParsers.tkhd=function(){this._parseFullBox(),1==this.version?(this.creation_time=this._readUint(64),this.modification_time=this._readUint(64),this.track_ID=this._readUint(32),this.reserved1=this._readUint(32),this.duration=this._readUint(64)):(this.creation_time=this._readUint(32),this.modification_time=this._readUint(32),this.track_ID=this._readUint(32),this.reserved1=this._readUint(32),this.duration=this._readUint(32)),this.reserved2=[this._readUint(32),this._readUint(32)],this.layer=this._readUint(16),this.alternate_group=this._readUint(16),this.volume=this._readTemplate(16),this.reserved3=this._readUint(16),this.matrix=[];for(var a=0;a<9;a++)this.matrix.push(this._readTemplate(32));this.width=this._readTemplate(32),this.height=this._readTemplate(32)},ISOBox.prototype._boxParsers.trex=function(){this._parseFullBox(),this.track_ID=this._readUint(32),this.default_sample_description_index=this._readUint(32),this.default_sample_duration=this._readUint(32),this.default_sample_size=this._readUint(32),this.default_sample_flags=this._readUint(32)},ISOBox.prototype._boxParsers.trun=function(){this._parseFullBox(),this.sample_count=this._readUint(32),1&this.flags&&(this.data_offset=this._readInt(32)),4&this.flags&&(this.first_sample_flags=this._readUint(32)),this.samples=[];for(var a=0;a<this.sample_count;a++){var b={};256&this.flags&&(b.sample_duration=this._readUint(32)),512&this.flags&&(b.sample_size=this._readUint(32)),1024&this.flags&&(b.sample_flags=this._readUint(32)),2048&this.flags&&(0===this.version?b.sample_composition_time_offset=this._readUint(32):b.sample_composition_time_offset=this._readInt(32)),this.samples.push(b)}},ISOBox.prototype._boxParsers["url "]=ISOBox.prototype._boxParsers["urn "]=function(){this._parseFullBox(),"urn "===this.type&&(this.name=this._readTerminatedString()),this.location=this._readTerminatedString()},ISOBox.prototype._boxParsers.vlab=function(){var a=new DataView(this._raw.buffer,this._cursor.offset,this._raw.byteLength-(this._cursor.offset-this._offset));this.source_label=ISOBoxer.Utils.dataViewToString(a)},ISOBox.prototype._boxParsers.vmhd=function(){this._parseFullBox(),this.graphicsmode=this._readUint(16),this.opcolor=[this._readUint(16),this._readUint(16),this._readUint(16)]},ISOBox.prototype._boxParsers.vttC=function(){var a=new DataView(this._raw.buffer,this._cursor.offset,this._raw.byteLength-(this._cursor.offset-this._offset));this.config=ISOBoxer.Utils.dataViewToString(a)},ISOBox.prototype._boxParsers.vtte=function(){};
/*! codem-isoboxer v0.3.0 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */
var ISOBoxer={};ISOBoxer.parseBuffer=function(a){return new ISOFile(a).parse()},ISOBoxer.addBoxProcessor=function(a,b){"string"==typeof a&&"function"==typeof b&&(ISOBox.prototype._boxProcessors[a]=b)},ISOBoxer.createFile=function(){return new ISOFile},ISOBoxer.createBox=function(a,b,c){var d=ISOBox.create(a);return b&&b.append(d,c),d},ISOBoxer.createFullBox=function(a,b,c){var d=ISOBoxer.createBox(a,b,c);return d.version=0,d.flags=0,d},ISOBoxer.Utils={},ISOBoxer.Utils.dataViewToString=function(a,b){var c=b||"utf-8";if("undefined"!=typeof TextDecoder)return new TextDecoder(c).decode(a);var d=[],e=0;if("utf-8"===c)for(;e<a.byteLength;){var f=a.getUint8(e++);f<128||(f<224?(f=(31&f)<<6,f|=63&a.getUint8(e++)):f<240?(f=(15&f)<<12,f|=(63&a.getUint8(e++))<<6,f|=63&a.getUint8(e++)):(f=(7&f)<<18,f|=(63&a.getUint8(e++))<<12,f|=(63&a.getUint8(e++))<<6,f|=63&a.getUint8(e++))),d.push(String.fromCharCode(f))}else for(;e<a.byteLength;)d.push(String.fromCharCode(a.getUint8(e++)));return d.join("")},ISOBoxer.Utils.utf8ToByteArray=function(a){var b,c;if("undefined"!=typeof TextEncoder)b=(new TextEncoder).encode(a);else for(b=[],c=0;c<a.length;++c){var d=a.charCodeAt(c);d<128?b.push(d):d<2048?(b.push(192|d>>6),b.push(128|63&d)):d<65536?(b.push(224|d>>12),b.push(128|63&d>>6),b.push(128|63&d)):(b.push(240|d>>18),b.push(128|63&d>>12),b.push(128|63&d>>6),b.push(128|63&d))}return b},ISOBoxer.Utils.appendBox=function(a,b,c){if(b._offset=a._cursor.offset,b._root=a._root?a._root:a,b._raw=a._raw,b._parent=a,c!==-1){if(void 0===c||null===c)return void a.boxes.push(b);var d,e=-1;if("number"==typeof c)e=c;else{if("string"==typeof c)d=c;else{if("object"!=typeof c||!c.type)return void a.boxes.push(b);d=c.type}for(var f=0;f<a.boxes.length;f++)if(d===a.boxes[f].type){e=f+1;break}}a.boxes.splice(e,0,b)}},"undefined"!=typeof exports&&(exports.parseBuffer=ISOBoxer.parseBuffer,exports.addBoxProcessor=ISOBoxer.addBoxProcessor,exports.createFile=ISOBoxer.createFile,exports.createBox=ISOBoxer.createBox,exports.createFullBox=ISOBoxer.createFullBox,exports.Utils=ISOBoxer.Utils),ISOBoxer.Cursor=function(a){this.offset="undefined"==typeof a?0:a};var ISOFile=function(a){this._cursor=new ISOBoxer.Cursor,this.boxes=[],a&&(this._raw=new DataView(a))};ISOFile.prototype.fetch=function(a){var b=this.fetchAll(a,!0);return b.length?b[0]:null},ISOFile.prototype.fetchAll=function(a,b){var c=[];return ISOFile._sweep.call(this,a,c,b),c},ISOFile.prototype.parse=function(){for(this._cursor.offset=0,this.boxes=[];this._cursor.offset<this._raw.byteLength;){var a=ISOBox.parse(this);if("undefined"==typeof a.type)break;this.boxes.push(a)}return this},ISOFile._sweep=function(a,b,c){this.type&&this.type==a&&b.push(this);for(var d in this.boxes){if(b.length&&c)return;ISOFile._sweep.call(this.boxes[d],a,b,c)}},ISOFile.prototype.write=function(){var a,b=0;for(a=0;a<this.boxes.length;a++)b+=this.boxes[a].getLength(!1);var c=new Uint8Array(b);for(this._rawo=new DataView(c.buffer),this.bytes=c,this._cursor.offset=0,a=0;a<this.boxes.length;a++)this.boxes[a].write();return c.buffer},ISOFile.prototype.append=function(a,b){ISOBoxer.Utils.appendBox(this,a,b)};var ISOBox=function(){this._cursor=new ISOBoxer.Cursor};ISOBox.parse=function(a){var b=new ISOBox;return b._offset=a._cursor.offset,b._root=a._root?a._root:a,b._raw=a._raw,b._parent=a,b._parseBox(),a._cursor.offset=b._raw.byteOffset+b._raw.byteLength,b},ISOBox.create=function(a){var b=new ISOBox;return b.type=a,b.boxes=[],b},ISOBox.prototype._boxContainers=["dinf","edts","mdia","meco","mfra","minf","moof","moov","mvex","stbl","strk","traf","trak","tref","udta","vttc","sinf","schi","encv","enca"],ISOBox.prototype._boxProcessors={},ISOBox.prototype._procField=function(a,b,c){this._parsing?this[a]=this._readField(b,c):this._writeField(b,c,this[a])},ISOBox.prototype._procFieldArray=function(a,b,c,d){var e;if(this._parsing)for(this[a]=[],e=0;e<b;e++)this[a][e]=this._readField(c,d);else for(e=0;e<this[a].length;e++)this._writeField(c,d,this[a][e])},ISOBox.prototype._procFullBox=function(){this._procField("version","uint",8),this._procField("flags","uint",24)},ISOBox.prototype._procEntries=function(a,b,c){var d;if(this._parsing)for(this[a]=[],d=0;d<b;d++)this[a].push({}),c.call(this,this[a][d]);else for(d=0;d<b;d++)c.call(this,this[a][d])},ISOBox.prototype._procSubEntries=function(a,b,c,d){var e;if(this._parsing)for(a[b]=[],e=0;e<c;e++)a[b].push({}),d.call(this,a[b][e]);else for(e=0;e<c;e++)d.call(this,a[b][e])},ISOBox.prototype._procEntryField=function(a,b,c,d){this._parsing?a[b]=this._readField(c,d):this._writeField(c,d,a[b])},ISOBox.prototype._procSubBoxes=function(a,b){var c;if(this._parsing)for(this[a]=[],c=0;c<b;c++)this[a].push(ISOBox.parse(this));else for(c=0;c<b;c++)this._rawo?this[a][c].write():this.size+=this[a][c].getLength()},ISOBox.prototype._readField=function(a,b){switch(a){case"uint":return this._readUint(b);case"int":return this._readInt(b);case"template":return this._readTemplate(b);case"string":return b===-1?this._readTerminatedString():this._readString(b);case"data":return this._readData(b);case"utf8":return this._readUTF8String();default:return-1}},ISOBox.prototype._readInt=function(a){var b=null,c=this._cursor.offset-this._raw.byteOffset;switch(a){case 8:b=this._raw.getInt8(c);break;case 16:b=this._raw.getInt16(c);break;case 32:b=this._raw.getInt32(c);break;case 64:var d=this._raw.getInt32(c),e=this._raw.getInt32(c+4);b=d*Math.pow(2,32)+e}return this._cursor.offset+=a>>3,b},ISOBox.prototype._readUint=function(a){var b,c,d=null,e=this._cursor.offset-this._raw.byteOffset;switch(a){case 8:d=this._raw.getUint8(e);break;case 16:d=this._raw.getUint16(e);break;case 24:b=this._raw.getUint16(e),c=this._raw.getUint8(e+2),d=(b<<8)+c;break;case 32:d=this._raw.getUint32(e);break;case 64:b=this._raw.getUint32(e),c=this._raw.getUint32(e+4),d=b*Math.pow(2,32)+c}return this._cursor.offset+=a>>3,d},ISOBox.prototype._readString=function(a){for(var b="",c=0;c<a;c++){var d=this._readUint(8);b+=String.fromCharCode(d)}return b},ISOBox.prototype._readTemplate=function(a){var b=this._readUint(a/2),c=this._readUint(a/2);return b+c/Math.pow(2,a/2)},ISOBox.prototype._readTerminatedString=function(){for(var a="";this._cursor.offset-this._offset<this._raw.byteLength;){var b=this._readUint(8);if(0===b)break;a+=String.fromCharCode(b)}return a},ISOBox.prototype._readData=function(a){var b=a>0?a:this._raw.byteLength-(this._cursor.offset-this._offset),c=new DataView(this._raw.buffer,this._cursor.offset,b);return this._cursor.offset+=b,c},ISOBox.prototype._readUTF8String=function(){var a=this._readData();return ISOBoxer.Utils.dataViewToString(a)},ISOBox.prototype._parseBox=function(){if(this._parsing=!0,this._cursor.offset=this._offset,this._offset+8>this._raw.buffer.byteLength)return void(this._root._incomplete=!0);switch(this._procField("size","uint",32),this._procField("type","string",4),1===this.size&&this._procField("largesize","uint",64),"uuid"===this.type&&this._procFieldArray("usertype",16,"uint",8),this.size){case 0:this._raw=new DataView(this._raw.buffer,this._offset,this._raw.byteLength-this._cursor.offset);break;case 1:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.largesize);break;default:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.size)}this._incomplete||(this._boxProcessors[this.type]&&this._boxProcessors[this.type].call(this),this._boxContainers.indexOf(this.type)!==-1?this._parseContainerBox():this._data=this._readData())},ISOBox.prototype._parseFullBox=function(){this.version=this._readUint(8),this.flags=this._readUint(24)},ISOBox.prototype._parseContainerBox=function(){for(this.boxes=[];this._cursor.offset-this._raw.byteOffset<this._raw.byteLength;)this.boxes.push(ISOBox.parse(this))},ISOBox.prototype.append=function(a,b){ISOBoxer.Utils.appendBox(this,a,b)},ISOBox.prototype.getLength=function(){if(this._parsing=!1,this._rawo=null,this.size=0,this._procField("size","uint",32),this._procField("type","string",4),1===this.size&&this._procField("largesize","uint",64),"uuid"===this.type&&this._procFieldArray("usertype",16,"uint",8),this._boxProcessors[this.type]&&this._boxProcessors[this.type].call(this),this._boxContainers.indexOf(this.type)!==-1)for(var a=0;a<this.boxes.length;a++)this.size+=this.boxes[a].getLength();return this._data&&this._writeData(this._data),this.size},ISOBox.prototype.write=function(){switch(this._parsing=!1,this._cursor.offset=this._parent._cursor.offset,this.size){case 0:this._rawo=new DataView(this._parent._rawo.buffer,this._cursor.offset,this.parent._rawo.byteLength-this._cursor.offset);break;case 1:this._rawo=new DataView(this._parent._rawo.buffer,this._cursor.offset,this.largesize);break;default:this._rawo=new DataView(this._parent._rawo.buffer,this._cursor.offset,this.size)}if(this._procField("size","uint",32),this._procField("type","string",4),1===this.size&&this._procField("largesize","uint",64),"uuid"===this.type&&this._procFieldArray("usertype",16,"uint",8),this._boxProcessors[this.type]&&this._boxProcessors[this.type].call(this),this._boxContainers.indexOf(this.type)!==-1)for(var a=0;a<this.boxes.length;a++)this.boxes[a].write();return this._data&&this._writeData(this._data),this._parent._cursor.offset+=this.size,this.size},ISOBox.prototype._writeInt=function(a,b){if(this._rawo){var c=this._cursor.offset-this._rawo.byteOffset;switch(a){case 8:this._rawo.setInt8(c,b);break;case 16:this._rawo.setInt16(c,b);break;case 32:this._rawo.setInt32(c,b);break;case 64:var d=Math.round(b/Math.pow(2,32)),e=b-d*Math.pow(2,32);this._rawo.setUint32(c,d),this._rawo.setUint32(c+4,e)}this._cursor.offset+=a>>3}else this.size+=a>>3},ISOBox.prototype._writeUint=function(a,b){if(this._rawo){var c,d,e=this._cursor.offset-this._rawo.byteOffset;switch(a){case 8:this._rawo.setUint8(e,b);break;case 16:this._rawo.setUint16(e,b);break;case 24:c=(16776960&b)>>8,d=255&b,this._rawo.setUint16(e,c),this._rawo.setUint8(e+2,d);break;case 32:this._rawo.setUint32(e,b);break;case 64:c=Math.round(b/Math.pow(2,32)),d=b-c*Math.pow(2,32),this._rawo.setUint32(e,c),this._rawo.setUint32(e+4,d)}this._cursor.offset+=a>>3}else this.size+=a>>3},ISOBox.prototype._writeString=function(a,b){for(var c=0;c<a;c++)this._writeUint(8,b.charCodeAt(c))},ISOBox.prototype._writeTerminatedString=function(a){if(0!==a.length){for(var b=0;b<a.length;b++)this._writeUint(8,a.charCodeAt(b));this._writeUint(8,0)}},ISOBox.prototype._writeTemplate=function(a,b){var c=Math.round(b),d=(b-c)*Math.pow(2,a/2);this._writeUint(a/2,c),this._writeUint(a/2,d)},ISOBox.prototype._writeData=function(a){if(a instanceof Array&&(a=new DataView(Uint8Array.from(a).buffer)),a instanceof Uint8Array&&(a=new DataView(a.buffer)),this._rawo){for(var b=this._cursor.offset-this._rawo.byteOffset,c=0;c<a.byteLength;c++)this._rawo.setUint8(b+c,a.getUint8(c));this._cursor.offset+=a.byteLength}else this.size+=a.byteLength},ISOBox.prototype._writeUTF8String=function(a){var b=ISOBoxer.Utils.utf8ToByteArray(a);if(this._rawo)for(var c=new DataView(this._rawo.buffer,this._cursor.offset,b.length),d=0;d<b.length;d++)c.setUint8(d,b[d]);else this.size+=b.length},ISOBox.prototype._writeField=function(a,b,c){switch(a){case"uint":this._writeUint(b,c);break;case"int":this._writeInt(b,c);break;case"template":this._writeTemplate(b,c);break;case"string":b==-1?this._writeTerminatedString(c):this._writeString(b,c);break;case"data":this._writeData(c);break;case"utf8":this._writeUTF8String(c)}},ISOBox.prototype._boxProcessors.avc1=ISOBox.prototype._boxProcessors.encv=function(){this._procFieldArray("reserved1",6,"uint",8),this._procField("data_reference_index","uint",16),this._procField("pre_defined1","uint",16),this._procField("reserved2","uint",16),this._procFieldArray("pre_defined2",3,"uint",32),this._procField("width","uint",16),this._procField("height","uint",16),this._procField("horizresolution","template",32),this._procField("vertresolution","template",32),this._procField("reserved3","uint",32),this._procField("frame_count","uint",16),this._procFieldArray("compressorname",32,"uint",8),this._procField("depth","uint",16),this._procField("pre_defined3","int",16),this._procField("config","data",-1)},ISOBox.prototype._boxProcessors.dref=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procSubBoxes("entries",this.entry_count)},ISOBox.prototype._boxProcessors.elst=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procEntries("entries",this.entry_count,function(a){this._procEntryField(a,"segment_duration","uint",1===this.version?64:32),this._procEntryField(a,"media_time","int",1===this.version?64:32),this._procEntryField(a,"media_rate_integer","int",16),this._procEntryField(a,"media_rate_fraction","int",16)})},ISOBox.prototype._boxProcessors.emsg=function(){this._procFullBox(),this._procField("scheme_id_uri","string",-1),this._procField("value","string",-1),this._procField("timescale","uint",32),this._procField("presentation_time_delta","uint",32),this._procField("event_duration","uint",32),this._procField("id","uint",32),this._procField("message_data","data",-1)},ISOBox.prototype._boxProcessors.free=ISOBox.prototype._boxProcessors.skip=function(){this._procField("data","data",-1)},ISOBox.prototype._boxProcessors.frma=function(){this._procField("data_format","uint",32)},ISOBox.prototype._boxProcessors.ftyp=ISOBox.prototype._boxProcessors.styp=function(){this._procField("major_brand","string",4),this._procField("minor_version","uint",32);var a=-1;this._parsing&&(a=(this._raw.byteLength-(this._cursor.offset-this._raw.byteOffset))/4),this._procFieldArray("compatible_brands",a,"string",4)},ISOBox.prototype._boxProcessors.hdlr=function(){this._procFullBox(),this._procField("pre_defined","uint",32),this._procField("handler_type","string",4),this._procFieldArray("reserved",3,"uint",32),this._procField("name","string",-1)},ISOBox.prototype._boxProcessors.mdat=function(){this._procField("data","data",-1)},ISOBox.prototype._boxProcessors.mdhd=function(){this._procFullBox(),this._procField("creation_time","uint",1==this.version?64:32),this._procField("modification_time","uint",1==this.version?64:32),this._procField("timescale","uint",32),this._procField("duration","uint",1==this.version?64:32),this._parsing||"string"!=typeof this.language||(this.language=this.language.charCodeAt(0)-96<<10|this.language.charCodeAt(1)-96<<5|this.language.charCodeAt(2)-96),this._procField("language","uint",16),this._parsing&&(this.language=String.fromCharCode((this.language>>10&31)+96,(this.language>>5&31)+96,(31&this.language)+96)),this._procField("pre_defined","uint",16)},ISOBox.prototype._boxProcessors.mehd=function(){this._procFullBox(),this._procField("fragment_duration","uint",1==this.version?64:32)},ISOBox.prototype._boxProcessors.mfhd=function(){this._procFullBox(),this._procField("sequence_number","uint",32)},ISOBox.prototype._boxProcessors.mfro=function(){this._procFullBox(),this._procField("mfra_size","uint",32)},ISOBox.prototype._boxProcessors.mp4a=ISOBox.prototype._boxProcessors.enca=function(){this._procFieldArray("reserved1",6,"uint",8),this._procField("data_reference_index","uint",16),this._procFieldArray("reserved2",2,"uint",32),this._procField("channelcount","uint",16),this._procField("samplesize","uint",16),this._procField("pre_defined","uint",16),this._procField("reserved3","uint",16),this._procField("samplerate","template",32),this._procField("esds","data",-1)},ISOBox.prototype._boxProcessors.mvhd=function(){this._procFullBox(),this._procField("creation_time","uint",1==this.version?64:32),this._procField("modification_time","uint",1==this.version?64:32),this._procField("timescale","uint",32),this._procField("duration","uint",1==this.version?64:32),this._procField("rate","template",32),this._procField("volume","template",16),this._procField("reserved1","uint",16),this._procFieldArray("reserved2",2,"uint",32),this._procFieldArray("matrix",9,"template",32),this._procFieldArray("pre_defined",6,"uint",32),this._procField("next_track_ID","uint",32)},ISOBox.prototype._boxProcessors.payl=function(){this._procField("cue_text","utf8")},ISOBox.prototype._boxProcessors.pssh=function(){this._procFullBox(),this._procFieldArray("SystemID",16,"uint",8),this._procField("DataSize","uint",32),this._procFieldArray("Data",this.DataSize,"uint",8)},ISOBox.prototype._boxProcessors.schm=function(){this._procFullBox(),this._procField("scheme_type","uint",32),this._procField("scheme_version","uint",32),1&this.flags&&this._procField("scheme_uri","string",-1)},ISOBox.prototype._boxProcessors.sdtp=function(){this._procFullBox();var a=-1;this._parsing&&(a=this._raw.byteLength-(this._cursor.offset-this._raw.byteOffset)),this._procFieldArray("sample_dependency_table",a,"uint",8)},ISOBox.prototype._boxProcessors.sidx=function(){this._procFullBox(),this._procField("reference_ID","uint",32),this._procField("timescale","uint",32),this._procField("earliest_presentation_time","uint",1==this.version?64:32),this._procField("first_offset","uint",1==this.version?64:32),this._procField("reserved","uint",16),this._procField("reference_count","uint",16),this._procEntries("references",this.reference_count,function(a){this._parsing||(a.reference=(1&a.reference_type)<<31,a.reference|=2147483647&a.referenced_size,a.sap=(1&a.starts_with_SAP)<<31,a.sap|=(3&a.SAP_type)<<28,a.sap|=268435455&a.SAP_delta_time),this._procEntryField(a,"reference","uint",32),this._procEntryField(a,"subsegment_duration","uint",32),this._procEntryField(a,"sap","uint",32),this._parsing&&(a.reference_type=a.reference>>31&1,a.referenced_size=2147483647&a.reference,a.starts_with_SAP=a.sap>>31&1,a.SAP_type=a.sap>>28&7,a.SAP_delta_time=268435455&a.sap)})},ISOBox.prototype._boxProcessors.smhd=function(){this._procFullBox(),this._procField("balance","uint",16),this._procField("reserved","uint",16)},ISOBox.prototype._boxProcessors.ssix=function(){this._procFullBox(),this._procField("subsegment_count","uint",32),this._procEntries("subsegments",this.subsegment_count,function(a){this._procEntryField(a,"ranges_count","uint",32),this._procSubEntries(a,"ranges",a.ranges_count,function(a){this._procEntryField(a,"level","uint",8),this._procEntryField(a,"range_size","uint",24)})})},ISOBox.prototype._boxProcessors.stsd=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procSubBoxes("entries",this.entry_count)},ISOBox.prototype._boxProcessors.subs=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procEntries("entries",this.entry_count,function(a){this._procEntryField(a,"sample_delta","uint",32),this._procEntryField(a,"subsample_count","uint",16),this._procSubEntries(a,"subsamples",a.subsample_count,function(a){this._procEntryField(a,"subsample_size","uint",1===this.version?32:16),this._procEntryField(a,"subsample_priority","uint",8),this._procEntryField(a,"discardable","uint",8),this._procEntryField(a,"codec_specific_parameters","uint",32)})})},ISOBox.prototype._boxProcessors.tenc=function(){this._procFullBox(),this._procField("default_IsEncrypted","uint",24),this._procField("default_IV_size","uint",8),this._procFieldArray("default_KID",16,"uint",8)},ISOBox.prototype._boxProcessors.tfdt=function(){this._procFullBox(),this._procField("baseMediaDecodeTime","uint",1==this.version?64:32)},ISOBox.prototype._boxProcessors.tfhd=function(){this._procFullBox(),this._procField("track_ID","uint",32),1&this.flags&&this._procField("base_data_offset","uint",64),2&this.flags&&this._procField("sample_description_offset","uint",32),8&this.flags&&this._procField("default_sample_duration","uint",32),16&this.flags&&this._procField("default_sample_size","uint",32),32&this.flags&&this._procField("default_sample_flags","uint",32)},ISOBox.prototype._boxProcessors.tfra=function(){this._procFullBox(),this._procField("track_ID","uint",32),this._parsing||(this.reserved=0,this.reserved|=(48&this.length_size_of_traf_num)<<4,this.reserved|=(12&this.length_size_of_trun_num)<<2,this.reserved|=3&this.length_size_of_sample_num),this._procField("reserved","uint",32),this._parsing&&(this.length_size_of_traf_num=(48&this.reserved)>>4,this.length_size_of_trun_num=(12&this.reserved)>>2,this.length_size_of_sample_num=3&this.reserved),this._procField("number_of_entry","uint",32),this._procEntries("entries",this.number_of_entry,function(a){this._procEntryField(a,"time","uint",1===this.version?64:32),this._procEntryField(a,"moof_offset","uint",1===this.version?64:32),this._procEntryField(a,"traf_number","uint",8*(this.length_size_of_traf_num+1)),this._procEntryField(a,"trun_number","uint",8*(this.length_size_of_trun_num+1)),this._procEntryField(a,"sample_number","uint",8*(this.length_size_of_sample_num+1))})},ISOBox.prototype._boxProcessors.tkhd=function(){this._procFullBox(),this._procField("creation_time","uint",1==this.version?64:32),this._procField("modification_time","uint",1==this.version?64:32),this._procField("track_ID","uint",32),this._procField("reserved1","uint",32),this._procField("duration","uint",1==this.version?64:32),this._procFieldArray("reserved2",2,"uint",32),this._procField("layer","uint",16),this._procField("alternate_group","uint",16),this._procField("volume","template",16),this._procField("reserved3","uint",16),this._procFieldArray("matrix",9,"template",32),this._procField("width","template",32),this._procField("height","template",32)},ISOBox.prototype._boxProcessors.trex=function(){this._procFullBox(),this._procField("track_ID","uint",32),this._procField("default_sample_description_index","uint",32),this._procField("default_sample_duration","uint",32),this._procField("default_sample_size","uint",32),this._procField("default_sample_flags","uint",32)},ISOBox.prototype._boxProcessors.trun=function(){this._procFullBox(),this._procField("sample_count","uint",32),1&this.flags&&this._procField("data_offset","int",32),4&this.flags&&this._procField("first_sample_flags","uint",32),this._procEntries("samples",this.sample_count,function(a){256&this.flags&&this._procEntryField(a,"sample_duration","uint",32),512&this.flags&&this._procEntryField(a,"sample_size","uint",32),1024&this.flags&&this._procEntryField(a,"sample_flags","uint",32),2048&this.flags&&this._procEntryField(a,"sample_composition_time_offset",1===this.version?"int":"uint",32)})},ISOBox.prototype._boxProcessors["url "]=ISOBox.prototype._boxProcessors["urn "]=function(){this._procFullBox(),"urn "===this.type&&this._procField("name","string",-1),this._procField("location","string",-1)},ISOBox.prototype._boxProcessors.vlab=function(){this._procField("source_label","utf8")},ISOBox.prototype._boxProcessors.vmhd=function(){this._procFullBox(),this._procField("graphicsmode","uint",16),this._procFieldArray("opcolor",3,"uint",16)},ISOBox.prototype._boxProcessors.vttC=function(){this._procField("config","utf8")},ISOBox.prototype._boxProcessors.vtte=function(){};
module.exports = function(grunt) {
var banner = '/*! <%= pkg.name %> v<%= pkg.version %> <%= licenseUrl %> */\n';
var boxes = grunt.option('boxes');
function includeWriteFunctions() {
return (grunt.option('write') !== false);
}
function getDestinationFile() {
return (boxes ? 'dist/iso_boxer.' + boxes + '.js' : 'dist/iso_boxer.js');
}
function getDestinationMinifiedFile() {
if (boxes) {
var minifiedFile = 'dist/iso_boxer.' + boxes + '.min.js';
return [{ src: '<%= concat.dist.dest %>', dest: minifiedFile }]
return [{ src: '<%= concat.dist.dest %>', dest: minifiedFile }];
}
return { 'dist/iso_boxer.min.js': ['<%= concat.dist.dest %>'] }
return { 'dist/iso_boxer.min.js': ['<%= concat.dist.dest %>'] };
}
function getSourceFiles() {
var defaultList = ['src/iso_boxer.js', 'src/cursor.js', 'src/iso_file.js', 'src/iso_box.js'];
if (!boxes) {
return defaultList.concat(['src/parsers/*.js']);
return defaultList.concat(['src/processors/*.js']);
}
var parsers = grunt.file.expand('src/parsers/*.js');
var processors = grunt.file.expand('src/processors/*.js');
var boxList = boxes.split(',');
var files = [];
boxList.forEach(function(box) {
var parser = getBoxParserForBox(parsers, box);
if (parser && files.indexOf(parser) == -1) files.push(parser);
})
var processor = getBoxProcessorForBox(processors, box);
if (processor && files.indexOf(processor) == -1) files.push(processor);
});
return defaultList.concat(files);
}
function getBoxParserForBox(parsers, box) {
function getBoxProcessorForBox(processors, box) {
var result;
parsers.forEach(function(parser) {
var providers = parser.split('/').pop().replace('.js', '').split(',')
if (providers.indexOf(box) != -1) result = parser;
})
processors.forEach(function(processor) {
var providers = processor.split('/').pop().replace('.js', '').split(',');
if (providers.indexOf(box) != -1) result = processor;
});
return result;
}
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
licenseUrl: 'https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt',
licenseUrl: 'https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt',
preprocess: {
options: {
context : {
WRITE: includeWriteFunctions()
}
},
inline : {
src : [ getDestinationFile() ],
options: {
inline : true,
context : {
WRITE: includeWriteFunctions()
}
}
}
},
concat: {

@@ -71,4 +91,5 @@ options: {

grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-preprocess');
grunt.registerTask('default', ['concat', 'uglify']);
grunt.registerTask('default', ['concat', 'preprocess', 'uglify']);
};
{
"name": "codem-isoboxer",
"version": "0.2.10",
"version": "0.3.0",
"description": "A lightweight JavaScript MP4 (MPEG-4, ISOBMFF) file/box parser.",

@@ -28,3 +28,5 @@ "keywords": [

"grunt-contrib-watch": "^1.0.0",
"grunt-preprocess": "^5.1.0",
"jasmine-node": "^1.14.5",
"arraybuffer-equal": "^1.0.4",
"jshint": "^2.9.4"

@@ -31,0 +33,0 @@ },

@@ -35,3 +35,3 @@ # codem-isoboxer

* moov / moof
* mp4a
* mp4a / enca
* mvex

@@ -68,3 +68,3 @@ * mvhd / mfhd

* avc1
* avc1 / encv

@@ -71,0 +71,0 @@ Support for more boxes can easily be added by adding additional box parsers in `src/parsers`. Some utility functions are included to help with reading the various ISOBMFF data types from the raw file. Also, see the [Box Support page on the Wiki](https://github.com/madebyhiro/codem-isoboxer/wiki/Box-support) for a full list.

ISOBoxer.Cursor = function(initialOffset) {
this.offset = (typeof initialOffset == 'undefined' ? 0 : initialOffset);
};
};

@@ -16,13 +16,151 @@ var ISOBox = function() {

ISOBox.create = function(type) {
var newBox = new ISOBox();
newBox.type = type;
newBox.boxes = [];
return newBox;
};
ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca'];
ISOBox.prototype._boxProcessors = {};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Generic read/write functions
ISOBox.prototype._procField = function (name, type, size) {
if (this._parsing) {
this[name] = this._readField(type, size);
}
// @ifdef WRITE
else {
this._writeField(type, size, this[name]);
}
// @endif
};
ISOBox.prototype._procFieldArray = function (name, length, type, size) {
var i;
if (this._parsing) {
this[name] = [];
for (i = 0; i < length; i++) {
this[name][i] = this._readField(type, size);
}
}
// @ifdef WRITE
else {
for (i = 0; i < this[name].length; i++) {
this._writeField(type, size, this[name][i]);
}
}
// @endif
};
ISOBox.prototype._procFullBox = function() {
this._procField('version', 'uint', 8);
this._procField('flags', 'uint', 24);
};
ISOBox.prototype._procEntries = function(name, length, fn) {
var i;
if (this._parsing) {
this[name] = [];
for (i = 0; i < length; i++) {
this[name].push({});
fn.call(this, this[name][i]);
}
}
// @ifdef WRITE
else {
for (i = 0; i < length; i++) {
fn.call(this, this[name][i]);
}
}
// @endif
};
ISOBox.prototype._procSubEntries = function(entry, name, length, fn) {
var i;
if (this._parsing) {
entry[name] = [];
for (i = 0; i < length; i++) {
entry[name].push({});
fn.call(this, entry[name][i]);
}
}
// @ifdef WRITE
else {
for (i = 0; i < length; i++) {
fn.call(this, entry[name][i]);
}
}
// @endif
};
ISOBox.prototype._procEntryField = function (entry, name, type, size) {
if (this._parsing) {
entry[name] = this._readField(type, size);
}
// @ifdef WRITE
else {
this._writeField(type, size, entry[name]);
}
// @endif
};
ISOBox.prototype._procSubBoxes = function(name, length) {
var i;
if (this._parsing) {
this[name] = [];
for (i = 0; i < length; i++) {
this[name].push(ISOBox.parse(this));
}
}
// @ifdef WRITE
else {
for (i = 0; i < length; i++) {
if (this._rawo) {
this[name][i].write();
} else {
this.size += this[name][i].getLength();
}
}
}
// @endif
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Read/parse functions
ISOBox.prototype._readField = function(type, size) {
switch (type) {
case 'uint':
return this._readUint(size);
case 'int':
return this._readInt(size);
case 'template':
return this._readTemplate(size);
case 'string':
return (size === -1) ? this._readTerminatedString() : this._readString(size);
case 'data':
return this._readData(size);
case 'utf8':
return this._readUTF8String();
default:
return -1;
}
};
ISOBox.prototype._readInt = function(size) {
var result = null;
var result = null,
offset = this._cursor.offset - this._raw.byteOffset;
switch(size) {
case 8:
result = this._raw.getInt8(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getInt8(offset);
break;
case 16:
result = this._raw.getInt16(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getInt16(offset);
break;
case 32:
result = this._raw.getInt32(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getInt32(offset);
break;

@@ -32,4 +170,4 @@ case 64:

// This will give unexpected results for integers >= 2^53
var s1 = this._raw.getInt32(this._cursor.offset - this._raw.byteOffset);
var s2 = this._raw.getInt32(this._cursor.offset - this._raw.byteOffset + 4);
var s1 = this._raw.getInt32(offset);
var s2 = this._raw.getInt32(offset + 4);
result = (s1 * Math.pow(2,32)) + s2;

@@ -44,17 +182,18 @@ break;

var result = null,
offset = this._cursor.offset - this._raw.byteOffset,
s1, s2;
switch(size) {
case 8:
result = this._raw.getUint8(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getUint8(offset);
break;
case 16:
result = this._raw.getUint16(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getUint16(offset);
break;
case 24:
s1 = this._raw.getUint16(this._cursor.offset - this._raw.byteOffset);
s2 = this._raw.getUint8(this._cursor.offset - this._raw.byteOffset + 2);
s1 = this._raw.getUint16(offset);
s2 = this._raw.getUint8(offset + 2);
result = (s1 << 8) + s2;
break;
case 32:
result = this._raw.getUint32(this._cursor.offset - this._raw.byteOffset);
result = this._raw.getUint32(offset);
break;

@@ -64,4 +203,4 @@ case 64:

// This will give unexpected results for integers >= 2^53
s1 = this._raw.getUint32(this._cursor.offset - this._raw.byteOffset);
s2 = this._raw.getUint32(this._cursor.offset - this._raw.byteOffset + 4);
s1 = this._raw.getUint32(offset);
s2 = this._raw.getUint32(offset + 4);
result = (s1 * Math.pow(2,32)) + s2;

@@ -83,2 +222,8 @@ break;

ISOBox.prototype._readTemplate = function(size) {
var pre = this._readUint(size / 2);
var post = this._readUint(size / 2);
return pre + (post / Math.pow(2, size / 2));
};
ISOBox.prototype._readTerminatedString = function() {

@@ -94,8 +239,2 @@ var str = '';

ISOBox.prototype._readTemplate = function(size) {
var pre = this._readUint(size / 2);
var post = this._readUint(size / 2);
return pre + (post / Math.pow(2, size / 2));
};
ISOBox.prototype._readData = function(size) {

@@ -108,3 +247,9 @@ var length = (size > 0) ? size : (this._raw.byteLength - (this._cursor.offset - this._offset));

ISOBox.prototype._readUTF8String = function() {
var data = this._readData();
return ISOBoxer.Utils.dataViewToString(data);
};
ISOBox.prototype._parseBox = function() {
this._parsing = true;
this._cursor.offset = this._offset;

@@ -118,7 +263,7 @@

this.size = this._readUint(32);
this.type = this._readString(4);
this._procField('size', 'uint', 32);
this._procField('type', 'string', 4);
if (this.size == 1) { this.largesize = this._readUint(64); }
if (this.type == 'uuid') { this.usertype = this._readString(16); }
if (this.size === 1) { this._procField('largesize', 'uint', 64); }
if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); }

@@ -148,6 +293,10 @@ switch(this.size) {

if (!this._incomplete) {
if (this._boxProcessors[this.type]) {
this._boxProcessors[this.type].call(this);
}
if (this._boxContainers.indexOf(this.type) !== -1) {
this._parseContainerBox();
} else if (this._boxParsers[this.type]) {
this._boxParsers[this.type].call(this);
} else{
// Unknown box => read and store box content
this._data = this._readData();
}

@@ -169,4 +318,223 @@ }

ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc'];
// @ifdef WRITE
///////////////////////////////////////////////////////////////////////////////////////////////////
// Write functions
ISOBox.prototype._boxParsers = {};
ISOBox.prototype.append = function(box, pos) {
ISOBoxer.Utils.appendBox(this, box, pos);
};
ISOBox.prototype.getLength = function() {
this._parsing = false;
this._rawo = null;
this.size = 0;
this._procField('size', 'uint', 32);
this._procField('type', 'string', 4);
if (this.size === 1) { this._procField('largesize', 'uint', 64); }
if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); }
if (this._boxProcessors[this.type]) {
this._boxProcessors[this.type].call(this);
}
if (this._boxContainers.indexOf(this.type) !== -1) {
for (var i = 0; i < this.boxes.length; i++) {
this.size += this.boxes[i].getLength();
}
}
if (this._data) {
this._writeData(this._data);
}
return this.size;
};
ISOBox.prototype.write = function() {
this._parsing = false;
this._cursor.offset = this._parent._cursor.offset;
switch(this.size) {
case 0:
this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, (this.parent._rawo.byteLength - this._cursor.offset));
break;
case 1:
this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.largesize);
break;
default:
this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.size);
}
this._procField('size', 'uint', 32);
this._procField('type', 'string', 4);
if (this.size === 1) { this._procField('largesize', 'uint', 64); }
if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); }
if (this._boxProcessors[this.type]) {
this._boxProcessors[this.type].call(this);
}
if (this._boxContainers.indexOf(this.type) !== -1) {
for (var i = 0; i < this.boxes.length; i++) {
this.boxes[i].write();
}
}
if (this._data) {
this._writeData(this._data);
}
this._parent._cursor.offset += this.size;
return this.size;
};
ISOBox.prototype._writeInt = function(size, value) {
if (this._rawo) {
var offset = this._cursor.offset - this._rawo.byteOffset;
switch(size) {
case 8:
this._rawo.setInt8(offset, value);
break;
case 16:
this._rawo.setInt16(offset, value);
break;
case 32:
this._rawo.setInt32(offset, value);
break;
case 64:
// Warning: JavaScript cannot handle 64-bit integers natively.
// This will give unexpected results for integers >= 2^53
var s1 = Math.round(value / Math.pow(2,32));
var s2 = value - (s1 * Math.pow(2,32));
this._rawo.setUint32(offset, s1);
this._rawo.setUint32(offset + 4, s2);
break;
}
this._cursor.offset += (size >> 3);
} else {
this.size += (size >> 3);
}
};
ISOBox.prototype._writeUint = function(size, value) {
if (this._rawo) {
var offset = this._cursor.offset - this._rawo.byteOffset,
s1, s2;
switch(size) {
case 8:
this._rawo.setUint8(offset, value);
break;
case 16:
this._rawo.setUint16(offset, value);
break;
case 24:
s1 = (value & 0xFFFF00) >> 8;
s2 = (value & 0x0000FF);
this._rawo.setUint16(offset, s1);
this._rawo.setUint8(offset + 2, s2);
break;
case 32:
this._rawo.setUint32(offset, value);
break;
case 64:
// Warning: JavaScript cannot handle 64-bit integers natively.
// This will give unexpected results for integers >= 2^53
s1 = Math.round(value / Math.pow(2,32));
s2 = value - (s1 * Math.pow(2,32));
this._rawo.setUint32(offset, s1);
this._rawo.setUint32(offset + 4, s2);
break;
}
this._cursor.offset += (size >> 3);
} else {
this.size += (size >> 3);
}
};
ISOBox.prototype._writeString = function(size, str) {
for (var c = 0; c < size; c++) {
this._writeUint(8, str.charCodeAt(c));
}
};
ISOBox.prototype._writeTerminatedString = function(str) {
if (str.length === 0) {
return;
}
for (var c = 0; c < str.length; c++) {
this._writeUint(8, str.charCodeAt(c));
}
this._writeUint(8, 0);
};
ISOBox.prototype._writeTemplate = function(size, value) {
var pre = Math.round(value);
var post = (value - pre) * Math.pow(2, size / 2);
this._writeUint(size / 2, pre);
this._writeUint(size / 2, post);
};
ISOBox.prototype._writeData = function(data) {
if (data instanceof Array) {
data = new DataView(Uint8Array.from(data).buffer);
}
if (data instanceof Uint8Array) {
data = new DataView(data.buffer);
}
if (this._rawo) {
var offset = this._cursor.offset - this._rawo.byteOffset;
for (var i = 0; i < data.byteLength; i++) {
this._rawo.setUint8(offset + i, data.getUint8(i));
}
this._cursor.offset += data.byteLength;
} else {
this.size += data.byteLength;
}
};
ISOBox.prototype._writeUTF8String = function(string) {
var u = ISOBoxer.Utils.utf8ToByteArray(string);
if (this._rawo) {
var dataView = new DataView(this._rawo.buffer, this._cursor.offset, u.length);
for (var i = 0; i < u.length; i++) {
dataView.setUint8(i, u[i]);
}
} else {
this.size += u.length;
}
};
ISOBox.prototype._writeField = function(type, size, value) {
switch (type) {
case 'uint':
this._writeUint(size, value);
break;
case 'int':
this._writeInt(size, value);
break;
case 'template':
this._writeTemplate(size, value);
break;
case 'string':
if (size == -1) {
this._writeTerminatedString(value);
} else {
this._writeString(size, value);
}
break;
case 'data':
this._writeData(value);
break;
case 'utf8':
this._writeUTF8String(value);
break;
default:
break;
}
};
// @endif

@@ -7,9 +7,32 @@ var ISOBoxer = {};

ISOBoxer.addBoxParser = function(type, parser) {
ISOBoxer.addBoxProcessor = function(type, parser) {
if (typeof type !== 'string' || typeof parser !== 'function') {
return;
}
ISOBox.prototype._boxParsers[type] = parser;
ISOBox.prototype._boxProcessors[type] = parser;
};
// @ifdef WRITE
ISOBoxer.createFile = function() {
return new ISOFile();
};
// See ISOBoxer.append() for 'pos' parameter syntax
ISOBoxer.createBox = function(type, parent, pos) {
var newBox = ISOBox.create(type);
if (parent) {
parent.append(newBox, pos);
}
return newBox;
};
// See ISOBoxer.append() for 'pos' parameter syntax
ISOBoxer.createFullBox = function(type, parent, pos) {
var newBox = ISOBoxer.createBox(type, parent, pos);
newBox.version = 0;
newBox.flags = 0;
return newBox;
};
// @endif
ISOBoxer.Utils = {};

@@ -59,6 +82,89 @@ ISOBoxer.Utils.dataViewToString = function(dataView, encoding) {

// @ifdef WRITE
ISOBoxer.Utils.utf8ToByteArray = function(string) {
// Only UTF-8 encoding is supported by TextEncoder
var u, i;
if (typeof TextEncoder !== 'undefined') {
u = new TextEncoder().encode(string);
} else {
u = [];
for (i = 0; i < string.length; ++i) {
var c = string.charCodeAt(i);
if (c < 0x80) {
u.push(c);
} else if (c < 0x800) {
u.push(0xC0 | (c >> 6));
u.push(0x80 | (63 & c));
} else if (c < 0x10000) {
u.push(0xE0 | (c >> 12));
u.push(0x80 | (63 & (c >> 6)));
u.push(0x80 | (63 & c));
} else {
u.push(0xF0 | (c >> 18));
u.push(0x80 | (63 & (c >> 12)));
u.push(0x80 | (63 & (c >> 6)));
u.push(0x80 | (63 & c));
}
}
}
return u;
};
// Method to append a box in the list of child boxes
// The 'pos' parameter can be either:
// - (number) a position index at which to insert the new box
// - (string) the type of the box after which to insert the new box
// - (object) the box after which to insert the new box
ISOBoxer.Utils.appendBox = function(parent, box, pos) {
box._offset = parent._cursor.offset;
box._root = (parent._root ? parent._root : parent);
box._raw = parent._raw;
box._parent = parent;
if (pos === -1) {
// The new box is a sub-box of the parent but not added in boxes array,
// for example when the new box is set as an entry (see dref and stsd for example)
return;
}
if (pos === undefined || pos === null) {
parent.boxes.push(box);
return;
}
var index = -1,
type;
if (typeof pos === "number") {
index = pos;
} else {
if (typeof pos === "string") {
type = pos;
} else if (typeof pos === "object" && pos.type) {
type = pos.type;
} else {
parent.boxes.push(box);
return;
}
for (var i = 0; i < parent.boxes.length; i++) {
if (type === parent.boxes[i].type) {
index = i + 1;
break;
}
}
}
parent.boxes.splice(index, 0, box);
};
// @endif
if (typeof exports !== 'undefined') {
exports.parseBuffer = ISOBoxer.parseBuffer;
exports.addBoxParser = ISOBoxer.addBoxParser;
exports.Utils = ISOBoxer.Utils;
}
exports.parseBuffer = ISOBoxer.parseBuffer;
exports.addBoxProcessor = ISOBoxer.addBoxProcessor;
// @ifdef WRITE
exports.createFile = ISOBoxer.createFile;
exports.createBox = ISOBoxer.createBox;
exports.createFullBox = ISOBoxer.createFullBox;
// @endif
exports.Utils = ISOBoxer.Utils;
}
var ISOFile = function(arrayBuffer) {
this._raw = new DataView(arrayBuffer);
this._cursor = new ISOBoxer.Cursor();
this.boxes = [];
if (arrayBuffer) {
this._raw = new DataView(arrayBuffer);
}
};

@@ -38,2 +40,51 @@

}
};
};
// @ifdef WRITE
ISOFile.prototype.write = function() {
var length = 0,
i;
for (i = 0; i < this.boxes.length; i++) {
length += this.boxes[i].getLength(false);
}
var bytes = new Uint8Array(length);
this._rawo = new DataView(bytes.buffer);
this.bytes = bytes;
this._cursor.offset = 0;
for (i = 0; i < this.boxes.length; i++) {
this.boxes[i].write();
}
return bytes.buffer;
};
ISOFile.prototype.append = function(box, pos) {
ISOBoxer.Utils.appendBox(this, box, pos);
};
/*ISOFile.prototype.create = function(type, parent, previousType) {
var newBox = ISOBox.create(type, parent),
inserted = false;
if (previousType) {
for (var i = 0; i < parent.boxes.length; i++) {
if (previousType === parent.boxes[i].type) {
parent.boxes.splice(i + 1, 0, newBox);
inserted = true;
break;
}
}
}
if (!inserted) {
parent.boxes.push(newBox);
}
return newBox;
};*/
// @endif

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc