@remotion/media-parser 4.0.192 → 4.0.194

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/boxes.json +1 -0
  2. package/dist/boxes/iso-base-media/esds/esds-descriptors.d.ts +21 -0
  3. package/dist/boxes/iso-base-media/esds/esds-descriptors.js +62 -0
  4. package/dist/boxes/iso-base-media/esds/esds.d.ts +15 -0
  5. package/dist/boxes/iso-base-media/esds/esds.js +27 -0
  6. package/dist/boxes/iso-base-media/esds-descriptors.d.ts +21 -0
  7. package/dist/boxes/iso-base-media/esds-descriptors.js +62 -0
  8. package/dist/boxes/iso-base-media/esds.d.ts +15 -0
  9. package/dist/boxes/iso-base-media/esds.js +27 -0
  10. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +12 -0
  11. package/dist/boxes/iso-base-media/mdat/mdat.js +13 -0
  12. package/dist/boxes/iso-base-media/process-box.js +67 -0
  13. package/dist/boxes/iso-base-media/stsd/samples.d.ts +2 -0
  14. package/dist/boxes/iso-base-media/stsd/samples.js +27 -8
  15. package/dist/boxes/iso-base-media/stsd/stco.d.ts +14 -0
  16. package/dist/boxes/iso-base-media/stsd/stco.js +30 -0
  17. package/dist/boxes/iso-base-media/stsd/stsc.d.ts +19 -0
  18. package/dist/boxes/iso-base-media/stsd/stsc.js +34 -0
  19. package/dist/boxes/iso-base-media/stsd/stsz.d.ts +15 -0
  20. package/dist/boxes/iso-base-media/stsd/stsz.js +32 -0
  21. package/dist/boxes/webm/parse-webm-header.js +3 -3
  22. package/dist/boxes/webm/segments/track-entry.d.ts +20 -0
  23. package/dist/boxes/webm/segments/track-entry.js +37 -2
  24. package/dist/boxes/webm/segments.d.ts +2 -2
  25. package/dist/boxes/webm/segments.js +12 -0
  26. package/dist/buffer-iterator.d.ts +3 -1
  27. package/dist/buffer-iterator.js +41 -8
  28. package/dist/from-node.js +12 -4
  29. package/dist/from-web.js +12 -4
  30. package/dist/get-audio-codec.d.ts +4 -0
  31. package/dist/get-audio-codec.js +106 -0
  32. package/dist/get-dimensions.js +6 -2
  33. package/dist/get-fps.d.ts +1 -0
  34. package/dist/get-fps.js +34 -1
  35. package/dist/get-sample-positions.d.ts +12 -0
  36. package/dist/get-sample-positions.js +25 -0
  37. package/dist/get-samples.d.ts +0 -0
  38. package/dist/get-samples.js +1 -0
  39. package/dist/get-tracks.d.ts +10 -0
  40. package/dist/get-tracks.js +66 -0
  41. package/dist/get-video-codec.js +3 -0
  42. package/dist/has-all-info.d.ts +1 -1
  43. package/dist/has-all-info.js +4 -0
  44. package/dist/options.d.ts +7 -3
  45. package/dist/parse-media.js +37 -9
  46. package/dist/parse-result.d.ts +3 -1
  47. package/dist/parse-video.d.ts +1 -0
  48. package/dist/parse-video.js +1 -0
  49. package/dist/reader.d.ts +5 -1
  50. package/dist/traversal.d.ts +19 -0
  51. package/dist/traversal.js +88 -0
  52. package/package.json +2 -2
  53. package/src/boxes/iso-base-media/esds/esds-descriptors.ts +104 -0
  54. package/src/boxes/iso-base-media/esds/esds.ts +49 -0
  55. package/src/boxes/iso-base-media/process-box.ts +75 -0
  56. package/src/boxes/iso-base-media/stsd/samples.ts +35 -8
  57. package/src/boxes/webm/parse-webm-header.ts +3 -3
  58. package/src/boxes/webm/segments/track-entry.ts +66 -1
  59. package/src/boxes/webm/segments.ts +29 -1
  60. package/src/buffer-iterator.ts +54 -10
  61. package/src/from-node.ts +13 -6
  62. package/src/from-web.ts +14 -4
  63. package/src/get-audio-codec.ts +143 -0
  64. package/src/get-dimensions.ts +11 -4
  65. package/src/get-fps.ts +48 -0
  66. package/src/get-video-codec.ts +4 -0
  67. package/src/has-all-info.ts +14 -2
  68. package/src/options.ts +18 -3
  69. package/src/parse-media.ts +51 -10
  70. package/src/parse-result.ts +4 -1
  71. package/src/parse-video.ts +2 -0
  72. package/src/reader.ts +6 -2
  73. package/src/test/matroska.test.ts +6 -7
  74. package/src/test/parse-esds.test.ts +75 -0
  75. package/src/test/stream-local.test.ts +80 -3
  76. package/src/test/stsd.test.ts +52 -5
  77. package/tsconfig.tsbuildinfo +1 -1
