@remotion/media-parser 4.0.199 → 4.0.201

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 (117) hide show
  1. package/dist/av1-codec-string.d.ts +5 -0
  2. package/dist/av1-codec-string.js +18 -1
  3. package/dist/bitstream/av1.d.ts +2 -0
  4. package/dist/bitstream/av1.js +12 -0
  5. package/dist/boxes/iso-base-media/avcc-hvcc.d.ts +20 -0
  6. package/dist/boxes/iso-base-media/avcc-hvcc.js +73 -0
  7. package/dist/boxes/iso-base-media/avcc.d.ts +18 -0
  8. package/dist/boxes/iso-base-media/avcc.js +27 -0
  9. package/dist/boxes/iso-base-media/esds-descriptors.d.ts +21 -0
  10. package/dist/boxes/iso-base-media/esds-descriptors.js +62 -0
  11. package/dist/boxes/iso-base-media/esds.d.ts +15 -0
  12. package/dist/boxes/iso-base-media/esds.js +27 -0
  13. package/dist/boxes/iso-base-media/mdat/mdat.js +2 -2
  14. package/dist/boxes/iso-base-media/moov/moov.js +1 -0
  15. package/dist/boxes/iso-base-media/process-box.d.ts +4 -2
  16. package/dist/boxes/iso-base-media/process-box.js +56 -40
  17. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +2 -1
  18. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
  19. package/dist/boxes/iso-base-media/stsd/samples.js +3 -0
  20. package/dist/boxes/iso-base-media/stsd/stco.d.ts +3 -2
  21. package/dist/boxes/iso-base-media/stsd/stco.js +2 -2
  22. package/dist/boxes/iso-base-media/trak/trak.js +1 -0
  23. package/dist/boxes/webm/bitstream/av1.js +10 -1
  24. package/dist/boxes/webm/ebml.d.ts +2 -0
  25. package/dist/boxes/webm/ebml.js +72 -0
  26. package/dist/boxes/webm/make-header.d.ts +9 -0
  27. package/dist/boxes/webm/make-header.js +79 -0
  28. package/dist/boxes/webm/parse-ebml.d.ts +7 -0
  29. package/dist/boxes/webm/parse-ebml.js +66 -0
  30. package/dist/boxes/webm/parse-webm-header.js +8 -9
  31. package/dist/boxes/webm/segments/all-segments.d.ts +262 -0
  32. package/dist/boxes/webm/segments/all-segments.js +130 -1
  33. package/dist/boxes/webm/segments/block-simple-block-flags.d.ts +9 -0
  34. package/dist/boxes/webm/segments/block-simple-block-flags.js +38 -0
  35. package/dist/boxes/webm/segments/seek-position.js +1 -1
  36. package/dist/boxes/webm/segments/seek.d.ts +1 -1
  37. package/dist/boxes/webm/segments/seek.js +8 -2
  38. package/dist/boxes/webm/segments/timestamp-scale.js +1 -1
  39. package/dist/boxes/webm/segments/track-entry.d.ts +25 -9
  40. package/dist/boxes/webm/segments/track-entry.js +73 -33
  41. package/dist/boxes/webm/segments.d.ts +3 -3
  42. package/dist/boxes/webm/segments.js +64 -30
  43. package/dist/boxes/webm/traversal.d.ts +1 -0
  44. package/dist/boxes/webm/traversal.js +12 -1
  45. package/dist/buffer-iterator.d.ts +10 -6
  46. package/dist/buffer-iterator.js +92 -9
  47. package/dist/from-fetch.js +13 -3
  48. package/dist/from-input-type-file.d.ts +2 -0
  49. package/dist/from-input-type-file.js +37 -0
  50. package/dist/from-node.js +9 -2
  51. package/dist/from-web-file.js +6 -1
  52. package/dist/from-web.js +15 -6
  53. package/dist/get-codec.d.ts +4 -0
  54. package/dist/get-codec.js +22 -0
  55. package/dist/get-sample-positions.js +1 -1
  56. package/dist/has-all-info.js +1 -1
  57. package/dist/options.d.ts +3 -2
  58. package/dist/parse-media.js +13 -9
  59. package/dist/parse-video.js +16 -0
  60. package/dist/parser-state.d.ts +8 -9
  61. package/dist/parser-state.js +39 -19
  62. package/dist/reader.d.ts +1 -1
  63. package/dist/web-file.d.ts +2 -0
  64. package/dist/web-file.js +37 -0
  65. package/dist/webcodec-sample-types.d.ts +0 -1
  66. package/package.json +2 -2
  67. package/src/boxes/iso-base-media/mdat/mdat.ts +2 -2
  68. package/src/boxes/iso-base-media/moov/moov.ts +1 -0
  69. package/src/boxes/iso-base-media/process-box.ts +70 -40
  70. package/src/boxes/iso-base-media/stsd/mebx.ts +3 -0
  71. package/src/boxes/iso-base-media/stsd/samples.ts +3 -0
  72. package/src/boxes/iso-base-media/stsd/stco.ts +5 -3
  73. package/src/boxes/iso-base-media/trak/trak.ts +1 -0
  74. package/src/boxes/webm/ebml.ts +78 -0
  75. package/src/boxes/webm/make-header.ts +138 -0
  76. package/src/boxes/webm/parse-ebml.ts +93 -0
  77. package/src/boxes/webm/parse-webm-header.ts +8 -12
  78. package/src/boxes/webm/segments/all-segments.ts +226 -0
  79. package/src/boxes/webm/segments/block-simple-block-flags.ts +52 -0
  80. package/src/boxes/webm/segments/seek-position.ts +1 -1
  81. package/src/boxes/webm/segments/seek.ts +12 -2
  82. package/src/boxes/webm/segments/timestamp-scale.ts +1 -1
  83. package/src/boxes/webm/segments/track-entry.ts +125 -41
  84. package/src/boxes/webm/segments.ts +107 -40
  85. package/src/boxes/webm/traversal.ts +13 -0
  86. package/src/buffer-iterator.ts +110 -10
  87. package/src/from-fetch.ts +22 -3
  88. package/src/from-node.ts +18 -4
  89. package/src/from-web-file.ts +11 -1
  90. package/src/get-sample-positions.ts +1 -1
  91. package/src/has-all-info.ts +1 -1
  92. package/src/options.ts +3 -2
  93. package/src/parse-media.ts +14 -8
  94. package/src/parse-video.ts +17 -0
  95. package/src/parser-state.ts +52 -25
  96. package/src/reader.ts +1 -0
  97. package/src/test/create-matroska.test.ts +48 -0
  98. package/src/test/matroska.test.ts +144 -127
  99. package/src/test/parse-stco.test.ts +2 -0
  100. package/src/test/stream-local.test.ts +70 -14
  101. package/src/test/stream-remote.test.ts +23 -19
  102. package/src/test/stsd.test.ts +2 -0
  103. package/src/webcodec-sample-types.ts +0 -1
  104. package/tsconfig.tsbuildinfo +1 -1
  105. package/dist/boxes/iso-base-media/ftype.d.ts +0 -9
  106. package/dist/boxes/iso-base-media/ftype.js +0 -31
  107. package/dist/get-video-metadata.d.ts +0 -2
  108. package/dist/get-video-metadata.js +0 -44
  109. package/dist/read-and-increment-offset.d.ts +0 -28
  110. package/dist/read-and-increment-offset.js +0 -177
  111. package/dist/understand-vorbis.d.ts +0 -1
  112. package/dist/understand-vorbis.js +0 -12
  113. package/src/boxes/webm/segments/unknown.ts +0 -19
  114. /package/dist/{boxes/webm/bitstream/av1/frame.d.ts → get-samples.d.ts} +0 -0
  115. /package/dist/{boxes/webm/bitstream/av1/frame.js → get-samples.js} +0 -0
  116. /package/dist/{boxes/webm/bitstream/h264/get-h264-descriptor.d.ts → sample-aspect-ratio.d.ts} +0 -0
  117. /package/dist/{boxes/webm/bitstream/h264/get-h264-descriptor.js → sample-aspect-ratio.js} +0 -0
