codem-isoboxer
Advanced tools
Comparing version 0.1.1 to 0.2.0
@@ -0,1 +1,5 @@ | ||
## codem-isoboxer 0.2.0 (2015/07/29) ## | ||
* Added support for modular builds (#1). See README (Advanced build options) for details. | ||
## codem-isoboxer 0.1.1 (2015/07/06) ## | ||
@@ -2,0 +6,0 @@ |
/*! codem-isoboxer v0.1.1 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */ | ||
var ISOBoxer = ISOBoxer || {}; | ||
var ISOBoxer = {}; | ||
ISOBoxer.parseBuffer = function(arrayBuffer) { | ||
return new ISOFile(arrayBuffer).parse(); | ||
}; | ||
ISOBoxer.Utils = {}; | ||
ISOBoxer.Utils.dataViewToString = function(dataView, encoding) { | ||
if (typeof TextDecoder !== 'undefined') { | ||
return new TextDecoder(encoding || 'utf-8').decode(dataView); | ||
} | ||
var str = ''; | ||
for (var i=0; i<dataView.byteLength; i++) { | ||
str += String.fromCharCode(dataView.getUint8(i)); | ||
} | ||
return str; | ||
}; | ||
if (typeof exports !== 'undefined') { | ||
exports.parseBuffer = ISOBoxer.parseBuffer; | ||
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 = []; | ||
} | ||
ISOFile.prototype.fetch = function(type) { | ||
var result = this.fetchAll(type, true); | ||
return (result.length ? result[0] : null); | ||
} | ||
ISOFile.prototype.fetchAll = function(type, returnEarly) { | ||
var result = []; | ||
ISOFile._sweep.call(this, type, result, returnEarly); | ||
return result; | ||
} | ||
ISOFile.prototype.parse = function() { | ||
this._cursor.offset = 0; | ||
this.boxes = []; | ||
while (this._cursor.offset < this._raw.byteLength) { | ||
var box = ISOBox.parse(this); | ||
// Box could not be parsed | ||
if (typeof box.type === 'undefined') break; | ||
this.boxes.push(box); | ||
} | ||
return this; | ||
} | ||
ISOFile._sweep = function(type, result, returnEarly) { | ||
if (this.type && this.type == type) result.push(this); | ||
for (var box in this.boxes) { | ||
if (result.length && returnEarly) return; | ||
ISOFile._sweep.call(this.boxes[box], type, result, returnEarly); | ||
} | ||
}; | ||
var ISOBox = function() { | ||
@@ -138,4 +196,3 @@ this._cursor = new ISOBoxer.Cursor(); | ||
ISOBox.prototype._boxParsers = {}; | ||
ISOBox.prototype._boxParsers = {};; | ||
// Simple container boxes, all from ISO/IEC 14496-12:2012 | ||
@@ -152,4 +209,3 @@ [ | ||
} | ||
}) | ||
}); | ||
// ISO/IEC 23009-1:2014 - 5.10.3.3 Event Message Box | ||
@@ -165,9 +221,7 @@ ISOBox.prototype._boxParsers['emsg'] = function() { | ||
this.message_data = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset)); | ||
} | ||
}; | ||
// 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)); | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 4.3 File Type Box / 8.16.2 Segment Type Box | ||
@@ -182,4 +236,3 @@ ISOBox.prototype._boxParsers['ftyp'] = ISOBox.prototype._boxParsers['styp'] = function() { | ||
} | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 8.4.3 Handler Reference Box | ||
@@ -192,9 +245,7 @@ ISOBox.prototype._boxParsers['hdlr'] = function() { | ||
this.name = this._readTerminatedString() | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 8.1.1 Media Data Box | ||
ISOBox.prototype._boxParsers['mdat'] = function() { | ||
this.data = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset)); | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 8.4.2 Media Header Box | ||
@@ -222,4 +273,3 @@ ISOBox.prototype._boxParsers['mdhd'] = function() { | ||
this.pre_defined = this._readUint(16); | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 8.8.5 Movie Fragment Header Box | ||
@@ -229,4 +279,3 @@ ISOBox.prototype._boxParsers['mfhd'] = function() { | ||
this.sequence_number = this._readUint(32); | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 8.2.2 Movie Header Box | ||
@@ -261,4 +310,3 @@ ISOBox.prototype._boxParsers['mvhd'] = function() { | ||
this.next_track_ID = this._readUint(32); | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 8.16.3 Segment Index Box | ||
@@ -291,4 +339,3 @@ ISOBox.prototype._boxParsers['sidx'] = function() { | ||
} | ||
} | ||
}; | ||
// ISO/IEC 14496-12:2012 - 8.16.4 Subsegment Index Box | ||
@@ -313,4 +360,22 @@ ISOBox.prototype._boxParsers['ssix'] = function() { | ||
} | ||
} | ||
}; | ||
// 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.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:2012 - 8.3.2 Track Header Box | ||
@@ -348,25 +413,3 @@ ISOBox.prototype._boxParsers['tkhd'] = function() { | ||
this.height = this._readUint(32); | ||
} | ||
// 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.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:2012 - 8.8.8 Track Run Box | ||
@@ -395,62 +438,2 @@ // Note: the 'trun' box has a direct relation to the 'tfhd' box for defaults. | ||
} | ||
}; | ||
var ISOBoxer = ISOBoxer || {}; | ||
ISOBoxer.parseBuffer = function(arrayBuffer) { | ||
return new ISOFile(arrayBuffer).parse(); | ||
}; | ||
ISOBoxer.Utils = {}; | ||
ISOBoxer.Utils.dataViewToString = function(dataView, encoding) { | ||
if (typeof TextDecoder !== 'undefined') { | ||
return new TextDecoder(encoding || 'utf-8').decode(dataView); | ||
} | ||
var str = ''; | ||
for (var i=0; i<dataView.byteLength; i++) { | ||
str += String.fromCharCode(dataView.getUint8(i)); | ||
} | ||
return str; | ||
}; | ||
if (typeof exports !== 'undefined') { | ||
exports.parseBuffer = ISOBoxer.parseBuffer; | ||
exports.Utils = ISOBoxer.Utils; | ||
}; | ||
var ISOFile = function(arrayBuffer) { | ||
this._raw = new DataView(arrayBuffer); | ||
this._cursor = new ISOBoxer.Cursor(); | ||
this.boxes = []; | ||
} | ||
ISOFile.prototype.fetch = function(type) { | ||
var result = this.fetchAll(type, true); | ||
return (result.length ? result[0] : null); | ||
} | ||
ISOFile.prototype.fetchAll = function(type, returnEarly) { | ||
var result = []; | ||
ISOFile._sweep.call(this, type, result, returnEarly); | ||
return result; | ||
} | ||
ISOFile.prototype.parse = function() { | ||
this._cursor.offset = 0; | ||
this.boxes = []; | ||
while (this._cursor.offset < this._raw.byteLength) { | ||
var box = ISOBox.parse(this); | ||
// Box could not be parsed | ||
if (typeof box.type === 'undefined') break; | ||
this.boxes.push(box); | ||
} | ||
return this; | ||
} | ||
ISOFile._sweep = function(type, result, returnEarly) { | ||
if (this.type && this.type == type) result.push(this); | ||
for (var box in this.boxes) { | ||
if (result.length && returnEarly) return; | ||
ISOFile._sweep.call(this.boxes[box], type, result, returnEarly); | ||
} | ||
} |
/*! codem-isoboxer v0.1.1 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */ | ||
var ISOBoxer=ISOBoxer||{};ISOBoxer.Cursor=function(a){this.offset="undefined"==typeof a?0:a};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)}return this._cursor.offset+=a>>3,b},ISOBox.prototype._readUint=function(a){var b=null;switch(a){case 8:b=this._raw.getUint8(this._cursor.offset-this._raw.byteOffset);break;case 16:b=this._raw.getUint16(this._cursor.offset-this._raw.byteOffset);break;case 24:var c=this._raw.getUint16(this._cursor.offset-this._raw.byteOffset),d=this._raw.getUint8(this._cursor.offset-this._raw.byteOffset+2);b=(c<<8)+d;break;case 32:b=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset);break;case 64:var c=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset),d=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset+4);b=c*Math.pow(2,32)+d}return this._cursor.offset+=a>>3,b},ISOBox.prototype._readString=function(a){for(var b="",c=0;a>c;c++){var d=this._readUint(8);b+=String.fromCharCode(d)}return b},ISOBox.prototype._readTerminatedString=function(){for(var a="";;){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._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._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._boxParsers={},["moov","trak","tref","mdia","minf","stbl","edts","dinf","mvex","moof","traf","mfra","udta","meco","strk"].forEach(function(a){ISOBox.prototype._boxParsers[a]=function(){for(this.boxes=[];this._cursor.offset-this._raw.byteOffset<this._raw.byteLength;)this.boxes.push(ISOBox.parse(this))}}),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_versions=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=new DataView(this._raw.buffer,this._cursor.offset,this._raw.byteLength-(this._cursor.offset-this._offset))},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.mfhd=function(){this._parseFullBox(),this.sequence_number=this._readUint(32)},ISOBox.prototype._boxParsers.mvhd=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)),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(var a=0;9>a;a++)this.matrix.push(this._readTemplate(32));this.pre_defined=[];for(var a=0;6>a;a++)this.pre_defined.push(this._readUint(32));this.next_track_ID=this._readUint(32)},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.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.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;9>a;a++)this.matrix.push(this._readTemplate(32));this.width=this._readUint(32),this.height=this._readUint(32)},ISOBox.prototype._boxParsers.tfdt=function(){this._parseFullBox(),this.baseMediaDecodeTime=this._readUint(1==this.version?64: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.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&&(b.sample_composition_time_offset=0==this.version?this._readUint(32):this._readInt(32)),this.samples.push(b)}};var ISOBoxer=ISOBoxer||{};ISOBoxer.parseBuffer=function(a){return new ISOFile(a).parse()},ISOBoxer.Utils={},ISOBoxer.Utils.dataViewToString=function(a,b){if("undefined"!=typeof TextDecoder)return new TextDecoder(b||"utf-8").decode(a);for(var c="",d=0;d<a.byteLength;d++)c+=String.fromCharCode(a.getUint8(d));return c},"undefined"!=typeof exports&&(exports.parseBuffer=ISOBoxer.parseBuffer,exports.Utils=ISOBoxer.Utils);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 ISOBoxer={};ISOBoxer.parseBuffer=function(a){return new ISOFile(a).parse()},ISOBoxer.Utils={},ISOBoxer.Utils.dataViewToString=function(a,b){if("undefined"!=typeof TextDecoder)return new TextDecoder(b||"utf-8").decode(a);for(var c="",d=0;d<a.byteLength;d++)c+=String.fromCharCode(a.getUint8(d));return c},"undefined"!=typeof exports&&(exports.parseBuffer=ISOBoxer.parseBuffer,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)}return this._cursor.offset+=a>>3,b},ISOBox.prototype._readUint=function(a){var b=null;switch(a){case 8:b=this._raw.getUint8(this._cursor.offset-this._raw.byteOffset);break;case 16:b=this._raw.getUint16(this._cursor.offset-this._raw.byteOffset);break;case 24:var c=this._raw.getUint16(this._cursor.offset-this._raw.byteOffset),d=this._raw.getUint8(this._cursor.offset-this._raw.byteOffset+2);b=(c<<8)+d;break;case 32:b=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset);break;case 64:var c=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset),d=this._raw.getUint32(this._cursor.offset-this._raw.byteOffset+4);b=c*Math.pow(2,32)+d}return this._cursor.offset+=a>>3,b},ISOBox.prototype._readString=function(a){for(var b="",c=0;a>c;c++){var d=this._readUint(8);b+=String.fromCharCode(d)}return b},ISOBox.prototype._readTerminatedString=function(){for(var a="";;){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._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._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._boxParsers={},["moov","trak","tref","mdia","minf","stbl","edts","dinf","mvex","moof","traf","mfra","udta","meco","strk"].forEach(function(a){ISOBox.prototype._boxParsers[a]=function(){for(this.boxes=[];this._cursor.offset-this._raw.byteOffset<this._raw.byteLength;)this.boxes.push(ISOBox.parse(this))}}),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_versions=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=new DataView(this._raw.buffer,this._cursor.offset,this._raw.byteLength-(this._cursor.offset-this._offset))},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.mfhd=function(){this._parseFullBox(),this.sequence_number=this._readUint(32)},ISOBox.prototype._boxParsers.mvhd=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)),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(var a=0;9>a;a++)this.matrix.push(this._readTemplate(32));this.pre_defined=[];for(var a=0;6>a;a++)this.pre_defined.push(this._readUint(32));this.next_track_ID=this._readUint(32)},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.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.tfdt=function(){this._parseFullBox(),this.baseMediaDecodeTime=this._readUint(1==this.version?64: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.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;9>a;a++)this.matrix.push(this._readTemplate(32));this.width=this._readUint(32),this.height=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&&(b.sample_composition_time_offset=0==this.version?this._readUint(32):this._readInt(32)),this.samples.push(b)}}; |
module.exports = function(grunt) { | ||
var banner = '/*! <%= pkg.name %> v<%= pkg.version %> <%= pkg.licenses[0].url %> */\n'; | ||
var boxes = grunt.option('boxes'); | ||
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 { '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']); | ||
} | ||
var parsers = grunt.file.expand('src/parsers/*.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); | ||
}) | ||
return defaultList.concat(files); | ||
} | ||
function getBoxParserForBox(parsers, box) { | ||
var result; | ||
parsers.forEach(function(parser) { | ||
var providers = parser.split('/').pop().replace('.js', '').split(',') | ||
if (providers.indexOf(box) != -1) result = parser; | ||
}) | ||
return result; | ||
} | ||
grunt.initConfig({ | ||
@@ -12,4 +49,4 @@ pkg: grunt.file.readJSON('package.json'), | ||
dist: { | ||
src: ['src/**/*.js'], | ||
dest: 'dist/iso_boxer.js' | ||
src: getSourceFiles(), | ||
dest: getDestinationFile() | ||
} | ||
@@ -22,5 +59,3 @@ }, | ||
dist: { | ||
files: { | ||
'dist/iso_boxer.min.js': ['<%= concat.dist.dest %>'] | ||
} | ||
files: getDestinationMinifiedFile() | ||
} | ||
@@ -39,3 +74,2 @@ }, | ||
grunt.registerTask('default', ['concat', 'uglify']); | ||
}; |
{ | ||
"name": "codem-isoboxer", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Browser-based MPEG-4 (ISOBMFF) file/box parsing.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -21,2 +21,3 @@ # codem-isoboxer | ||
* ftyp / styp | ||
* hdlr | ||
* mdat | ||
@@ -143,2 +144,12 @@ * mdia | ||
## Advanced build options | ||
`codem-isoboxer` now has the option for modular builds. This means you can specify which boxes you are interested in during build time and you will get a generated file containing only the necessary boxes. This can help you further decrease the size of the library if you know you will only need access to some boxes. The syntax for building is: | ||
grunt --boxes=moov,mdat | ||
This will generate a build that only contains the code to parse these boxes and can yield significantly smaller builds. The list needs to be comma-separated. Be sure not to include any white-space in it. Note that some parsers share identical code (e.g. `ftyp`/`styp`, `free`/`skip` and all the regular container boxes). Including one of those will automatically include the other ones as well, but at no additional build size. See `src/parsers` for a list of available parsers and see which parsers share code. | ||
`codem-isoboxer` does not take into account the box hierarchy/dependency when building, you must explicitly specify which boxes you need (e.g. if you want to parse `mvhd` you must also include `moov`). | ||
## Demo | ||
@@ -145,0 +156,0 @@ |
@@ -1,5 +0,3 @@ | ||
var ISOBoxer = ISOBoxer || {}; | ||
ISOBoxer.Cursor = function(initialOffset) { | ||
this.offset = (typeof initialOffset == 'undefined' ? 0 : initialOffset); | ||
} |
@@ -132,248 +132,2 @@ var ISOBox = function() { | ||
ISOBox.prototype._boxParsers = {}; | ||
// Simple container boxes, all from ISO/IEC 14496-12:2012 | ||
[ | ||
'moov', 'trak', 'tref', 'mdia', 'minf', 'stbl', 'edts', 'dinf', | ||
'mvex', 'moof', 'traf', 'mfra', 'udta', 'meco', 'strk' | ||
].forEach(function(boxType) { | ||
ISOBox.prototype._boxParsers[boxType] = function() { | ||
this.boxes = []; | ||
while (this._cursor.offset - this._raw.byteOffset < this._raw.byteLength) { | ||
this.boxes.push(ISOBox.parse(this)); | ||
} | ||
} | ||
}) | ||
// 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)); | ||
} | ||
// 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)); | ||
} | ||
// 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_versions = this._readUint(32); | ||
this.compatible_brands = []; | ||
while (this._cursor.offset - this._raw.byteOffset < this._raw.byteLength) { | ||
this.compatible_brands.push(this._readString(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() | ||
} | ||
// ISO/IEC 14496-12:2012 - 8.1.1 Media Data Box | ||
ISOBox.prototype._boxParsers['mdat'] = function() { | ||
this.data = new DataView(this._raw.buffer, this._cursor.offset, this._raw.byteLength - (this._cursor.offset - this._offset)); | ||
} | ||
// 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); | ||
} | ||
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); | ||
} | ||
// 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); | ||
} | ||
// ISO/IEC 14496-12:2012 - 8.2.2 Movie Header Box | ||
ISOBox.prototype._boxParsers['mvhd'] = 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); | ||
} | ||
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 (var i=0; i<9; i++) { | ||
this.matrix.push(this._readTemplate(32)); | ||
} | ||
this.pre_defined = []; | ||
for (var i=0; i<6; i++) { | ||
this.pre_defined.push(this._readUint(32)); | ||
} | ||
this.next_track_ID = this._readUint(32); | ||
} | ||
// 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 14496-12:2012 - 8.16.4 Subsegment Index Box | ||
ISOBox.prototype._boxParsers['ssix'] = function() { | ||
this._parseFullBox(); | ||
this.subsegment_count = this._readUint(32); | ||
this.subsegments = []; | ||
for (var i=0; i<this.subsegment_count; i++) { | ||
var subsegment = {}; | ||
subsegment.ranges_count = this._readUint(32); | ||
subsegment.ranges = []; | ||
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); | ||
} | ||
this.subsegments.push(subsegment); | ||
} | ||
} | ||
// ISO/IEC 14496-12:2012 - 8.3.2 Track Header Box | ||
ISOBox.prototype._boxParsers['tkhd'] = function() { | ||
this._parseFullBox(); | ||
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._readUint(32); | ||
this.height = this._readUint(32); | ||
} | ||
// 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.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: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._boxParsers = {}; |
@@ -1,2 +0,2 @@ | ||
var ISOBoxer = ISOBoxer || {}; | ||
var ISOBoxer = {}; | ||
@@ -3,0 +3,0 @@ ISOBoxer.parseBuffer = function(arrayBuffer) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51251
27
838
160