Skip to content

Commit a99f454

Browse files
authored
preselections metadata (#59)
* Bump package version to 0.3.10 * Add meta box Add a skeleton implementation of 'meta'. This makes the read/write editlist.mp4 test fail. This is because The meta subboxes are not yet implemented. When neither reader nor writer for meta were implemented, the test for reading/writing editlist.mp4 worked, but as soon as meta is added as a reader, the subboxes have to be implemented too to not fail this test. Rather than adding the additional boxes, we remove 'meta' from editlist.mp4. * Add grpl box * Add utf8string datatype * Add prsl box * Add the prsl box, unit tests, and an mp4 file for testing * Implement FDIS version of prsl * Make the interleaving tag is optional and contingent on a flag * Use new test content * Add labl box * Implement FDIS version of labl * read is_group_label from the flags instead of as a separate field * represent is_group_label as boolean * Add 'elng' box * Add 'ardi' box * Add 'kind' box * Add 'imda' box * Update bundles
1 parent 933f702 commit a99f454

File tree

15 files changed

+235
-6
lines changed

15 files changed

+235
-6
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,24 @@
1616
Currently a limited set of ISOBMFF boxes is supported:
1717

1818
### ISO/IEC 14496-12:2012 (ISOBMFF)
19+
* ardi
1920
* dinf
2021
* edts
2122
* elst
23+
* elng
2224
* free / skip
2325
* ftyp / styp
26+
* grpl
2427
* hdlr
28+
* imda
29+
* kind
30+
* labl
2531
* mdat
2632
* mdia
2733
* mdhd
2834
* meco
2935
* mehd
36+
* meta
3037
* mfhd
3138
* mfra
3239
* mfro
@@ -35,6 +42,7 @@ Currently a limited set of ISOBMFF boxes is supported:
3542
* mp4a / enca
3643
* mvex
3744
* mvhd / mfhd
45+
* prsl
3846
* sidx
3947
* ssix
4048
* stbl

dist/iso_boxer.js

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! codem-isoboxer v0.3.8 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */
1+
/*! codem-isoboxer v0.3.10 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */
22
var ISOBoxer = {};
33

44
ISOBoxer.parseBuffer = function(arrayBuffer) {
@@ -253,7 +253,7 @@ ISOBox.create = function(type) {
253253
return newBox;
254254
};
255255

256-
ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca'];
256+
ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca','meta','grpl','prsl'];
257257

258258
ISOBox.prototype._boxProcessors = {};
259259

@@ -366,6 +366,8 @@ ISOBox.prototype._readField = function(type, size) {
366366
return this._readData(size);
367367
case 'utf8':
368368
return this._readUTF8String();
369+
case 'utf8string':
370+
return this._readUTF8TerminatedString();
369371
default:
370372
return -1;
371373
}
@@ -476,6 +478,25 @@ ISOBox.prototype._readUTF8String = function() {
476478
return data ? ISOBoxer.Utils.dataViewToString(data) : data;
477479
};
478480

481+
ISOBox.prototype._readUTF8TerminatedString = function() {
482+
var length = this._raw.byteLength - (this._cursor.offset - this._offset);
483+
var data = null;
484+
if (length > 0) {
485+
data = new DataView(this._raw.buffer, this._cursor.offset, length);
486+
487+
var l;
488+
for (l=0; l<length; l++)
489+
if (data.getUint8(l) === 0)
490+
break;
491+
492+
// remap the Dataview with the actual length
493+
data = new DataView(this._raw.buffer, this._cursor.offset, l);
494+
this._cursor.offset += Math.min(l+1, length);
495+
}
496+
497+
return data ? ISOBoxer.Utils.dataViewToString(data) : data;
498+
};
499+
479500
ISOBox.prototype._parseBox = function() {
480501
this._parsing = true;
481502
this._cursor.offset = this._offset;
@@ -769,6 +790,12 @@ ISOBox.prototype._writeField = function(type, size, value) {
769790
}
770791
};
771792

793+
// ISO/IEC 14496-12:202x - 12.2.8 Audio rendering indication box
794+
ISOBox.prototype._boxProcessors['ardi'] = function() {
795+
this._procFullBox();
796+
this._procField('audio_rendering_indication', 'uint', 8);
797+
};
798+
772799
// ISO/IEC 14496-15:2014 - avc1/2/3/4, hev1, hvc1, encv
773800
ISOBox.prototype._boxProcessors['avc1'] =
774801
ISOBox.prototype._boxProcessors['avc2'] =
@@ -814,6 +841,12 @@ ISOBox.prototype._boxProcessors['dref'] = function() {
814841
this._procSubBoxes('entries', this.entry_count);
815842
};
816843

844+
// ISO/IEC 14496-12:202x - 8.4.6 Extended language tag
845+
ISOBox.prototype._boxProcessors['elng'] = function() {
846+
this._procFullBox();
847+
this._procField('extended_language', 'utf8string');
848+
};
849+
817850
// ISO/IEC 14496-12:2012 - 8.6.6 Edit List Box
818851
ISOBox.prototype._boxProcessors['elst'] = function() {
819852
this._procFullBox();
@@ -876,6 +909,30 @@ ISOBox.prototype._boxProcessors['hdlr'] = function() {
876909
this._procField('name', 'string', -1);
877910
};
878911

912+
// ISO/IEC 14496-12:2012 - 9.1.4.1 Identified media data box
913+
ISOBox.prototype._boxProcessors['imda'] = function() {
914+
this._procField('imda_identifier', 'uint', 32);
915+
// until the end of the box
916+
this._procField('data', 'data', -1);
917+
};
918+
919+
// ISO/IEC 14496-12:202x - 8.10.4 Track kind box
920+
ISOBox.prototype._boxProcessors['kind'] = function() {
921+
this._procFullBox();
922+
923+
this._procField('schemeURI', 'utf8string');
924+
this._procField('value', 'utf8string');
925+
};
926+
927+
// ISO/IEC 14496-12:202x - 8.10.5 Label box
928+
ISOBox.prototype._boxProcessors['labl'] = function() {
929+
this._procFullBox();
930+
this.is_group_label = (this.flags & 0x1) != 0;
931+
this._procField('label_id', 'uint', 16);
932+
this._procField('language', 'utf8string');
933+
this._procField('label', 'utf8string');
934+
};
935+
879936
// ISO/IEC 14496-12:2012 - 8.1.1 Media Data Box
880937
ISOBox.prototype._boxProcessors['mdat'] = function() {
881938
this._procField('data', 'data', -1);
@@ -909,6 +966,13 @@ ISOBox.prototype._boxProcessors['mehd'] = function() {
909966
this._procField('fragment_duration', 'uint', (this.version == 1) ? 64 : 32);
910967
};
911968

969+
// ISO/IEC 14496-12:202x - 8.11.1 Meta box
970+
ISOBox.prototype._boxProcessors['meta'] = function() {
971+
this._procFullBox();
972+
973+
/* rest of the boxes will be read by _parseContainerBox */
974+
};
975+
912976
// ISO/IEC 14496-12:2012 - 8.8.5 Movie Fragment Header Box
913977
ISOBox.prototype._boxProcessors['mfhd'] = function() {
914978
this._procFullBox();
@@ -968,6 +1032,21 @@ ISOBox.prototype._boxProcessors['prft'] = function() {
9681032
this._procField('media_time', 'uint', (this.version == 1) ? 64 : 32);
9691033
};
9701034

1035+
// ISO/IEC 14496-12:202x - 8.18.4.1 Preselection group box
1036+
ISOBox.prototype._boxProcessors['prsl'] = function() {
1037+
this._procFullBox();
1038+
this._procField('group_id', 'uint', 32);
1039+
this._procField('num_entities_in_group', 'uint', 32);
1040+
this._procEntries('entities', this.num_entities_in_group, function(entry) {
1041+
this._procEntryField(entry, 'entity_id', 'uint', 32);
1042+
});
1043+
if (this.flags & 0x1000) this._procField('preselection_tag', 'utf8string');
1044+
if (this.flags & 0x2000) this._procField('selection_priority', 'uint', 8);
1045+
if (this.flags & 0x4000) this._procField('interleaving_tag', 'utf8string');
1046+
1047+
/* rest of the boxes will be read by _parseContainerBox */
1048+
};
1049+
9711050
//ISO/IEC 23001-7:2011 - 8.1 Protection System Specific Header Box
9721051
ISOBox.prototype._boxProcessors['pssh'] = function() {
9731052
this._procFullBox();
@@ -1056,6 +1135,11 @@ ISOBox.prototype._boxProcessors['stsd'] = function() {
10561135
this._procSubBoxes('entries', this.entry_count);
10571136
};
10581137

1138+
// ISO/IEC 14496-30:2014 - WebVTT Cue Settings Box.
1139+
ISOBox.prototype._boxProcessors['sttg'] = function() {
1140+
this._procField('settings', 'utf8');
1141+
};
1142+
10591143
// ISO/IEC 14496-12:2012 - 8.6.1.2 Decoding Time To Sample Box
10601144
ISOBox.prototype._boxProcessors['stts'] = function() {
10611145
this._procFullBox();

dist/iso_boxer.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codem-isoboxer",
3-
"version": "0.3.9",
3+
"version": "0.3.10",
44
"description": "A lightweight JavaScript MP4 (MPEG-4, ISOBMFF) file/box parser.",
55
"keywords": [
66
"mp4",

src/iso_box.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ISOBox.create = function(type) {
2020
return newBox;
2121
};
2222

23-
ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca'];
23+
ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca','meta','grpl','prsl'];
2424

2525
ISOBox.prototype._boxProcessors = {};
2626

@@ -145,6 +145,8 @@ ISOBox.prototype._readField = function(type, size) {
145145
return this._readData(size);
146146
case 'utf8':
147147
return this._readUTF8String();
148+
case 'utf8string':
149+
return this._readUTF8TerminatedString();
148150
default:
149151
return -1;
150152
}
@@ -255,6 +257,25 @@ ISOBox.prototype._readUTF8String = function() {
255257
return data ? ISOBoxer.Utils.dataViewToString(data) : data;
256258
};
257259

260+
ISOBox.prototype._readUTF8TerminatedString = function() {
261+
var length = this._raw.byteLength - (this._cursor.offset - this._offset);
262+
var data = null;
263+
if (length > 0) {
264+
data = new DataView(this._raw.buffer, this._cursor.offset, length);
265+
266+
var l;
267+
for (l=0; l<length; l++)
268+
if (data.getUint8(l) === 0)
269+
break;
270+
271+
// remap the Dataview with the actual length
272+
data = new DataView(this._raw.buffer, this._cursor.offset, l);
273+
this._cursor.offset += Math.min(l+1, length);
274+
}
275+
276+
return data ? ISOBoxer.Utils.dataViewToString(data) : data;
277+
};
278+
258279
ISOBox.prototype._parseBox = function() {
259280
this._parsing = true;
260281
this._cursor.offset = this._offset;

src/processors/ardi.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// ISO/IEC 14496-12:202x - 12.2.8 Audio rendering indication box
2+
ISOBox.prototype._boxProcessors['ardi'] = function() {
3+
this._procFullBox();
4+
this._procField('audio_rendering_indication', 'uint', 8);
5+
};

src/processors/elng.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// ISO/IEC 14496-12:202x - 8.4.6 Extended language tag
2+
ISOBox.prototype._boxProcessors['elng'] = function() {
3+
this._procFullBox();
4+
this._procField('extended_language', 'utf8string');
5+
};

src/processors/imda.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// ISO/IEC 14496-12:2012 - 9.1.4.1 Identified media data box
2+
ISOBox.prototype._boxProcessors['imda'] = function() {
3+
this._procField('imda_identifier', 'uint', 32);
4+
// until the end of the box
5+
this._procField('data', 'data', -1);
6+
};

src/processors/kind.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// ISO/IEC 14496-12:202x - 8.10.4 Track kind box
2+
ISOBox.prototype._boxProcessors['kind'] = function() {
3+
this._procFullBox();
4+
5+
this._procField('schemeURI', 'utf8string');
6+
this._procField('value', 'utf8string');
7+
};

src/processors/labl.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// ISO/IEC 14496-12:202x - 8.10.5 Label box
2+
ISOBox.prototype._boxProcessors['labl'] = function() {
3+
this._procFullBox();
4+
this.is_group_label = (this.flags & 0x1) != 0;
5+
this._procField('label_id', 'uint', 16);
6+
this._procField('language', 'utf8string');
7+
this._procField('label', 'utf8string');
8+
};

0 commit comments

Comments
 (0)