@@ -1,3 +1,8 @@
1
1
  import type { ColorParameterBox } from './boxes/iso-base-media/stsd/colr';
2
2
  import type { Av1BitstreamHeaderSegment } from './boxes/webm/bitstream/av1/header-segment';
3
+ import type { ClusterSegment, TrackEntrySegment } from './boxes/webm/segments/track-entry';
3
4
  export declare const constructAv1CodecString: (av1BitstreamHeader: Av1BitstreamHeaderSegment, colrAtom: ColorParameterBox | null) => string;
5
+ export declare const av1CodecStringToString: ({ track, clusterSegment, }: {
6
+ track: TrackEntrySegment;
7
+ clusterSegment: ClusterSegment;
8
+ }) => string | null;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  // https://aomediacodec.github.io/av1-isobmff/#codecsparam
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.constructAv1CodecString = void 0;
4
+ exports.av1CodecStringToString = exports.constructAv1CodecString = void 0;
5
+ const traversal_1 = require("./boxes/webm/traversal");
6
+ const traversal_2 = require("./traversal");
5
7
  const constructAv1CodecString = (av1BitstreamHeader, colrAtom) => {
6
8
  let str = 'av01.';
7
9
  // Profile
@@ -89,3 +91,18 @@ const constructAv1CodecString = (av1BitstreamHeader, colrAtom) => {
89
91
  return str;
90
92
  };
91
93
  exports.constructAv1CodecString = constructAv1CodecString;
94
+ const av1CodecStringToString = ({ track, clusterSegment, }) => {
95
+ const codecSegment = (0, traversal_2.getCodecSegment)(track);
96
+ if (!codecSegment) {
97
+ throw new Error('Expected codec segment');
98
+ }
99
+ if (codecSegment.codec !== 'V_AV1') {
100
+ throw new Error(`Should not call this function if it is not AV1: ${codecSegment.codec}`);
101
+ }
102
+ const av1BitstreamHeader = (0, traversal_1.getAv1BitstreamHeader)(clusterSegment);
103
+ if (!av1BitstreamHeader) {
104
+ return null;
105
+ }
106
+ return (0, exports.constructAv1CodecString)(av1BitstreamHeader, null);
107
+ };
108
+ exports.av1CodecStringToString = av1CodecStringToString;
@@ -0,0 +1,2 @@
1
+ import type { BufferIterator } from '../buffer-iterator';
2
+ export declare const expectBitstream: (iterator: BufferIterator, size: number) => null;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expectBitstream = void 0;
4
+ const expectBitstream = (iterator, size) => {
5
+ const offset = iterator.counter.getOffset();
6
+ const firstByte = iterator.getUint8();
7
+ console.log({ firstByte, size });
8
+ const remaining = size - (iterator.counter.getOffset() - offset);
9
+ iterator.discard(remaining);
10
+ return null;
11
+ };
12
+ exports.expectBitstream = expectBitstream;
@@ -0,0 +1,20 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ export interface AvccBox {
3
+ type: 'avcc-box';
4
+ data: Uint8Array;
5
+ configurationString: string;
6
+ }
7
+ export declare const parseAvcc: ({ data, size, }: {
8
+ data: BufferIterator;
9
+ size: number;
10
+ }) => AvccBox;
11
+ export interface HvccBox {
12
+ type: 'hvcc-box';
13
+ data: Uint8Array;
14
+ configurationString: string;
15
+ }
16
+ export declare const parseHvcc: ({ data, size, offset, }: {
17
+ data: BufferIterator;
18
+ size: number;
19
+ offset: number;
20
+ }) => HvccBox;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseHvcc = exports.parseAvcc = void 0;
4
+ const parseAvcc = ({ data, size, }) => {
5
+ const confVersion = data.getUint8();
6
+ if (confVersion !== 1) {
7
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
8
+ }
9
+ const profile = data.getUint8();
10
+ const profileCompatibility = data.getUint8();
11
+ const level = data.getUint8();
12
+ const str = `${profile.toString(16).padStart(2, '0')}${profileCompatibility.toString(16).padStart(2, '0')}${level.toString(16).padStart(2, '0')}`;
13
+ data.counter.decrement(4);
14
+ return {
15
+ type: 'avcc-box',
16
+ data: data.getSlice(size - 8),
17
+ configurationString: str,
18
+ };
19
+ };
20
+ exports.parseAvcc = parseAvcc;
21
+ const parseHvcc = ({ data, size, offset, }) => {
22
+ const raw = data.getSlice(size - 8);
23
+ data.counter.decrement(size - 8);
24
+ const configurationVersion = data.getUint8();
25
+ if (configurationVersion !== 1) {
26
+ throw new Error(`Unsupported HVCC version ${configurationVersion}`);
27
+ }
28
+ const generalProfileSpaceTierFlagAndIdc = data.getUint8();
29
+ let generalProfileCompatibility = data.getUint32();
30
+ // unsigned int(2) general_profile_space;
31
+ // unsigned int(1) general_tier_flag;
32
+ // unsigned int(5) general_profile_idc;
33
+ const generalProfileSpace = generalProfileSpaceTierFlagAndIdc >> 6;
34
+ const generalTierFlag = generalProfileSpaceTierFlagAndIdc >> 5;
35
+ const generalProfileIdc = generalProfileSpaceTierFlagAndIdc >> 0;
36
+ // general_constraint_indicator_flags(48)
37
+ const generalConstraintIndicator = data.getSlice(6);
38
+ const generalLevelIdc = data.getUint8();
39
+ let reversedGeneralProfileSpace = 0;
40
+ for (let i = 0; i < 32; i++) {
41
+ reversedGeneralProfileSpace |= generalProfileCompatibility & 1;
42
+ if (i === 31)
43
+ break;
44
+ reversedGeneralProfileSpace <<= 1;
45
+ generalProfileCompatibility >>= 1;
46
+ }
47
+ const profileSpaceChar = generalProfileSpace === 0
48
+ ? ''
49
+ : generalProfileSpace === 1
50
+ ? 'A'
51
+ : generalProfileSpace === 2
52
+ ? 'B'
53
+ : 'C';
54
+ const generalTierChar = generalTierFlag === 0 ? 'L' : 'H';
55
+ let hasByte = false;
56
+ let generalConstraintString = '';
57
+ for (let i = 5; i >= 0; i--) {
58
+ if (generalConstraintIndicator[i] || hasByte) {
59
+ generalConstraintString =
60
+ generalConstraintIndicator[i].toString(16) + generalConstraintString;
61
+ hasByte = true;
62
+ }
63
+ }
64
+ const constraintString = `${profileSpaceChar}${generalProfileIdc.toString(16)}.${reversedGeneralProfileSpace.toString(16)}.${generalTierChar}${generalLevelIdc}.${generalConstraintString}`;
65
+ const remaining = size - (data.counter.getOffset() - offset);
66
+ data.discard(remaining);
67
+ return {
68
+ type: 'hvcc-box',
69
+ data: raw,
70
+ configurationString: constraintString,
71
+ };
72
+ };
73
+ exports.parseHvcc = parseHvcc;
@@ -0,0 +1,18 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ export interface AvccBox {
3
+ type: 'avcc-box';
4
+ data: Uint8Array;
5
+ configurationString: string;
6
+ }
7
+ export declare const parseAvcc: ({ data, size, }: {
8
+ data: BufferIterator;
9
+ size: number;
10
+ }) => AvccBox;
11
+ export interface HvccBox {
12
+ type: 'hvcc-box';
13
+ data: Uint8Array;
14
+ }
15
+ export declare const parseHvcc: ({ data, size, }: {
16
+ data: BufferIterator;
17
+ size: number;
18
+ }) => HvccBox;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseHvcc = exports.parseAvcc = void 0;
4
+ const parseAvcc = ({ data, size, }) => {
5
+ const confVersion = data.getUint8();
6
+ if (confVersion !== 1) {
7
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
8
+ }
9
+ const profile = data.getUint8();
10
+ const profileCompatibility = data.getUint8();
11
+ const level = data.getUint8();
12
+ const str = `${profile.toString(16).padStart(2, '0')}${profileCompatibility.toString(16).padStart(2, '0')}${level.toString(16).padStart(2, '0')}`;
13
+ data.counter.decrement(4);
14
+ return {
15
+ type: 'avcc-box',
16
+ data: data.getSlice(size - 8),
17
+ configurationString: str,
18
+ };
19
+ };
20
+ exports.parseAvcc = parseAvcc;
21
+ const parseHvcc = ({ data, size, }) => {
22
+ return {
23
+ type: 'hvcc-box',
24
+ data: data.getSlice(size - 8),
25
+ };
26
+ };
27
+ exports.parseHvcc = parseHvcc;
@@ -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;
@@ -5,7 +5,7 @@ const get_tracks_1 = require("../../../get-tracks");
5
5
  const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, }) => {
6
6
  const alreadyHas = (0, get_tracks_1.hasTracks)(existingBoxes);
7
7
  if (!alreadyHas) {
8
- data.discard(size - 8);
8
+ data.discard(size - (data.counter.getOffset() - fileOffset));
9
9
  return Promise.resolve({
10
10
  type: 'mdat-box',
11
11
  boxSize: size,
@@ -62,7 +62,6 @@ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, }) =>
62
62
  await options.parserState.onAudioSample(sampleWithIndex.track.trackId, {
63
63
  data: bytes,
64
64
  timestamp: sampleWithIndex.samplePosition.offset,
65
- offset: data.counter.getOffset(),
66
65
  trackId: sampleWithIndex.track.trackId,
67
66
  type: sampleWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
68
67
  });
@@ -83,6 +82,7 @@ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, }) =>
83
82
  });