package/boxes.json ADDED
@@ -0,0 +1 @@
1
+ [{"type":"ftyp-box","majorBrand":"qt","minorVersion":0,"compatibleBrands":["qt"],"offset":0,"boxSize":20},{"type":"regular-box","boxType":"wide","boxSize":8,"children":[],"offset":20},{"type":"regular-box","boxType":"mdat","children":[],"boxSize":39048800,"offset":28},{"offset":39048828,"boxSize":14100,"type":"moov-box","children":[{"creationTime":1686832959000,"modificationTime":1686832973000,"timeScale":600,"durationInUnits":7541,"durationInSeconds":12.568333333333333,"rate":1,"volume":1,"matrix":[65536,0,0,0,65536,0,0,0,1073741824],"nextTrackId":6,"type":"mvhd-box","boxSize":108,"offset":39048836},{"offset":39048944,"boxSize":7341,"type":"trak-box","children":[{"offset":39048952,"boxSize":92,"type":"tkhd-box","creationTime":1686832959000,"modificationTime":1686832973000,"trackId":1,"duration":7541,"layer":0,"alternateGroup":0,"volume":0,"matrix":[0,65536,0,4294901760,0,0,141557760,0,1073741824],"width":3840,"height":2160,"version":0},{"type":"regular-box","boxType":"tapt","boxSize":68,"children":[],"offset":39049044},{"type":"regular-box","boxType":"edts","boxSize":36,"children":[],"offset":39049112},{"type":"regular-box","boxType":"mdia","boxSize":7137,"children":[{"type":"mdhd-box","duration":7541,"timescale":600,"version":0,"language":21956,"quality":0},{"type":"regular-box","boxType":"hdlr","boxSize":49,"children":[],"offset":39049188},{"type":"regular-box","boxType":"minf","boxSize":7048,"children":[{"type":"regular-box","boxType":"vmhd","boxSize":20,"children":[],"offset":39049245},{"type":"regular-box","boxType":"hdlr","boxSize":56,"children":[],"offset":39049265},{"type":"regular-box","boxType":"dinf","boxSize":36,"children":[],"offset":39049321},{"type":"regular-box","boxType":"stbl","boxSize":6928,"children":[{"type":"stsd-box","boxSize":309,"offset":39049365,"numberOfEntries":1,"samples":[{"format":"hvc1","offset":39049381,"dataReferenceIndex":1,"version":0,"revisionLevel":0,"vendor":[0,0,0,0],"size":293,"type":"video","width":3840,"height":2160,"horizontalResolutionPpi":72,"verticalResolutionPpi":72,"spacialQuality":512,"temporalQuality":512,"dataSize":0,"frameCountPerSample":1,"compressorName":[4,72,69,86,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"depth":24,"colorTableId":-1}]},{"type":"regular-box","boxType":"sgpd","boxSize":104,"children":[],"offset":39049674},{"type":"regular-box","boxType":"sgpd","boxSize":26,"children":[],"offset":39049778},{"type":"regular-box","boxType":"sgpd","boxSize":28,"children":[],"offset":39049804},{"type":"regular-box","boxType":"sbgp","boxSize":212,"children":[],"offset":39049832},{"type":"regular-box","boxType":"csgm","boxSize":71,"children":[],"offset":39050044},{"type":"regular-box","boxType":"csgm","boxSize":249,"children":[],"offset":39050115},{"type":"stts-box","sampleDistribution":[{"sampleCount":269,"sampleDelta":20},{"sampleCount":1,"sampleDelta":21},{"sampleCount":107,"sampleDelta":20}]},{"type":"regular-box","boxType":"ctts","boxSize":3032,"children":[],"offset":39050404},{"type":"regular-box","boxType":"cslg","boxSize":32,"children":[],"offset":39053436},{"type":"regular-box","boxType":"stss","boxSize":64,"children":[],"offset":39053468},{"type":"regular-box","boxType":"sdtp","boxSize":389,"children":[],"offset":39053532},{"type":"regular-box","boxType":"stsc","boxSize":616,"children":[],"offset":39053921},{"type":"regular-box","boxType":"stsz","boxSize":1528,"children":[],"offset":39054537},{"type":"regular-box","boxType":"stco","boxSize":220,"children":[],"offset":39056065}],"offset":39049357}],"offset":39049237}],"offset":39049148}]},{"offset":39056285,"boxSize":3190,"type":"trak-box","children":[{"offset":39056293,"boxSize":92,"type":"tkhd-box","creationTime":1686832959000,"modificationTime":1686832973000,"trackId":2,"duration":7540,"layer":0,"alternateGroup":0,"volume":256,"matrix":[65536,0,0,0,65536,0,0,0,1073741824],"width":0,"height":0,"version":0},{"type":"regular-box","boxType":"edts","boxSize":36,"children":[],"offset":39056385},{"type":"regular-box","boxType":"mdia","boxSize":3054,"children":[{"type":"mdhd-box","duration":557056,"timescale":44100,"version":0,"language":21956,"quality":0},{"type":"regular-box","boxType":"hdlr","boxSize":49,"children":[],"offset":39056461},{"type":"regular-box","boxType":"minf","boxSize":2965,"children":[{"type":"regular-box","boxType":"smhd","boxSize":16,"children":[],"offset":39056518},{"type":"regular-box","boxType":"hdlr","boxSize":56,"children":[],"offset":39056534},{"type":"regular-box","boxType":"dinf","boxSize":36,"children":[],"offset":39056590},{"type":"regular-box","boxType":"stbl","boxSize":2849,"children":[{"type":"stsd-box","boxSize":159,"offset":39056634,"numberOfEntries":1,"samples":[{"format":"mp4a","offset":39056650,"dataReferenceIndex":1,"version":1,"revisionLevel":0,"vendor":[0,0,0,0],"size":143,"type":"audio","numberOfChannels":2,"sampleSize":16,"compressionId":-2,"packetSize":0,"sampleRate":44100,"samplesPerPacket":1024,"bytesPerPacket":1,"bytesPerFrame":2,"bitsPerSample":2,"children":[{"type":"regular-box","boxType":"wave","boxSize":91,"children":[{"type":"regular-box","boxType":"frma","boxSize":12,"children":[],"offset":39056710},{"type":"regular-box","boxType":"mp4a","boxSize":12,"children":[],"offset":39056722},{"type":"esds-box","version":0,"tag":3,"sizeOfInstance":34,"esId":0,"descriptors":[{"type":"decoder-config-descriptor","objectTypeIndication":"aac"},{"type":"sl-config-descriptor"}]},{"type":"regular-box","boxType":"\u0000\u0000\u0000\u0000","boxSize":8,"children":[],"offset":39056785}],"offset":39056702}]}]},{"type":"regular-box","boxType":"sgpd","boxSize":26,"children":[],"offset":39056793},{"type":"regular-box","boxType":"sbgp","boxSize":28,"children":[],"offset":39056819},{"type":"stts-box","sampleDistribution":[{"sampleCount":544,"sampleDelta":1024}]},{"type":"regular-box","boxType":"stsc","boxSize":292,"children":[],"offset":39056871},{"type":"regular-box","boxType":"stsz","boxSize":2196,"children":[],"offset":39057163},{"type":"regular-box","boxType":"stco","boxSize":116,"children":[],"offset":39059359}],"offset":39056626}],"offset":39056510}],"offset":39056421}]},{"offset":39059475,"boxSize":629,"type":"trak-box","children":[{"offset":39059483,"boxSize":92,"type":"tkhd-box","creationTime":1686832959000,"modificationTime":1686832973000,"trackId":3,"duration":7541,"layer":0,"alternateGroup":0,"volume":0,"matrix":[65536,0,0,0,65536,0,0,0,1073741824],"width":0,"height":0,"version":0},{"type":"regular-box","boxType":"edts","boxSize":36,"children":[],"offset":39059575},{"type":"regular-box","boxType":"tref","boxSize":32,"children":[],"offset":39059611},{"type":"regular-box","boxType":"mdia","boxSize":461,"children":[{"type":"mdhd-box","duration":7541,"timescale":600,"version":0,"language":21956,"quality":0},{"type":"regular-box","boxType":"hdlr","boxSize":52,"children":[],"offset":39059683},{"type":"regular-box","boxType":"minf","boxSize":369,"children":[{"type":"regular-box","boxType":"gmhd","boxSize":32,"children":[],"offset":39059743},{"type":"regular-box","boxType":"hdlr","boxSize":56,"children":[],"offset":39059775},{"type":"regular-box","boxType":"dinf","boxSize":36,"children":[],"offset":39059831},{"type":"regular-box","boxType":"stbl","boxSize":237,"children":[{"type":"stsd-box","boxSize":133,"offset":39059875,"numberOfEntries":1,"samples":[{"type":"unknown","offset":39059891,"dataReferenceIndex":1,"version":0,"revisionLevel":101,"vendor":[107,101,121,115],"size":117,"format":"mebx"}]},{"type":"stts-box","sampleDistribution":[{"sampleCount":1,"sampleDelta":7541}]},{"type":"regular-box","boxType":"stsc","boxSize":28,"children":[],"offset":39060032},{"type":"regular-box","boxType":"stsz","boxSize":24,"children":[],"offset":39060060},{"type":"regular-box","boxType":"stco","boxSize":20,"children":[],"offset":39060084}],"offset":39059867}],"offset":39059735}],"offset":39059643}]},{"offset":39060104,"boxSize":1074,"type":"trak-box","children":[{"offset":39060112,"boxSize":92,"type":"tkhd-box","creationTime":1686832959000,"modificationTime":1686832973000,"trackId":4,"duration":7541,"layer":0,"alternateGroup":0,"volume":0,"matrix":[65536,0,0,0,65536,0,0,0,1073741824],"width":0,"height":0,"version":0},{"type":"regular-box","boxType":"edts","boxSize":36,"children":[],"offset":39060204},{"type":"regular-box","boxType":"tref","boxSize":32,"children":[],"offset":39060240},{"type":"regular-box","boxType":"mdia","boxSize":906,"children":[{"type":"mdhd-box","duration":7541,"timescale":600,"version":0,"language":21956,"quality":0},{"type":"regular-box","boxType":"hdlr","boxSize":52,"children":[],"offset":39060312},{"type":"regular-box","boxType":"minf","boxSize":814,"children":[{"type":"regular-box","boxType":"gmhd","boxSize":32,"children":[],"offset":39060372},{"type":"regular-box","boxType":"hdlr","boxSize":56,"children":[],"offset":39060404},{"type":"regular-box","boxType":"dinf","boxSize":36,"children":[],"offset":39060460},{"type":"regular-box","boxType":"stbl","boxSize":682,"children":[{"type":"stsd-box","boxSize":578,"offset":39060504,"numberOfEntries":1,"samples":[{"type":"unknown","offset":39060520,"dataReferenceIndex":1,"version":0,"revisionLevel":502,"vendor":[107,101,121,115],"size":562,"format":"mebx"}]},{"type":"stts-box","sampleDistribution":[{"sampleCount":1,"sampleDelta":7541}]},{"type":"regular-box","boxType":"stsc","boxSize":28,"children":[],"offset":39061106},{"type":"regular-box","boxType":"stsz","boxSize":24,"children":[],"offset":39061134},{"type":"regular-box","boxType":"stco","boxSize":20,"children":[],"offset":39061158}],"offset":39060496}],"offset":39060364}],"offset":39060272}]},{"offset":39061178,"boxSize":1218,"type":"trak-box","children":[{"offset":39061186,"boxSize":92,"type":"tkhd-box","creationTime":1686832959000,"modificationTime":1686832973000,"trackId":5,"duration":7541,"layer":0,"alternateGroup":0,"volume":0,"matrix":[65536,0,0,0,65536,0,0,0,1073741824],"width":0,"height":0,"version":0},{"type":"regular-box","boxType":"edts","boxSize":36,"children":[],"offset":39061278},{"type":"regular-box","boxType":"tref","boxSize":32,"children":[],"offset":39061314},{"type":"regular-box","boxType":"mdia","boxSize":1050,"children":[{"type":"mdhd-box","duration":7541,"timescale":600,"version":0,"language":21956,"quality":0},{"type":"regular-box","boxType":"hdlr","boxSize":52,"children":[],"offset":39061386},{"type":"regular-box","boxType":"minf","boxSize":958,"children":[{"type":"regular-box","boxType":"gmhd","boxSize":32,"children":[],"offset":39061446},{"type":"regular-box","boxType":"hdlr","boxSize":56,"children":[],"offset":39061478},{"type":"regular-box","boxType":"dinf","boxSize":36,"children":[],"offset":39061534},{"type":"regular-box","boxType":"stbl","boxSize":826,"children":[{"type":"stsd-box","boxSize":598,"offset":39061578,"numberOfEntries":1,"samples":[{"type":"unknown","offset":39061594,"dataReferenceIndex":1,"version":0,"revisionLevel":566,"vendor":[107,101,121,115],"size":582,"format":"mebx"}]},{"type":"stts-box","sampleDistribution":[{"sampleCount":269,"sampleDelta":20},{"sampleCount":1,"sampleDelta":21},{"sampleCount":107,"sampleDelta":20}]},{"type":"regular-box","boxType":"stsc","boxSize":40,"children":[],"offset":39062216},{"type":"regular-box","boxType":"stsz","boxSize":20,"children":[],"offset":39062256},{"type":"regular-box","boxType":"stco","boxSize":120,"children":[],"offset":39062276}],"offset":39061570}],"offset":39061438}],"offset":39061346}]},{"type":"regular-box","boxType":"meta","boxSize":532,"children":[],"offset":39062396}]}]
@@ -0,0 +1,21 @@
1
+ import type { BufferIterator } from '../../../buffer-iterator';
2
+ type AudioObjectType = 'aac' | 'mp3' | 'unknown';
3
+ type DecoderConfigDescriptor = {
4
+ type: 'decoder-config-descriptor';
5
+ objectTypeIndication: AudioObjectType;
6
+ };
7
+ type SlConfigDescriptor = {
8
+ type: 'sl-config-descriptor';
9
+ };
10
+ type UnknownDescriptor = {
11
+ type: 'unknown-descriptor';
12
+ };
13
+ export type Descriptor = DecoderConfigDescriptor | SlConfigDescriptor | UnknownDescriptor;
14
+ type DescriptorAndNext = {
15
+ descriptor: Descriptor | null;
16
+ };
17
+ export declare const processDescriptor: ({ iterator, }: {
18
+ iterator: BufferIterator;
19
+ }) => DescriptorAndNext;
20
+ export declare const parseDescriptors: (iterator: BufferIterator, maxBytes: number) => Descriptor[];
21
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseDescriptors = exports.processDescriptor = void 0;
4
+ const mapToObjectAudioIndicator = (num) => {
5
+ // https://chromium.googlesource.com/chromium/src/media/+/master/formats/mp4/es_descriptor.h
6
+ // http://netmedia.zju.edu.cn/multimedia2013/mpeg-4/ISO%20IEC%2014496-1%20MPEG-4%20System%20Standard.pdf
7
+ // Page 42, table 8
8
+ if (num === 0x40) {
9
+ return 'aac';
10
+ }
11
+ if (num === 0x6b) {
12
+ return 'mp3';
13
+ }
14
+ return 'unknown';
15
+ };
16
+ const processDescriptor = ({ iterator, }) => {
17
+ const tag = iterator.getUint8();
18
+ if (tag === 4) {
19
+ const size = iterator.getPaddedFourByteNumber();
20
+ const initialOffset = iterator.counter.getOffset();
21
+ const objectTypeIndication = iterator.getUint8();
22
+ const remaining = size - (iterator.counter.getOffset() - initialOffset);
23
+ iterator.discard(remaining);
24
+ return {
25
+ descriptor: {
26
+ type: 'decoder-config-descriptor',
27
+ objectTypeIndication: mapToObjectAudioIndicator(objectTypeIndication),
28
+ },
29
+ };
30
+ }
31
+ if (tag === 6) {
32
+ const size = iterator.getPaddedFourByteNumber();
33
+ iterator.discard(size);
34
+ return {
35
+ descriptor: {
36
+ type: 'sl-config-descriptor',
37
+ },
38
+ };
39
+ }
40
+ return {
41
+ descriptor: null,
42
+ };
43
+ };
44
+ exports.processDescriptor = processDescriptor;
45
+ const parseDescriptors = (iterator, maxBytes) => {
46
+ const descriptors = [];
47
+ const initialOffset = iterator.counter.getOffset();
48
+ while (iterator.bytesRemaining() > 0 &&
49
+ iterator.counter.getOffset() - initialOffset < maxBytes) {
50
+ const { descriptor } = (0, exports.processDescriptor)({
51
+ iterator,
52
+ });
53
+ if (descriptor) {
54
+ descriptors.push(descriptor);
55
+ }
56
+ else {
57
+ break;
58
+ }
59
+ }
60
+ return descriptors;
61
+ };
62
+ exports.parseDescriptors = parseDescriptors;
@@ -0,0 +1,15 @@
1
+ import type { BufferIterator } from '../../../buffer-iterator';
2
+ import type { Descriptor } from './esds-descriptors';
3
+ export interface EsdsBox {
4
+ type: 'esds-box';
5
+ version: number;
6
+ tag: number;
7
+ sizeOfInstance: number;
8
+ esId: number;
9
+ descriptors: Descriptor[];
10
+ }
11
+ export declare const parseEsds: ({ data, size, fileOffset, }: {
12
+ data: BufferIterator;
13
+ size: number;
14
+ fileOffset: number;
15
+ }) => EsdsBox;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseEsds = void 0;
4
+ const esds_descriptors_1 = require("./esds-descriptors");
5
+ const parseEsds = ({ data, size, fileOffset, }) => {
6
+ const version = data.getUint8();
7
+ // Flags, we discard them
8
+ data.discard(3);
9
+ const tag = data.getUint8();
10
+ const sizeOfInstance = data.getPaddedFourByteNumber();
11
+ const esId = data.getUint16();
12
+ // disard 1 byte, currently unknown
13
+ data.discard(1);
14
+ const remaining = size - (data.counter.getOffset() - fileOffset);
15
+ const descriptors = (0, esds_descriptors_1.parseDescriptors)(data, remaining);
16
+ const remainingNow = size - (data.counter.getOffset() - fileOffset);
17
+ data.discard(remainingNow);
18
+ return {
19
+ type: 'esds-box',
20
+ version,
21
+ tag,
22
+ sizeOfInstance,
23
+ esId,
24
+ descriptors,
25
+ };
26
+ };
27
+ exports.parseEsds = parseEsds;
@@ -0,0 +1,21 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ type AudioObjectType = 'aac' | 'mp3' | 'unknown';
3
+ type DecoderConfigDescriptor = {
4
+ type: 'decoder-config-descriptor';
5
+ objectTypeIndication: AudioObjectType;
6
+ };
7
+ type SlConfigDescriptor = {
8
+ type: 'sl-config-descriptor';
9
+ };
10
+ type UnknownDescriptor = {
11
+ type: 'unknown-descriptor';
12
+ };
13
+ export type Descriptor = DecoderConfigDescriptor | SlConfigDescriptor | UnknownDescriptor;
14
+ type DescriptorAndNext = {
15
+ descriptor: Descriptor | null;
16
+ };
17
+ export declare const processDescriptor: ({ iterator, }: {
18
+ iterator: BufferIterator;
19
+ }) => DescriptorAndNext;
20
+ export declare const parseDescriptors: (iterator: BufferIterator, maxBytes: number) => Descriptor[];
21
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseDescriptors = exports.processDescriptor = void 0;
4
+ const mapToObjectAudioIndicator = (num) => {
5
+ // https://chromium.googlesource.com/chromium/src/media/+/master/formats/mp4/es_descriptor.h
6
+ // http://netmedia.zju.edu.cn/multimedia2013/mpeg-4/ISO%20IEC%2014496-1%20MPEG-4%20System%20Standard.pdf
7
+ // Page 42, table 8
8
+ if (num === 0x40) {
9
+ return 'aac';
10
+ }
11
+ if (num === 0x6b) {
12
+ return 'mp3';
13
+ }
14
+ return 'unknown';
15
+ };
16
+ const processDescriptor = ({ iterator, }) => {
17
+ const tag = iterator.getUint8();
18
+ if (tag === 4) {
19
+ const size = iterator.getPaddedFourByteNumber();
20
+ const initialOffset = iterator.counter.getOffset();
21
+ const objectTypeIndication = iterator.getUint8();
22
+ const remaining = size - (iterator.counter.getOffset() - initialOffset);
23
+ iterator.discard(remaining);
24
+ return {
25
+ descriptor: {
26
+ type: 'decoder-config-descriptor',
27
+ objectTypeIndication: mapToObjectAudioIndicator(objectTypeIndication),
28
+ },
29
+ };
30
+ }
31
+ if (tag === 6) {
32
+ const size = iterator.getPaddedFourByteNumber();
33
+ iterator.discard(size);
34
+ return {
35
+ descriptor: {
36
+ type: 'sl-config-descriptor',
37
+ },
38
+ };
39
+ }
40
+ return {
41
+ descriptor: null,
42
+ };
43
+ };
44
+ exports.processDescriptor = processDescriptor;
45
+ const parseDescriptors = (iterator, maxBytes) => {
46
+ const descriptors = [];
47
+ const initialOffset = iterator.counter.getOffset();
48
+ while (iterator.bytesRemaining() > 0 &&
49
+ iterator.counter.getOffset() - initialOffset < maxBytes) {
50
+ const { descriptor } = (0, exports.processDescriptor)({
51
+ iterator,
52
+ });
53
+ if (descriptor) {
54
+ descriptors.push(descriptor);
55
+ }
56
+ else {
57
+ break;
58
+ }
59
+ }
60
+ return descriptors;
61
+ };
62
+ exports.parseDescriptors = parseDescriptors;
@@ -0,0 +1,15 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ import type { Descriptor } from './esds-descriptors';
3
+ export interface EsdsBox {
4
+ type: 'esds-box';
5
+ version: number;
6
+ tag: number;
7
+ sizeOfInstance: number;
8
+ esId: number;
9
+ descriptors: Descriptor[];
10
+ }
11
+ export declare const parseEsds: ({ data, size, fileOffset, }: {
12
+ data: BufferIterator;
13
+ size: number;
14
+ fileOffset: number;
15
+ }) => EsdsBox;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseEsds = void 0;
4
+ const esds_descriptors_1 = require("./esds-descriptors");
5
+ const parseEsds = ({ data, size, fileOffset, }) => {
6
+ const version = data.getUint8();
7
+ // Flags, we discard them
8
+ data.discard(3);
9
+ const tag = data.getUint8();
10
+ const sizeOfInstance = data.getPaddedFourByteNumber();
11
+ const esId = data.getUint16();
12
+ // disard 1 byte, currently unknown
13
+ data.discard(1);
14
+ const remaining = size - (data.counter.getOffset() - fileOffset);
15
+ const descriptors = (0, esds_descriptors_1.parseDescriptors)(data, remaining);
16
+ const remainingNow = size - (data.counter.getOffset() - fileOffset);
17
+ data.discard(remainingNow);
18
+ return {
19
+ type: 'esds-box',
20
+ version,
21
+ tag,
22
+ sizeOfInstance,
23
+ esId,
24
+ descriptors,
25
+ };
26
+ };
27
+ exports.parseEsds = parseEsds;
@@ -0,0 +1,12 @@
1
+ import type { BufferIterator } from '../../../buffer-iterator';
2
+ import type { AnySegment } from '../../../parse-result';
3
+ export interface MdatBox {
4
+ type: 'mdat-box';
5
+ boxSize: number;
6
+ }
7
+ export declare const parseMdat: ({ data, size, fileOffset, }: {
8
+ data: BufferIterator;
9
+ size: number;
10
+ fileOffset: number;
11
+ existingBoxes: AnySegment[];
12
+ }) => MdatBox;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseMdat = void 0;
4
+ const parseMdat = ({ data, size, fileOffset, }) => {
5
+ // TODO: Do something cool with it
6
+ // const tracks = getTracks(existingBoxes);
7
+ data.discard(size - (data.counter.getOffset() - fileOffset));
8
+ return {
9
+ type: 'mdat-box',
10
+ boxSize: size,
11
+ };
12
+ };
13
+ exports.parseMdat = parseMdat;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseBoxes = void 0;
4
+ const esds_1 = require("./esds/esds");
4
5
  const ftyp_1 = require("./ftyp");
5
6
  const mdhd_1 = require("./mdhd");
6
7
  const moov_1 = require("./moov/moov");
@@ -15,6 +16,7 @@ const getChildren = ({ boxType, iterator, bytesRemainingInBox, }) => {
15
16
  boxType === 'minf' ||
16
17
  boxType === 'stbl' ||
17
18
  boxType === 'dims' ||
19
+ boxType === 'wave' ||
18
20
  boxType === 'stsb';
19
21
  if (parseChildren) {
20
22
  const parsed = (0, exports.parseBoxes)({
@@ -28,6 +30,9 @@ const getChildren = ({ boxType, iterator, bytesRemainingInBox, }) => {
28
30
  }
29
31
  return parsed.segments;
30
32
  }
33
+ if (bytesRemainingInBox < 0) {
34
+ throw new Error('Box size is too big ' + JSON.stringify({ boxType }));
35
+ }
31
36
  iterator.discard(bytesRemainingInBox);
32
37
  return [];
33
38
  };
@@ -39,6 +44,29 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
39
44
  throw new Error(`Expected box size of not 0, got ${boxSize}`);
40
45
  }
41
46
  if (bytesRemaining < boxSize) {
47
+ if (bytesRemaining >= 4) {
48
+ const type = iterator.getByteString(4);
49
+ iterator.counter.decrement(4);
50
+ if (type === 'mdat') {
51
+ const skipTo = fileOffset + boxSize;
52
+ const bytesToSkip = skipTo - iterator.counter.getOffset();
53
+ // If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
54
+ if (bytesToSkip > 1000000) {
55
+ return {
56
+ type: 'complete',
57
+ box: {
58
+ type: 'regular-box',
59
+ boxType: 'mdat',
60
+ children: [],
61
+ boxSize,
62
+ offset: fileOffset,
63
+ },
64
+ size: boxSize,
65
+ skipTo: fileOffset + boxSize,
66
+ };
67
+ }
68
+ }
69
+ }
42
70
  iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
43
71
  if (allowIncompleteBoxes) {
44
72
  return {
@@ -54,6 +82,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
54
82
  type: 'complete',
55
83
  box,
56
84
  size: boxSize,
85
+ skipTo: null,
57
86
  };
58
87
  }
59
88
  if (boxType === 'mvhd') {
@@ -62,6 +91,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
62
91
  type: 'complete',
63
92
  box,
64
93
  size: boxSize,
94
+ skipTo: null,
65
95
  };
66
96
  }
67
97
  if (boxType === 'tkhd') {
@@ -70,6 +100,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
70
100
  type: 'complete',
71
101
  box,
72
102
  size: boxSize,
103
+ skipTo: null,
73
104
  };
74
105
  }
75
106
  if (boxType === 'stsd') {
@@ -78,6 +109,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
78
109
  type: 'complete',
79
110
  box,
80
111
  size: boxSize,
112
+ skipTo: null,
81
113
  };
82
114
  }
