Skip to content

Commit baf7d61

Browse files
committed
simple print node test
1 parent e090d74 commit baf7d61

12 files changed

+195
-66
lines changed

Gruntfile.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module.exports = function(grunt) {
3131
'src/isofile-sample-processing.js', // file level sample processing operations (sample table, get, ...)
3232
'src/isofile-item-processing.js', // item processing operations (sample table, get, ...)
3333
'src/isofile-write.js', // file level write operations (segment creation ...)
34+
'src/box-print.js', // simple print
3435
'src/mp4box.js' // application level operations (data append, sample extraction, segmentation, ...)
3536
],
3637
dest: 'dist/<%= pkg.name %>.all.js'

src/DataStream.js

+3
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,9 @@ DataStream.prototype.readCString = function(length) {
566566
*/
567567
var MAX_SIZE = Math.pow(2, 32);
568568

569+
DataStream.prototype.readInt64 = function () {
570+
return (this.readInt32()*MAX_SIZE)+this.readUint32();
571+
}
569572
DataStream.prototype.readUint64 = function () {
570573
return (this.readUint32()*MAX_SIZE)+this.readUint32();
571574
}

src/box-print.js

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) Telecom ParisTech/TSI/MM/GPAC Cyril Concolato
3+
* License: BSD-3-Clause (see LICENSE file)
4+
*/
5+
BoxParser.Box.prototype.printHeader = function(output) {
6+
this.size += 8;
7+
if (this.size > MAX_SIZE) {
8+
this.size += 8;
9+
}
10+
if (this.type === "uuid") {
11+
this.size += 16;
12+
}
13+
output.log(output.indent+"size:"+this.size);
14+
output.log(output.indent+"type:"+this.type);
15+
}
16+
17+
BoxParser.FullBox.prototype.printHeader = function(output) {
18+
this.size += 4;
19+
BoxParser.Box.prototype.printHeader.call(this, output);
20+
output.log(output.indent+"version:"+this.version);
21+
output.log(output.indent+"flags:"+this.flags);
22+
}
23+
24+
BoxParser.Box.prototype.print = function(output) {
25+
this.printHeader(output);
26+
}
27+
28+
BoxParser.ContainerBox.prototype.print = function(output) {
29+
this.printHeader(output);
30+
for (var i=0; i<this.boxes.length; i++) {
31+
if (this.boxes[i]) {
32+
var prev_indent = output.indent;
33+
output.indent += " ";
34+
this.boxes[i].print(output);
35+
output.indent = prev_indent;
36+
}
37+
}
38+
}
39+
40+
ISOFile.prototype.print = function(output) {
41+
output.indent = "";
42+
for (var i=0; i<this.boxes.length; i++) {
43+
if (this.boxes[i]) {
44+
this.boxes[i].print(output);
45+
}
46+
}
47+
}
48+
49+
BoxParser.mvhdBox.prototype.print = function(output) {
50+
BoxParser.FullBox.prototype.printHeader.call(this, output);
51+
output.log("creation_time: "+this.creation_time);
52+
output.log("modification_time: "+this.modification_time);
53+
output.log("timescale: "+this.timescale);
54+
output.log("duration: "+this.duration);
55+
output.log("rate: "+this.rate);
56+
output.log("volume: "+this.volume>>8);
57+
output.log("matrix: "+this.matrix.join(", "));
58+
output.log("next_track_id: "+this.next_track_id);
59+
}
60+
61+
BoxParser.tkhdBox.prototype.print = function(output) {
62+
BoxParser.FullBox.prototype.printHeader.call(this, output);
63+
output.log("creation_time: "+this.creation_time);
64+
output.log("modification_time: "+this.modification_time);
65+
output.log("track_id: "+this.track_id);
66+
output.log("duration: "+this.duration);
67+
output.log("volume: "+this.volume>>8);
68+
output.log("matrix: "+this.matrix.join(", "));
69+
output.log("layer: "+this.layer);
70+
output.log("alternate_group: "+this.alternate_group);
71+
output.log("width: "+this.width);
72+
output.log("height: "+this.height);
73+
}

src/box.js