84
83
  }
85
84
  const remaining = size - (data.counter.getOffset() - fileOffset);
85
+ data.removeBytesRead();
86
86
  if (remaining === 0) {
87
87
  break;
88
88
  }
@@ -10,6 +10,7 @@ const parseMoov = async ({ iterator, offset, size, options, }) => {
10
10
  initialBoxes: [],
11
11
  options,
12
12
  continueMdat: false,
13
+ littleEndian: false,
13
14
  });
14
15
  if (children.status === 'incomplete') {
15
16
  throw new Error('Incomplete boxes are not allowed');
@@ -9,17 +9,19 @@ export declare const parseMdatPartially: ({ iterator, boxSize, fileOffset, parse
9
9
  parsedBoxes: AnySegment[];
10
10
  options: ParserContext;
11
11
  }) => Promise<BoxAndNext>;
12
- export declare const processBox: ({ iterator, allowIncompleteBoxes, parsedBoxes, options, }: {
12
+ export declare const processBox: ({ iterator, allowIncompleteBoxes, parsedBoxes, options, littleEndian, }: {
13
13
  iterator: BufferIterator;
14
14
  allowIncompleteBoxes: boolean;
15
15
  parsedBoxes: AnySegment[];
16
16
  options: ParserContext;
17
+ littleEndian: boolean;
17
18
  }) => Promise<BoxAndNext>;
18
- export declare const parseBoxes: ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, }: {
19
+ export declare const parseBoxes: ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, littleEndian, }: {
19
20
  iterator: BufferIterator;
20
21
  maxBytes: number;
21
22
  allowIncompleteBoxes: boolean;
22
23
  initialBoxes: IsoBaseMediaBox[];
23
24
  options: ParserContext;
24
25
  continueMdat: false | PartialMdatBox;
26
+ littleEndian: boolean;
25
27
  }) => Promise<ParseResult>;
@@ -25,7 +25,7 @@ const stsz_1 = require("./stsd/stsz");
25
25
  const stts_1 = require("./stsd/stts");
26
26
  const tkhd_1 = require("./tkhd");
27
27
  const trak_1 = require("./trak/trak");
28
- const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, }) => {
28
+ const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, littleEndian, }) => {
29
29
  const parseChildren = boxType === 'mdia' ||
30
30
  boxType === 'minf' ||
31
31
  boxType === 'stbl' ||
@@ -40,6 +40,7 @@ const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, })
40
40
  initialBoxes: [],