83
115
  if (boxType === 'mebx') {
@@ -86,6 +118,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
86
118
  type: 'complete',
87
119
  box,
88
120
  size: boxSize,
121
+ skipTo: null,
89
122
  };
90
123
  }
91
124
  if (boxType === 'moov') {
@@ -94,6 +127,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
94
127
  type: 'complete',
95
128
  box,
96
129
  size: boxSize,
130
+ skipTo: null,
97
131
  };
98
132
  }
99
133
  if (boxType === 'trak') {
@@ -106,6 +140,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
106
140
  type: 'complete',
107
141
  box,
108
142
  size: boxSize,
143
+ skipTo: null,
109
144
  };
110
145
  }
111
146
  if (boxType === 'stts') {
@@ -118,6 +153,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
118
153
  type: 'complete',
119
154
  box,
120
155
  size: boxSize,
156
+ skipTo: null,
121
157
  };
122
158
  }
123
159
  if (boxType === 'mdhd') {
@@ -130,6 +166,20 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
130
166
  type: 'complete',
131
167
  box,
132
168
  size: boxSize,
169
+ skipTo: null,
170
+ };
171
+ }
172
+ if (boxType === 'esds') {
173
+ const box = (0, esds_1.parseEsds)({
174
+ data: iterator,
175
+ size: boxSize,
176
+ fileOffset,
177
+ });
178
+ return {
179
+ type: 'complete',
180
+ box,
181
+ size: boxSize,
182
+ skipTo: null,
133
183
  };
134
184
  }