+15-15
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,9 @@ var BoxParser = {
1010
"mdat", "idat", "free", "skip",
1111
"avcC", "hvcC", "ftyp", "styp",
1212
"payl", "vttC",
13-
"rtp ", "sdp ",
13+
"sdp ",
1414
"btrt", "frma",
1515
"trpy", "tpyl", "totl", "tpay", "dmed", "dimm", "drep", "nump", "npck", "maxr", "tmin", "tmax", "dmax", "pmax", "payt",
16-
"vmhd", "smhd", "hmhd", // full boxes not yet parsed
17-
"idat", "meco",
18-
"udta", "strk",
19-
"free", "skip",
2016
"clap", "pasp"
2117
],
2218
fullBoxCodes : [ "mvhd", "tkhd", "mdhd", "hdlr", "vmhd", "smhd", "hmhd", "nmhd", "url ", "urn ",
@@ -25,7 +21,7 @@ var BoxParser = {
2521
"esds", "subs",
2622
"txtC",
2723
"sidx", "emsg", "prft", "pssh",
28-
"elst", "dref", "url ", "urn ",
24+
"elst", "dref",
2925
"sbgp", "sgpd",
3026
"cprt",
3127
"iods",
@@ -34,9 +30,12 @@ var BoxParser = {
3430
"schm",
3531
"stvi",
3632
"padb", "stdp", "sdtp", "saio", "saiz",
37-
"meta", "xml ", "bxml", "iloc", "pitm", "ipro", "iinf", "infe", "iref" , "mere",
33+
"meta", "xml ", "bxml", "iloc", "pitm", "ipro", "iinf", "infe", "mere",
3834
"kind", "elng",
39-
"ipma", "pixi", "ispe"
35+
"ipma", "pixi", "ispe",
36+
"sthd",
37+
"tenc",
38+
"vpcC"
4039
/* missing "stsd", "iref", : special case full box and container */
4140
],
4241
containerBoxCodes : [
@@ -53,7 +52,6 @@ var BoxParser = {
5352
[ "vttc" ],
5453
[ "tref" ],
5554
[ "iref" ],
56-
[ "udta" ],
5755
[ "mfra" ],
5856
[ "meco" ],
5957
[ "hnti" ],
@@ -71,7 +69,7 @@ var BoxParser = {
7169
sampleEntryCodes : [
7270
/* 4CC as registered on http://mp4ra.org/codecs.html */
7371
{ prefix: "Visual", types: [ "mp4v", "avc1", "avc2", "avc3", "avc4", "avcp", "drac", "encv", "mjp2", "mvc1", "mvc2", "resv", "s263", "svc1", "vc-1", "hvc1", "hev1" ] },
74-
{ prefix: "Audio", types: [ "mp4a", "ac-3", "alac", "dra1", "dtsc", "dtse", ,"dtsh", "dtsl", "ec-3", "enca", "g719", "g726", "m4ae", "mlpa", "raw ", "samr", "sawb", "sawp", "sevc", "sqcp", "ssmv", "twos", ".mp3" ] },
72+
{ prefix: "Audio", types: [ "mp4a", "ac-3", "alac", "dra1", "dtsc", "dtse", "dtsh", "dtsl", "ec-3", "enca", "g719", "g726", "m4ae", "mlpa", "raw ", "samr", "sawb", "sawp", "sevc", "sqcp", "ssmv", "twos", ".mp3" ] },
7573
{ prefix: "Hint", types: [ "fdp ", "m2ts", "pm2t", "prtp", "rm2t", "rrtp", "rsrp", "rtp ", "sm2t", "srtp" ] },
7674
{ prefix: "Metadata", types: [ "metx", "mett", "urim" ] },
7775
{ prefix: "Subtitle", types: [ "stpp", "wvtt", "sbtt", "tx3g", "stxt" ] },
@@ -212,13 +210,15 @@ BoxParser.TRUN_FLAGS_FLAGS = 0x400;
212210
BoxParser.TRUN_FLAGS_CTS_OFFSET = 0x800;
213211

214212
BoxParser.Box.prototype.add = function(name) {
215-
var i, j;
216-
var box = new BoxParser[name+"Box"]();
213+
return this.addBox(new BoxParser[name+"Box"]());
214+
}
215+
216+
BoxParser.Box.prototype.addBox = function(box) {
217217
this.boxes.push(box);
218-
if (this[name+"s"]) {
219-
this[name+"s"].push(box);
218+
if (this[box.type+"s"]) {
219+
this[box.type+"s"].push(box);
220220
} else {
221-
this[name] = box;
221+
this[box.type] = box;
222222
}
223223
return box;
224224
}

src/isofile-advanced-creation.js

+55-34
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
ISOFile.prototype.add = BoxParser.Box.prototype.add;
2+
ISOFile.prototype.addBox = BoxParser.Box.prototype.addBox;
23

3-
ISOFile.prototype.init = function () {
4-
var ftyp = this.add("ftyp").set("major_brand", "iso4")
4+
ISOFile.prototype.init = function (_options) {
5+
var options = _options || {};
6+
var ftyp = this.add("ftyp").set("major_brand", (options.brands && options.brands[0]) || "iso4")
57
.set("minor_version", 0)
6-
.set("compatible_brands", []);
8+
.set("compatible_brands", options.brands || ["iso4"]);
79
var moov = this.add("moov");
8-
moov.add("mvhd").set("timescale",600)
9-
.set("rate", 1)
10+
moov.add("mvhd").set("timescale", options.timescale || 600)
11+
.set("rate", options.rate || 1)
1012
.set("creation_time", 0)
1113
.set("modification_time", 0)
12-
.set("duration", 0)
14+
.set("duration", options.duration || 0)
1315
.set("volume", 1)
1416
.set("matrix", [ 0, 0, 0, 0, 0, 0, 0, 0, 0])
1517
.set("next_track_id", 1);
@@ -19,7 +21,7 @@ ISOFile.prototype.init = function () {
1921

2022
ISOFile.prototype.addTrack = function (_options) {
2123
if (!this.moov) {
22-
this.init();
24+
this.init(_options);
2325
}
2426

2527
var options = _options || {};
@@ -30,11 +32,14 @@ ISOFile.prototype.addTrack = function (_options) {
3032

3133
var trak = this.moov.add("trak");
3234
this.moov.mvhd.next_track_id = options.id+1;
33-
trak.add("tkhd").set("creation_time",0)
35+
trak.add("tkhd").set("flags",BoxParser.TKHD_FLAG_ENABLED |
36+
BoxParser.TKHD_FLAG_IN_MOVIE |
37+
BoxParser.TKHD_FLAG_IN_PREVIEW)
38+
.set("creation_time",0)
3439
.set("modification_time", 0)
3540
.set("track_id", options.id)
36-
.set("duration", 0)
37-
.set("layer", 0)
41+
.set("duration", options.duration || 0)
42+
.set("layer", options.layer || 0)
3843
.set("alternate_group", 0)
3944
.set("volume", 1)
4045
.set("matrix", [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ])
@@ -45,7 +50,7 @@ ISOFile.prototype.addTrack = function (_options) {
4550
mdia.add("mdhd").set("creation_time", 0)
4651
.set("modification_time", 0)
4752
.set("timescale", options.timescale || 1)
48-
.set("duration", 0)
53+
.set("duration", options.media_duration || 0)
4954
.set("language", options.language || 0);
5055

5156
mdia.add("hdlr").set("handler", options.hdlr || "vide")
@@ -54,7 +59,9 @@ ISOFile.prototype.addTrack = function (_options) {
5459
mdia.add("elng").set("extended_language", options.language || "fr-FR");
5560

5661
var minf = mdia.add("minf");
57-
var sample_entry = new BoxParser[options.type+"SampleEntry"]();
62+
if (BoxParser[options.type+"SampleEntry"] === undefined) return;
63+
var sample_description_entry = new BoxParser[options.type+"SampleEntry"]();
64+
sample_description_entry.data_reference_index = 1;
5865
var media_type = "";
5966
for (var i = 0; i < BoxParser.sampleEntryCodes.length; i++) {
6067
var code = BoxParser.sampleEntryCodes[i];
@@ -66,30 +73,39 @@ ISOFile.prototype.addTrack = function (_options) {
6673
switch(media_type) {
6774
case "Visual":
6875
minf.add("vmhd").set("graphicsmode",0).set("opcolor", [ 0, 0, 0 ]);
69-
sample_entry.set("width", options.width)
76+
sample_description_entry.set("width", options.width)
7077
.set("height", options.height)
7178
.set("horizresolution", 0x48<<16)
7279
.set("vertresolution", 0x48<<16)
7380
.set("frame_count", 1)
7481
.set("compressorname", options.type+" Compressor")
7582
.set("depth", 0x18);
76-
77-
sample_entry.add("avcC").set("SPS", [])
78-
.set("PPS", [])
79-
.set("configurationVersion", 1)
80-
.set("AVCProfileIndication",0)
81-
.set("profile_compatibility", 0)
82-
.set("AVCLevelIndication" ,0)
83-
.set("lengthSizeMinusOne", 0);
83+
// sample_description_entry.add("avcC").set("SPS", [])
84+
// .set("PPS", [])
85+
// .set("configurationVersion", 1)
86+
// .set("AVCProfileIndication",0)
87+
// .set("profile_compatibility", 0)
88+
// .set("AVCLevelIndication" ,0)
89+
// .set("lengthSizeMinusOne", 0);
8490
break;
8591
case "Audio":
86-
minf.add("smhd");
92+
minf.add("smhd").set("balance", options.balance || 0);
93+
sample_description_entry.set("channel_count", options.channel_count || 2)
94+
.set("samplesize", options.samplesize || 16)
95+
.set("samplerate", options.samplerate || 1<<16);
8796
break;
8897
case "Hint":
89-
minf.add("hmhd");
98+
minf.add("hmhd"); // TODO: add properties
9099
break;
91100
case "Subtitle":
92101
minf.add("sthd");
102+
switch (options.type) {
103+
case "stpp":
104+
sample_description_entry.set("namespace", options.namespace || "nonamespace")
105+
.set("schema_location", options.schema_location || "")
106+
.set("auxiliary_mime_types", options.auxiliary_mime_types || "");
107+
break;
108+
}
93109
break;
94110
case "Metadata":
95111
minf.add("nmhd");
@@ -101,9 +117,12 @@ ISOFile.prototype.addTrack = function (_options) {
101117
minf.add("nmhd");
102118
break;
103119
}
120+
if (options.description) {
121+
sample_description_entry.addBox(options.description);
122+
}
104123
minf.add("dinf").add("dref").addEntry((new BoxParser["url Box"]()).set("flags", 0x1));
105124
var stbl = minf.add("stbl");
106-
stbl.add("stsd").addEntry(sample_entry);
125+
stbl.add("stsd").addEntry(sample_description_entry);
107126
stbl.add("stts").set("sample_counts", [])
108127
.set("sample_deltas", []);
109128
stbl.add("stsc").set("first_chunk", [])
@@ -118,18 +137,20 @@ ISOFile.prototype.addTrack = function (_options) {
118137
.set("default_sample_size", options.default_sample_size || 0)
119138
.set("default_sample_flags", options.default_sample_flags || 0);
120139
this.buildTrakSampleLists(trak);
121-
return trak;
140+
return options.id;
122141
}
123142

124-
BoxParser.Box.prototype.computeSize = function() {
143+
BoxParser.Box.prototype.computeSize = function(stream_) {
125144
var stream = stream_ || new DataStream();
126145
stream.endianness = DataStream.BIG_ENDIAN;
127146
this.write(stream);
128147
}
129148

130-
ISOFile.prototype.addSample = function (trak, data, _options) {
149+
ISOFile.prototype.addSample = function (track_id, data, _options) {
131150
var options = _options || {};
132151
var sample = {};
152+
var trak = this.getTrackById(track_id);
153+
if (trak === null) return;
133154
sample.number = trak.samples.length;
134155
sample.track_id = trak.tkhd.track_id;
135156
sample.timescale = trak.mdia.mdhd.timescale;
@@ -155,13 +176,13 @@ ISOFile.prototype.addSample = function (trak, data, _options) {
155176

156177
this.processSamples();
157178

158-
//var moof = ISOFile.createSingleSampleMoof(sample);
159-
//this.moofs.push(moof);
160-
//this.boxes.push(moof);
161-
//moof.computeSize();
162-
///* adjusting the data_offset now that the moof size is known*/
163-
//moof.trafs[0].truns[0].data_offset = moof.size+8; //8 is mdat header
164-
//this.add("mdat").data = data;
179+
var moof = ISOFile.createSingleSampleMoof(sample);
180+
this.addBox(moof);
181+
moof.computeSize();
182+
/* adjusting the data_offset now that the moof size is known*/
183+
moof.trafs[0].truns[0].data_offset = moof.size+8; //8 is mdat header
184+
this.add("mdat").data = data;
185+
return sample;
165186
}
166187

167188
ISOFile.createSingleSampleMoof = function(sample) {

src/mp4box.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ MP4Box.createFile = function (_keepMdatData, _stream) {
1313
}
1414

1515
if (typeof exports !== 'undefined') {
16-
module.exports = MP4Box;
16+
exports.createFile = MP4Box.createFile;
1717
}

src/parsing/rtp.js

-5
This file was deleted.

src/writing/sampleentry.js

+12
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,15 @@ BoxParser.AudioSampleEntry.prototype.write = function(stream) {
5959
stream.writeUint32(this.samplerate<<16);
6060
this.writeFooter(stream);
6161
}
62+
63+
BoxParser.stppSampleEntry.prototype.write = function(stream) {
64+
this.writeHeader(stream);
65+
this.size += this.namespace.length+1+
66+
this.schema_location.length+1+
67+
this.auxiliary_mime_types.length+1;
68+
stream.writeCString(this.namespace);
69+
stream.writeCString(this.schema_location);
70+
stream.writeCString(this.auxiliary_mime_types);
71+
this.writeFooter(stream);
72+
}
73+

test/node/info.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
var fs = require('fs');
2-
var MP4Box = require('mp4box');
2+
var MP4Box = require('../../dist/mp4box.all.js');
33

44
if (process.argv.length > 2) {
55
var mp4boxfile = MP4Box.createFile();
66
var arrayBuffer = new Uint8Array(fs.readFileSync(process.argv[2])).buffer;
77
arrayBuffer.fileStart = 0;
88

99
mp4boxfile.appendBuffer(arrayBuffer);
10-
console.log(mp4boxfile.getInfo());
10+
console.log(mp4boxfile.print(MP4Box.Log));
1111
} else {
1212
console.log("usage: node info.js <file>");
1313
}

0 commit comments

Comments
 (0)