41
41
  options,
42
42
  continueMdat: false,
43
+ littleEndian,
43
44
  });
44
45
  if (parsed.status === 'incomplete') {
45
46
  throw new Error('Incomplete boxes are not allowed');
@@ -76,12 +77,23 @@ const parseMdatPartially = async ({ iterator, boxSize, fileOffset, parsedBoxes,
76
77
  };
77
78
  };
78
79
  exports.parseMdatPartially = parseMdatPartially;
79
- const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options, }) => {
80
+ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options, littleEndian, }) => {
80
81
  var _a, _b;
81
82
  const fileOffset = iterator.counter.getOffset();
82
83
  const bytesRemaining = iterator.bytesRemaining();
83
- const boxSize = iterator.getFourByteNumber();
84
- if (boxSize === 0) {
84
+ const boxSizeRaw = iterator.getFourByteNumber(littleEndian);
85
+ // If `boxSize === 1`, the 8 bytes after the box type are the size of the box.
86
+ if ((boxSizeRaw === 1 && iterator.bytesRemaining() < 12) ||
87
+ iterator.bytesRemaining() < 4) {
88
+ iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
89
+ if (allowIncompleteBoxes) {
90
+ return {
91
+ type: 'incomplete',
92
+ };
93
+ }
94
+ throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSizeRaw}. Incomplete boxes are not allowed.`);
95
+ }
96
+ if (boxSizeRaw === 0) {
85
97
  return {
86
98
  type: 'complete',
87
99
  box: {
@@ -92,41 +104,38 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
92
104
  skipTo: null,
93
105
  };
94
106
  }
107
+ const boxType = iterator.getByteString(4);
108
+ const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber(littleEndian) : boxSizeRaw;
95
109
  if (bytesRemaining < boxSize) {
96
- if (bytesRemaining >= 4) {
97
- const type = iterator.getByteString(4);
98
- iterator.counter.decrement(4);
99
- if (type === 'mdat') {
100
- const shouldSkip = options.canSkipVideoData || !(0, get_tracks_1.hasTracks)(parsedBoxes);
101
- if (shouldSkip) {
102
- const skipTo = fileOffset + boxSize;
103
- const bytesToSkip = skipTo - iterator.counter.getOffset();
104
- // If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
105
- if (bytesToSkip > 1000000) {
106
- return {
107
- type: 'complete',
108
- box: {
109
- type: 'mdat-box',
110
- boxSize,
111
- fileOffset,
112
- samplesProcessed: false,
113
- },
114
- size: boxSize,
115
- skipTo: fileOffset + boxSize,
116
- };
117
- }
118
- }
119
- else {
120
- iterator.discard(4);
121
- return (0, exports.parseMdatPartially)({
122
- iterator,
123
- boxSize,
124
- fileOffset,
125
- parsedBoxes,
126
- options,
127
- });
110
+ if (boxType === 'mdat') {
111
+ const shouldSkip = options.canSkipVideoData || !(0, get_tracks_1.hasTracks)(parsedBoxes);
112
+ if (shouldSkip) {
113
+ const skipTo = fileOffset + boxSize;
114
+ const bytesToSkip = skipTo - iterator.counter.getOffset();
115
+ // If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
116
+ if (bytesToSkip > 1000000) {
117
+ return {
118
+ type: 'complete',
119
+ box: {
120
+ type: 'mdat-box',
121
+ boxSize,
122
+ fileOffset,
123
+ samplesProcessed: false,
124
+ },
125
+ size: boxSize,
126
+ skipTo: fileOffset + boxSize,
127
+ };
128
128
  }
129
129
  }
130
+ else {
131
+ return (0, exports.parseMdatPartially)({
132
+ iterator,
133
+ boxSize,
134
+ fileOffset,
135
+ parsedBoxes,
136
+ options,
137
+ });
138
+ }
130
139
  }
131
140
  iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
132
141
  if (allowIncompleteBoxes) {
@@ -136,7 +145,6 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
136
145
  }
137
146
  throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSize}. Incomplete boxes are not allowed.`);
138
147
  }