135
185
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
@@ -148,6 +198,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
148
198
  offset: fileOffset,
149
199
  },
150
200
  size: boxSize,
201
+ skipTo: null,
151
202
  };
152
203
  };
153
204
  const parseBoxes = ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, }) => {
@@ -174,9 +225,25 @@ const parseBoxes = ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, })
174
225
  initialBoxes: boxes,
175
226
  });
176
227
  },
228
+ skipTo: null,
177
229
  };
178
230
  }
179
231
  boxes.push(result.box);
232
+ if (result.skipTo !== null) {
233
+ return {
234
+ status: 'incomplete',
235
+ segments: boxes,
236
+ continueParsing: () => {
237
+ return (0, exports.parseBoxes)({
238
+ iterator,
239
+ maxBytes,
240
+ allowIncompleteBoxes,
241
+ initialBoxes: boxes,
242
+ });
243
+ },
244
+ skipTo: result.skipTo,
245
+ };
246
+ }
180
247
  iterator.discardFirstBytes();
181
248
  }
182
249
  return {
@@ -1,4 +1,5 @@
1
1
  import type { BufferIterator } from '../../../buffer-iterator';
2
+ import type { AnySegment } from '../../../parse-result';
2
3
  type SampleBase = {
3
4
  format: string;
4
5
  offset: number;
@@ -19,6 +20,7 @@ type AudioSample = SampleBase & {
19
20
  bytesPerPacket: number | null;
20
21
  bytesPerFrame: number | null;
21
22
  bitsPerSample: number | null;
23
+ children: AnySegment[];
22
24
  };
23
25
  type VideoSample = SampleBase & {
24
26
  type: 'video';
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseSamples = exports.processSample = void 0;
4
+ const process_box_1 = require("../process-box");
4
5
  // https://developer.apple.com/documentation/quicktime-file-format/video_sample_description
5
6
  const videoTags = [
6
7
  'cvid',
@@ -99,7 +100,15 @@ const processSample = ({ iterator, }) => {
99
100
  const packetSize = iterator.getUint16();
100
101
  const sampleRate = iterator.getFixedPoint1616Number();
101
102
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
102
- iterator.discard(bytesRemainingInBox);
103
+ const children = (0, process_box_1.parseBoxes)({
104
+ iterator,
105
+ allowIncompleteBoxes: false,
106
+ maxBytes: bytesRemainingInBox,
107
+ initialBoxes: [],
108
+ });
109
+ if (children.status === 'incomplete') {
110
+ throw new Error('Incomplete boxes are not allowed');
111
+ }
103
112
  return {
104
113
  sample: {
105
114
  format: boxFormat,
@@ -119,21 +128,30 @@ const processSample = ({ iterator, }) => {
119
128
  bytesPerPacket: null,
120
129
  bytesPerFrame: null,
121
130
  bitsPerSample: null,
131
+ children: children.segments,
122
132
  },
123
133
  };
124
134
  }
125
135
  if (version === 1) {
126
136
  const numberOfChannels = iterator.getUint16();
127
137
  const sampleSize = iterator.getUint16();
128
- const compressionId = iterator.getUint16();
138
+ const compressionId = iterator.getInt16();
129
139
  const packetSize = iterator.getUint16();
130
140
  const sampleRate = iterator.getFixedPoint1616Number();
131
- const samplesPerPacket = iterator.getUint16();
132
- const bytesPerPacket = iterator.getUint16();
133
- const bytesPerFrame = iterator.getUint16();
134
- const bitsPerSample = iterator.getUint16();
141
+ const samplesPerPacket = iterator.getUint32();
142
+ const bytesPerPacket = iterator.getUint32();
143
+ const bytesPerFrame = iterator.getUint32();
144
+ const bytesPerSample = iterator.getUint32();
135
145
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
136
- iterator.discard(bytesRemainingInBox);
146
+ const children = (0, process_box_1.parseBoxes)({
147
+ iterator,
148
+ allowIncompleteBoxes: false,
149
+ maxBytes: bytesRemainingInBox,
150
+ initialBoxes: [],
151
+ });
152
+ if (children.status === 'incomplete') {
153
+ throw new Error('Incomplete boxes are not allowed');
154
+ }
137
155
  return {
138
156
  sample: {
139
157
  format: boxFormat,
@@ -152,7 +170,8 @@ const processSample = ({ iterator, }) => {
152
170
  samplesPerPacket,
153
171
  bytesPerPacket,
154
172
  bytesPerFrame,
155
- bitsPerSample,
173
+ bitsPerSample: bytesPerSample,
174
+ children: children.segments,
156
175
  },
157
176
  };
158
177
  }
@@ -0,0 +1,14 @@
1
+ import type { BufferIterator } from '../../../buffer-iterator';
2
+ import type { BaseBox } from '../base-type';
3
+ export interface StcoBox extends BaseBox {
4
+ type: 'stco-box';
5
+ version: number;
6
+ flags: number[];
7
+ entryCount: number;
8
+ entries: number[];
9
+ }
10
+ export declare const parseStco: ({ iterator, offset, size, }: {
11
+ iterator: BufferIterator;
12
+ offset: number;
13
+ size: number;
14
+ }) => StcoBox;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseStco = void 0;
4
+ const parseStco = ({ iterator, offset, size, }) => {
5
+ const version = iterator.getUint8();
6
+ if (version !== 0) {
7
+ throw new Error(`Unsupported STSD version ${version}`);
8
+ }
9
+ const flags = iterator.getSlice(3);
10
+ const entryCount = iterator.getUint32();
11
+ const entries = [];
12
+ for (let i = 0; i < entryCount; i++) {
13
+ const bytesRemaining = size - (iterator.counter.getOffset() - offset);
14
+ if (bytesRemaining < 4) {
15
+ break;
16
+ }
17
+ entries.push(iterator.getUint32());
18
+ }
19
+ iterator.discard(size - (iterator.counter.getOffset() - offset));
20
+ return {
21
+ type: 'stco-box',
22
+ boxSize: size,
23
+ offset,
24
+ version,
25
+ flags: [...flags],
26
+ entries,
27
+ entryCount,
28
+ };
29
+ };
30
+ exports.parseStco = parseStco;
@@ -0,0 +1,19 @@
1
+ import type { BufferIterator } from '../../../buffer-iterator';
2
+ import type { BaseBox } from '../base-type';
3
+ type StscEntry = {
4
+ firstChunk: number;
5
+ samplesPerChunk: number;
6
+ };
7
+ export interface StscBox extends BaseBox {
8
+ type: 'stsc-box';
9
+ version: number;
10
+ flags: number[];
11
+ entryCount: number;
12
+ entries: StscEntry[];
13
+ }
14
+ export declare const parseStsc: ({ iterator, offset, size, }: {
15
+ iterator: BufferIterator;
16
+ offset: number;
17
+ size: number;
18
+ }) => StscBox;
19
+ export {};