139
- const boxType = iterator.getByteString(4);
140
148
  if (boxType === 'ftyp') {
141
149
  const box = (0, ftyp_1.parseFtyp)({ iterator, size: boxSize, offset: fileOffset });
142
150
  return {
@@ -202,11 +210,12 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
202
210
  skipTo: null,
203
211
  };
204
212
  }
205
- if (boxType === 'stco') {
213
+ if (boxType === 'stco' || boxType === 'co64') {
206
214
  const box = (0, stco_1.parseStco)({
207
215
  iterator,
208
216
  offset: fileOffset,
209
217
  size: boxSize,
218
+ mode64Bit: boxType === 'co64',
210
219
  });
211
220
  return {
212
221
  type: 'complete',
@@ -273,6 +282,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
273
282
  offset: fileOffset,
274
283
  size: boxSize,
275
284
  options,
285
+ littleEndian,
276
286
  });
277
287
  return {
278
288
  type: 'complete',
@@ -417,6 +427,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
417
427
  iterator,
418
428
  bytesRemainingInBox,
419
429
  options,
430
+ littleEndian,
420
431
  });
421
432
  return {
422
433
  type: 'complete',
@@ -432,7 +443,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
432
443
  };
433
444
  };
434
445
  exports.processBox = processBox;
435
- const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, }) => {
446
+ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, littleEndian, }) => {
436
447
  let boxes = initialBoxes;
437
448
  const initialOffset = iterator.counter.getOffset();
438
449
  const alreadyHasMdat = boxes.find((b) => b.type === 'mdat-box');
@@ -451,6 +462,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
451
462
  allowIncompleteBoxes,
452
463
  parsedBoxes: initialBoxes,
453
464
  options,
465
+ littleEndian,
454
466
  });
455
467
  if (result.type === 'incomplete') {
456
468
  if (Number.isFinite(maxBytes)) {
@@ -467,6 +479,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
467
479
  initialBoxes: boxes,
468
480
  options,
469
481
  continueMdat: false,
482
+ littleEndian,
470
483
  });
471
484
  },
472
485
  skipTo: null,
@@ -484,6 +497,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
484
497
  initialBoxes: boxes,
485
498
  options,
486
499
  continueMdat: result,
500
+ littleEndian,
487
501
  }));
488
502
  },
489
503
  skipTo: null,
@@ -509,12 +523,13 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
509
523
  initialBoxes: boxes,
510
524
  options,
511
525
  continueMdat: false,
526
+ littleEndian,
512
527
  });
513
528
  },
514
529
  skipTo: result.skipTo,
515
530
  };
516
531
  }
517
- iterator.discardFirstBytes();
532
+ iterator.removeBytesRead();
518
533
  }
519
534
  const mdatState = (0, traversal_1.hasSkippedMdatProcessing)(boxes);
520
535
  if (mdatState.skipped && !options.canSkipVideoData) {
@@ -529,6 +544,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
529
544
  initialBoxes: boxes,
530
545
  options,
531
546
  continueMdat: false,
547
+ littleEndian,
532
548
  });
533
549
  },
534
550
  skipTo: mdatState.fileOffset,
@@ -8,9 +8,10 @@ export interface MebxBox extends BaseBox {
8
8
  format: string;
9
9
  children: AnySegment[];
10
10
  }
11
- export declare const parseMebx: ({ iterator, offset, size, options, }: {
11
+ export declare const parseMebx: ({ iterator, offset, size, options, littleEndian, }: {
12
12
  iterator: BufferIterator;
13
13
  offset: number;
14
14
  size: number;
15
15
  options: ParserContext;
16
+ littleEndian: boolean;
16
17
  }) => Promise<MebxBox>;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMebx = void 0;
4
4
  const process_box_1 = require("../process-box");
5
- const parseMebx = async ({ iterator, offset, size, options, }) => {
5
+ const parseMebx = async ({ iterator, offset, size, options, littleEndian, }) => {
6
6
  // reserved, 6 bit
7
7
  iterator.discard(6);
8
8
  const dataReferenceIndex = iterator.getUint16();
@@ -13,6 +13,7 @@ const parseMebx = async ({ iterator, offset, size, options, }) => {
13
13
  initialBoxes: [],
14
14
  options,
15
15
  continueMdat: false,
16
+ littleEndian,
16
17
  });
17
18
  if (children.status === 'incomplete') {
18
19
  throw new Error('Incomplete boxes are not allowed');
@@ -108,6 +108,7 @@ const processSample = async ({ iterator, options, }) => {
108
108
  initialBoxes: [],
109
109
  options,
110
110
  continueMdat: false,
111
+ littleEndian: false,
111
112
  });
112
113
  if (children.status === 'incomplete') {
113
114
  throw new Error('Incomplete boxes are not allowed');
@@ -153,6 +154,7 @@ const processSample = async ({ iterator, options, }) => {
153
154
  initialBoxes: [],
154
155
  options,
155
156
  continueMdat: false,
157
+ littleEndian: false,
156
158
  });
157
159
  if (children.status === 'incomplete') {
158
160
  throw new Error('Incomplete boxes are not allowed');
@@ -202,6 +204,7 @@ const processSample = async ({ iterator, options, }) => {
202
204
  initialBoxes: [],
203
205
  options,
204
206
  continueMdat: false,
207
+ littleEndian: false,
205
208
  });
206
209
  if (children.status === 'incomplete') {
207
210
  throw new Error('Incomplete boxes are not allowed');
@@ -5,10 +5,11 @@ export interface StcoBox extends BaseBox {
5
5
  version: number;
6
6
  flags: number[];
7
7
  entryCount: number;
8
- entries: number[];
8
+ entries: (number | bigint)[];
9
9
  }
10
- export declare const parseStco: ({ iterator, offset, size, }: {
10
+ export declare const parseStco: ({ iterator, offset, size, mode64Bit, }: {
11
11
  iterator: BufferIterator;
12
12
  offset: number;
13
13
  size: number;
14
+ mode64Bit: boolean;
14
15
  }) => StcoBox;