@remotion/media-parser 4.0.231 → 4.0.233

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 (115) hide show
  1. package/dist/add-avc-profile-to-track.d.ts +3 -0
  2. package/dist/add-avc-profile-to-track.js +35 -0
  3. package/dist/add-new-matroska-tracks.d.ts +6 -1
  4. package/dist/add-new-matroska-tracks.js +16 -1
  5. package/dist/boxes/avc/parse-avc.d.ts +18 -0
  6. package/dist/boxes/avc/parse-avc.js +96 -0
  7. package/dist/boxes/iso-base-media/esds/decoder-specific-config.d.ts +1 -2
  8. package/dist/boxes/iso-base-media/esds/decoder-specific-config.js +1 -5
  9. package/dist/boxes/iso-base-media/esds/esds-descriptors.d.ts +2 -4
  10. package/dist/boxes/iso-base-media/esds/esds-descriptors.js +3 -4
  11. package/dist/boxes/iso-base-media/esds/esds.d.ts +1 -3
  12. package/dist/boxes/iso-base-media/esds/esds.js +2 -2
  13. package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +7 -1
  14. package/dist/boxes/iso-base-media/make-track.js +3 -3
  15. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -2
  16. package/dist/boxes/iso-base-media/mdat/mdat.js +5 -2
  17. package/dist/boxes/iso-base-media/moov/moov.js +2 -2
  18. package/dist/boxes/iso-base-media/process-box.d.ts +5 -5
  19. package/dist/boxes/iso-base-media/process-box.js +38 -38
  20. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -2
  21. package/dist/boxes/iso-base-media/stsd/samples.d.ts +2 -2
  22. package/dist/boxes/iso-base-media/stsd/samples.js +15 -14
  23. package/dist/boxes/iso-base-media/trak/trak.js +2 -2
  24. package/dist/boxes/iso-base-media/traversal.d.ts +1 -1
  25. package/dist/boxes/riff/expect-riff-box.d.ts +16 -0
  26. package/dist/boxes/riff/expect-riff-box.js +49 -0
  27. package/dist/boxes/riff/get-tracks-from-avi.d.ts +21 -0
  28. package/dist/boxes/riff/get-tracks-from-avi.js +108 -0
  29. package/dist/boxes/riff/is-movi.d.ts +2 -0
  30. package/dist/boxes/riff/is-movi.js +12 -0
  31. package/dist/boxes/riff/parse-avih.d.ts +6 -0
  32. package/dist/boxes/riff/parse-avih.js +32 -0
  33. package/dist/boxes/riff/parse-box.d.ts +13 -0
  34. package/dist/boxes/riff/parse-box.js +113 -0
  35. package/dist/boxes/riff/parse-fmt-box.d.ts +7 -0
  36. package/dist/boxes/riff/parse-fmt-box.js +33 -0
  37. package/dist/boxes/riff/parse-list-box.d.ts +8 -0
  38. package/dist/boxes/riff/parse-list-box.js +30 -0
  39. package/dist/boxes/riff/parse-movi.d.ts +17 -0
  40. package/dist/boxes/riff/parse-movi.js +122 -0
  41. package/dist/boxes/riff/parse-riff-box.d.ts +10 -0
  42. package/dist/boxes/riff/parse-riff-box.js +33 -0
  43. package/dist/boxes/riff/parse-strf.d.ts +7 -0
  44. package/dist/boxes/riff/parse-strf.js +67 -0
  45. package/dist/boxes/riff/parse-strh.d.ts +6 -0
  46. package/dist/boxes/riff/parse-strh.js +46 -0
  47. package/dist/boxes/riff/riff-box.d.ts +81 -0
  48. package/dist/boxes/riff/riff-box.js +2 -0
  49. package/dist/boxes/riff/strf.d.ts +7 -0
  50. package/dist/boxes/riff/strf.js +67 -0
  51. package/dist/boxes/riff/timescale.d.ts +1 -0
  52. package/dist/boxes/riff/timescale.js +4 -0
  53. package/dist/boxes/riff/traversal.d.ts +8 -0
  54. package/dist/boxes/riff/traversal.js +36 -0
  55. package/dist/boxes/webm/parse-ebml.js +2 -2
  56. package/dist/boxes/webm/parse-webm-header.d.ts +2 -2
  57. package/dist/boxes/webm/parse-webm-header.js +7 -7
  58. package/dist/boxes/webm/traversal.d.ts +2 -2
  59. package/dist/buffer-iterator.d.ts +6 -1
  60. package/dist/buffer-iterator.js +24 -5
  61. package/dist/create/event-emitter.d.ts +31 -0
  62. package/dist/create/event-emitter.js +25 -0
  63. package/dist/create/iso-base-media/create-iso-base-media.d.ts +1 -1
  64. package/dist/create/iso-base-media/create-iso-base-media.js +3 -5
  65. package/dist/create/matroska/cluster.js +1 -1
  66. package/dist/create/matroska/create-matroska-media.d.ts +1 -1
  67. package/dist/create/matroska/create-matroska-media.js +7 -14
  68. package/dist/create/media-fn.d.ts +2 -1
  69. package/dist/create/mp3/create-mp3.d.ts +2 -0
  70. package/dist/create/mp3/create-mp3.js +49 -0
  71. package/dist/create/progress-tracker.d.ts +7 -0
  72. package/dist/create/progress-tracker.js +43 -0
  73. package/dist/create/wav/create-wav.d.ts +2 -0
  74. package/dist/create/wav/create-wav.js +110 -0
  75. package/dist/create/with-resolvers.d.ts +10 -0
  76. package/dist/create/with-resolvers.js +28 -0
  77. package/dist/emit-available-info.d.ts +2 -2
  78. package/dist/emit-available-info.js +17 -6
  79. package/dist/esm/from-node.mjs +2 -1
  80. package/dist/esm/index.mjs +1828 -605
  81. package/dist/get-audio-codec.d.ts +4 -3
  82. package/dist/get-audio-codec.js +17 -3
  83. package/dist/get-container.d.ts +3 -3
  84. package/dist/get-container.js +9 -7
  85. package/dist/get-dimensions.d.ts +3 -3
  86. package/dist/get-duration.d.ts +3 -3
  87. package/dist/get-duration.js +32 -14
  88. package/dist/get-fps.d.ts +3 -3
  89. package/dist/get-fps.js +31 -4
  90. package/dist/get-is-hdr.d.ts +4 -0
  91. package/dist/get-is-hdr.js +18 -0
  92. package/dist/get-sample-positions-from-lpcm.d.ts +3 -0
  93. package/dist/get-sample-positions-from-lpcm.js +46 -0
  94. package/dist/get-tracks.d.ts +7 -10
  95. package/dist/get-tracks.js +55 -27
  96. package/dist/get-video-codec.d.ts +5 -4
  97. package/dist/get-video-codec.js +47 -13
  98. package/dist/has-all-info.d.ts +2 -2
  99. package/dist/has-all-info.js +10 -5
  100. package/dist/index.d.ts +23 -3
  101. package/dist/index.js +9 -0
  102. package/dist/options.d.ts +16 -9
  103. package/dist/parse-media.js +3 -1
  104. package/dist/parse-result.d.ts +20 -6
  105. package/dist/parse-video.d.ts +2 -2
  106. package/dist/parse-video.js +5 -16
  107. package/dist/parser-context.d.ts +1 -0
  108. package/dist/parser-state.d.ts +11 -0
  109. package/dist/parser-state.js +30 -0
  110. package/dist/readers/from-node.js +2 -1
  111. package/dist/register-track.d.ts +13 -0
  112. package/dist/register-track.js +25 -0
  113. package/dist/version.d.ts +1 -1
  114. package/dist/version.js +1 -1
  115. package/package.json +3 -3
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseBoxes = exports.processBox = exports.parseMdatPartially = void 0;
3
+ exports.parseIsoBaseMediaBoxes = exports.processBox = exports.parseMdatPartially = void 0;
4
4
  const get_tracks_1 = require("../../get-tracks");
5
+ const register_track_1 = require("../../register-track");
5
6
  const esds_1 = require("./esds/esds");
6
7
  const ftyp_1 = require("./ftyp");
7
8
  const make_track_1 = require("./make-track");
@@ -39,7 +40,7 @@ const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, si
39
40
  boxType === 'stsb';
40
41
  if (parseChildren) {
41
42
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
42
- const parsed = await (0, exports.parseBoxes)({
43
+ const parsed = await (0, exports.parseIsoBaseMediaBoxes)({
43
44
  iterator,
44
45
  maxBytes: bytesRemainingInBox,
45
46
  allowIncompleteBoxes: false,
@@ -52,7 +53,7 @@ const getChildren = async ({ boxType, iterator, bytesRemainingInBox, options, si
52
53
  if (parsed.status === 'incomplete') {
53
54
  throw new Error('Incomplete boxes are not allowed');
54
55
  }
55
- return parsed.segments;
56
+ return parsed.segments.boxes;
56
57
  }
57
58
  if (bytesRemainingInBox < 0) {
58
59
  throw new Error('Box size is too big ' + JSON.stringify({ boxType }));
@@ -87,7 +88,6 @@ const parseMdatPartially = async ({ iterator, boxSize, fileOffset, parsedBoxes,
87
88
  };
88
89
  exports.parseMdatPartially = parseMdatPartially;
89
90
  const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options, signal, logLevel, }) => {
90
- var _a, _b;
91
91
  const fileOffset = iterator.counter.getOffset();
92
92
  const bytesRemaining = iterator.bytesRemaining();
93
93
  const boxSizeRaw = iterator.getFourByteNumber();
@@ -117,7 +117,8 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
117
117
  const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber() : boxSizeRaw;
118
118
  if (bytesRemaining < boxSize) {
119
119
  if (boxType === 'mdat') {
120
- const shouldSkip = (options.canSkipVideoData || !(0, get_tracks_1.hasTracks)(parsedBoxes)) &&
120
+ const shouldSkip = (options.canSkipVideoData ||
121
+ !(0, get_tracks_1.hasTracks)({ type: 'iso-base-media', boxes: parsedBoxes }, options.parserState)) &&
121
122
  options.supportsContentRange;
122
123
  if (shouldSkip) {
123
124
  const skipTo = fileOffset + boxSize;
@@ -349,14 +350,11 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
349
350
  });
350
351
  const transformedTrack = (0, make_track_1.makeBaseMediaTrack)(box);
351
352
  if (transformedTrack) {
352
- if (transformedTrack.type === 'audio') {
353
- const callback = await ((_a = options.onAudioTrack) === null || _a === void 0 ? void 0 : _a.call(options, transformedTrack));
354
- await options.parserState.registerAudioSampleCallback(transformedTrack.trackId, callback !== null && callback !== void 0 ? callback : null);
355
- }
356
- if (transformedTrack.type === 'video') {
357
- const callback = await ((_b = options.onVideoTrack) === null || _b === void 0 ? void 0 : _b.call(options, transformedTrack));
358
- await options.parserState.registerVideoSampleCallback(transformedTrack.trackId, callback !== null && callback !== void 0 ? callback : null);
359
- }
353
+ await (0, register_track_1.registerTrack)({
354
+ options,
355
+ state: options.parserState,
356
+ track: transformedTrack,
357
+ });
360
358
  }
361
359
  return {
362
360
  type: 'complete',
@@ -446,7 +444,6 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
446
444
  data: iterator,
447
445
  size: boxSize,
448
446
  fileOffset,
449
- logLevel,
450
447
  });
451
448
  return {
452
449
  type: 'complete',
@@ -498,10 +495,13 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
498
495
  };
499
496
  };
500
497
  exports.processBox = processBox;
501
- const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, signal, logLevel, }) => {
502
- let boxes = initialBoxes;
498
+ const parseIsoBaseMediaBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, options, continueMdat, signal, logLevel, }) => {
499
+ const structure = {
500
+ type: 'iso-base-media',
501
+ boxes: initialBoxes,
502
+ };
503
503
  const initialOffset = iterator.counter.getOffset();
504
- const alreadyHasMdat = boxes.find((b) => b.type === 'mdat-box');
504
+ const alreadyHasMdat = structure.boxes.find((b) => b.type === 'mdat-box');
505
505
  while (iterator.bytesRemaining() > 0 &&
506
506
  iterator.counter.getOffset() - initialOffset < maxBytes) {
507
507
  const result = continueMdat
@@ -527,13 +527,13 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
527
527
  }
528
528
  return {
529
529
  status: 'incomplete',
530
- segments: boxes,
530
+ segments: structure,
531
531
  continueParsing: () => {
532
- return (0, exports.parseBoxes)({
532
+ return (0, exports.parseIsoBaseMediaBoxes)({
533
533
  iterator,
534
534
  maxBytes,
535
535
  allowIncompleteBoxes,
536
- initialBoxes: boxes,
536
+ initialBoxes: structure.boxes,
537
537
  options,
538
538
  continueMdat: false,
539
539
  signal,
@@ -546,13 +546,13 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
546
546
  if (result.type === 'partial-mdat-box') {
547
547
  return {
548
548
  status: 'incomplete',
549
- segments: boxes,
549
+ segments: structure,
550
550
  continueParsing: () => {
551
- return Promise.resolve((0, exports.parseBoxes)({
551
+ return Promise.resolve((0, exports.parseIsoBaseMediaBoxes)({
552
552
  iterator,
553
553
  maxBytes,
554
554
  allowIncompleteBoxes,
555
- initialBoxes: boxes,
555
+ initialBoxes: structure.boxes,
556
556
  options,
557
557
  continueMdat: result,
558
558
  signal,
@@ -563,8 +563,8 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
563
563
  };
564
564
  }
565
565
  if (result.box.type === 'mdat-box' && alreadyHasMdat) {
566
- boxes = boxes.filter((b) => b.type !== 'mdat-box');
567
- boxes.push(result.box);
566
+ structure.boxes = structure.boxes.filter((b) => b.type !== 'mdat-box');
567
+ structure.boxes.push(result.box);
568
568
  iterator.allowDiscard();
569
569
  if (result.box.status !== 'samples-processed') {
570
570
  throw new Error('unexpected');
@@ -572,7 +572,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
572
572
  break;
573
573
  }
574
574
  else {
575
- boxes.push(result.box);
575
+ structure.boxes.push(result.box);
576
576
  }
577
577
  if (result.skipTo !== null) {
578
578
  if (!options.supportsContentRange) {
@@ -580,13 +580,13 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
580
580
  }
581
581
  return {
582
582
  status: 'incomplete',
583
- segments: boxes,
583
+ segments: structure,
584
584
  continueParsing: () => {
585
- return (0, exports.parseBoxes)({
585
+ return (0, exports.parseIsoBaseMediaBoxes)({
586
586
  iterator,
587
587
  maxBytes,
588
588
  allowIncompleteBoxes,
589
- initialBoxes: boxes,
589
+ initialBoxes: structure.boxes,
590
590
  options,
591
591
  continueMdat: false,
592
592
  signal,
@@ -599,13 +599,13 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
599
599
  if (iterator.bytesRemaining() < 0) {
600
600
  return {
601
601
  status: 'incomplete',
602
- segments: boxes,
602
+ segments: structure,
603
603
  continueParsing: () => {
604
- return (0, exports.parseBoxes)({
604
+ return (0, exports.parseIsoBaseMediaBoxes)({
605
605
  iterator,
606
606
  maxBytes,
607
607
  allowIncompleteBoxes,
608
- initialBoxes: boxes,
608
+ initialBoxes: structure.boxes,
609
609
  options,
610
610
  continueMdat: false,
611
611
  signal,
@@ -617,7 +617,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
617
617
  }
618
618
  iterator.removeBytesRead();
619
619
  }
620
- const mdatState = (0, traversal_1.getMdatBox)(boxes);
620
+ const mdatState = (0, traversal_1.getMdatBox)(structure.boxes);
621
621
  const skipped = (mdatState === null || mdatState === void 0 ? void 0 : mdatState.status) === 'samples-skipped' &&
622
622
  !options.canSkipVideoData &&
623
623
  options.supportsContentRange;
@@ -625,16 +625,16 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
625
625
  if (skipped || buffered) {
626
626
  return {
627
627
  status: 'incomplete',
628
- segments: boxes,
628
+ segments: structure,
629
629
  continueParsing: () => {
630
630
  if (buffered) {
631
631
  iterator.skipTo(mdatState.fileOffset, false);
632
632
  }
633
- return (0, exports.parseBoxes)({
633
+ return (0, exports.parseIsoBaseMediaBoxes)({
634
634
  iterator,
635
635
  maxBytes,
636
636
  allowIncompleteBoxes: false,
637
- initialBoxes: boxes,
637
+ initialBoxes: structure.boxes,
638
638
  options,
639
639
  continueMdat: false,
640
640
  signal,
@@ -646,7 +646,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
646
646
  }
647
647
  return {
648
648
  status: 'done',
649
- segments: boxes,
649
+ segments: structure,
650
650
  };
651
651
  };
652
- exports.parseBoxes = parseBoxes;
652
+ exports.parseIsoBaseMediaBoxes = parseIsoBaseMediaBoxes;
@@ -6,7 +6,7 @@ const parseMebx = async ({ iterator, offset, size, options, signal, }) => {
6
6
  // reserved, 6 bit
7
7
  iterator.discard(6);
8
8
  const dataReferenceIndex = iterator.getUint16();
9
- const children = await (0, process_box_1.parseBoxes)({
9
+ const children = await (0, process_box_1.parseIsoBaseMediaBoxes)({
10
10
  iterator,
11
11
  maxBytes: iterator.counter.getOffset() - offset,
12
12
  allowIncompleteBoxes: false,
@@ -25,7 +25,7 @@ const parseMebx = async ({ iterator, offset, size, options, signal, }) => {
25
25
  offset,
26
26
  dataReferenceIndex,
27
27
  format: 'mebx',
28
- children: children.segments,
28
+ children: children.segments.boxes,
29
29
  };
30
30
  };
31
31
  exports.parseMebx = parseMebx;
@@ -1,6 +1,6 @@
1
1
  import type { BufferIterator } from '../../../buffer-iterator';
2
2
  import type { LogLevel } from '../../../log';
3
- import type { AnySegment } from '../../../parse-result';
3
+ import type { AnySegment, IsoBaseMediaBox } from '../../../parse-result';
4
4
  import type { ParserContext } from '../../../parser-context';
5
5
  type SampleBase = {
6
6
  format: string;
@@ -37,7 +37,7 @@ export type VideoSample = SampleBase & {
37
37
  frameCountPerSample: number;
38
38
  depth: number;
39
39
  colorTableId: number;
40
- descriptors: AnySegment[];
40
+ descriptors: IsoBaseMediaBox[];
41
41
  version: number;
42
42
  revisionLevel: number;
43
43
  vendor: number[];
@@ -45,6 +45,7 @@ const audioTags = [
45
45
  'MAC6 ',
46
46
  'ima4',
47
47
  'fl32',
48
+ 'lpcm',
48
49
  'fl64',
49
50
  'in24',
50
51
  'in32',
@@ -98,7 +99,7 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
98
99
  const packetSize = iterator.getUint16();
99
100
  const sampleRate = iterator.getFixedPointUnsigned1616Number();
100
101
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
101
- const children = await (0, process_box_1.parseBoxes)({
102
+ const children = await (0, process_box_1.parseIsoBaseMediaBoxes)({
102
103
  iterator,
103
104
  allowIncompleteBoxes: false,
104
105
  maxBytes: bytesRemainingInBox,
@@ -130,7 +131,7 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
130
131
  bytesPerPacket: null,
131
132
  bytesPerFrame: null,
132
133
  bitsPerSample: null,
133
- children: children.segments,
134
+ children: children.segments.boxes,
134
135
  },
135
136
  };
136
137
  }
@@ -145,7 +146,7 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
145
146
  const bytesPerFrame = iterator.getUint32();
146
147
  const bytesPerSample = iterator.getUint32();
147
148
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
148
- const children = await (0, process_box_1.parseBoxes)({
149
+ const children = await (0, process_box_1.parseIsoBaseMediaBoxes)({
149
150
  iterator,
150
151
  allowIncompleteBoxes: false,
151
152
  maxBytes: bytesRemainingInBox,
@@ -177,26 +178,26 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
177
178
  bytesPerPacket,
178
179
  bytesPerFrame,
179
180
  bitsPerSample: bytesPerSample,
180
- children: children.segments,
181
+ children: children.segments.boxes,
181
182
  },
182
183
  };
183
184
  }
184
185
  if (version === 2) {
185
- const numberOfChannels = iterator.getUint16();
186
+ iterator.getUint16(); // always 3
186
187
  const sampleSize = iterator.getUint16();
187
188
  const compressionId = iterator.getUint16();
188
189
  const packetSize = iterator.getUint16();
189
190
  iterator.getFixedPointUnsigned1616Number(); // LQ sample rate;
190
191
  iterator.getUint32(); // ignore
191
192
  const higherSampleRate = iterator.getFloat64();
192
- iterator.getUint32(); // ignore;
193
+ const numAudioChannel = iterator.getUint32(); // ignore;
193
194
  iterator.getUint32(); // ignore, always 0x7F000000?
194
- const bitsPerCodedSample = iterator.getUint32();
195
+ const bitsPerChannel = iterator.getUint32();
195
196
  iterator.getUint32(); // ignore;
196
197
  const bytesPerFrame = iterator.getUint32();
197
198
  const samplesPerPacket = iterator.getUint32();
198
199
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
199
- const children = await (0, process_box_1.parseBoxes)({
200
+ const children = await (0, process_box_1.parseIsoBaseMediaBoxes)({
200
201
  iterator,
201
202
  allowIncompleteBoxes: false,
202
203
  maxBytes: bytesRemainingInBox,
@@ -219,7 +220,7 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
219
220
  vendor: [...Array.from(new Uint8Array(vendor))],
220
221
  size: boxSize,
221
222
  type: 'audio',
222
- numberOfChannels,
223
+ numberOfChannels: numAudioChannel,
223
224
  sampleSize,
224
225
  compressionId,
225
226
  packetSize,
@@ -227,8 +228,8 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
227
228
  samplesPerPacket,
228
229
  bytesPerPacket: null,
229
230
  bytesPerFrame,
230
- bitsPerSample: bitsPerCodedSample,
231
- children: children.segments,
231
+ bitsPerSample: bitsPerChannel,
232
+ children: children.segments.boxes,
232
233
  },
233
234
  };
234
235
  }
@@ -251,7 +252,7 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
251
252
  const colorTableId = iterator.getInt16();
252
253
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
253
254
  const children = bytesRemainingInBox > 8
254
- ? await (0, process_box_1.parseBoxes)({
255
+ ? await (0, process_box_1.parseIsoBaseMediaBoxes)({
255
256
  iterator,
256
257
  allowIncompleteBoxes: false,
257
258
  maxBytes: bytesRemainingInBox,
@@ -262,7 +263,7 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
262
263
  logLevel,
263
264
  })
264
265
  : (iterator.discard(bytesRemainingInBox),
265
- { status: 'done', segments: [] });
266
+ { status: 'done', segments: { boxes: [], type: 'iso-base-media' } });
266
267
  if (children.status === 'incomplete') {
267
268
  throw new Error('Incomplete boxes are not allowed');
268
269
  }
@@ -287,7 +288,7 @@ const processSample = async ({ iterator, options, signal, logLevel, }) => {
287
288
  compressorName,
288
289
  depth,
289
290
  colorTableId,
290
- descriptors: children.segments,
291
+ descriptors: children.segments.boxes,
291
292
  },
292
293
  };
293
294
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseTrak = void 0;
4
4
  const process_box_1 = require("../process-box");
5
5
  const parseTrak = async ({ data, size, offsetAtStart, options, signal, logLevel, }) => {
6
- const children = await (0, process_box_1.parseBoxes)({
6
+ const children = await (0, process_box_1.parseIsoBaseMediaBoxes)({
7
7
  iterator: data,
8
8
  maxBytes: size - (data.counter.getOffset() - offsetAtStart),
9
9
  allowIncompleteBoxes: false,
@@ -20,7 +20,7 @@ const parseTrak = async ({ data, size, offsetAtStart, options, signal, logLevel,
20
20
  offset: offsetAtStart,
21
21
  boxSize: size,
22
22
  type: 'trak-box',
23
- children: children.segments,
23
+ children: children.segments.boxes,
24
24
  };
25
25
  };
26
26
  exports.parseTrak = parseTrak;
@@ -17,7 +17,7 @@ import type { TkhdBox } from './tkhd';
17
17
  import type { TrakBox } from './trak/trak';
18
18
  import type { TrunBox } from './trun';
19
19
  export declare const getFtypBox: (segments: AnySegment[]) => FtypBox | null;
20
- export declare const getMoovBox: (segments: AnySegment[]) => MoovBox | null;
20
+ export declare const getMoovBox: (segments: IsoBaseMediaBox[]) => MoovBox | null;
21
21
  export declare const getMoofBox: (main: AnySegment[]) => IsoBaseMediaBox | null;
22
22
  export declare const getMvhdBox: (moovBox: MoovBox) => MvhdBox | null;
23
23
  export declare const getTraks: (moovBox: MoovBox) => TrakBox[];
@@ -0,0 +1,16 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ import type { RiffStructure } from '../../parse-result';
3
+ import type { ParserContext } from '../../parser-context';
4
+ import type { RiffBox } from './riff-box';
5
+ export type RiffResult = {
6
+ type: 'incomplete';
7
+ continueParsing: () => Promise<RiffResult>;
8
+ } | {
9
+ type: 'complete';
10
+ box: RiffBox | null;
11
+ };
12
+ export declare const expectRiffBox: ({ iterator, options, structure, }: {
13
+ iterator: BufferIterator;
14
+ options: ParserContext;
15
+ structure: RiffStructure;
16
+ }) => Promise<RiffResult>;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expectRiffBox = void 0;
4
+ const is_movi_1 = require("./is-movi");
5
+ const parse_movi_1 = require("./parse-movi");
6
+ const parse_riff_box_1 = require("./parse-riff-box");
7
+ const expectRiffBox = async ({ iterator, options, structure, }) => {
8
+ // Need at least 16 bytes to read LIST,size,movi,size
9
+ if (iterator.bytesRemaining() < 16) {
10
+ return {
11
+ type: 'incomplete',
12
+ continueParsing() {
13
+ return (0, exports.expectRiffBox)({ structure, iterator, options });
14
+ },
15
+ };
16
+ }
17
+ const ckId = iterator.getByteString(4);
18
+ const ckSize = iterator.getUint32Le();
19
+ if ((0, is_movi_1.isMoviAtom)(iterator, ckId)) {
20
+ iterator.discard(4);
21
+ return (0, parse_movi_1.parseMovi)({
22
+ iterator,
23
+ maxOffset: ckSize + iterator.counter.getOffset() - 4,
24
+ options,
25
+ structure,
26
+ });
27
+ }
28
+ // TODO: Add capability to read partially
29
+ if (iterator.bytesRemaining() < ckSize) {
30
+ iterator.counter.decrement(8);
31
+ return {
32
+ type: 'incomplete',
33
+ continueParsing: () => {
34
+ return (0, exports.expectRiffBox)({ structure, iterator, options });
35
+ },
36
+ };
37
+ }
38
+ return {
39
+ type: 'complete',
40
+ box: await (0, parse_riff_box_1.parseRiffBox)({
41
+ id: ckId,
42
+ iterator,
43
+ size: ckSize,
44
+ boxes: structure.boxes,
45
+ options,
46
+ }),
47
+ };
48
+ };
49
+ exports.expectRiffBox = expectRiffBox;
@@ -0,0 +1,21 @@
1
+ import type { AudioTrack, OtherTrack, VideoTrack } from '../../get-tracks';
2
+ import type { RiffStructure } from '../../parse-result';
3
+ import type { ParserState } from '../../parser-state';
4
+ import type { StrfBoxAudio, StrfBoxVideo, StrhBox } from './riff-box';
5
+ export type AllTracks = {
6
+ videoTracks: VideoTrack[];
7
+ audioTracks: AudioTrack[];
8
+ otherTracks: OtherTrack[];
9
+ };
10
+ export declare const getNumberOfTracks: (structure: RiffStructure) => number;
11
+ export declare const makeAviAudioTrack: ({ strf, index, }: {
12
+ strf: StrfBoxAudio;
13
+ index: number;
14
+ }) => AudioTrack;
15
+ export declare const makeAviVideoTrack: ({ strh, strf, index, }: {
16
+ strh: StrhBox;
17
+ strf: StrfBoxVideo;
18
+ index: number;
19
+ }) => VideoTrack;
20
+ export declare const getTracksFromAvi: (structure: RiffStructure, state: ParserState) => AllTracks;
21
+ export declare const hasAllTracksFromAvi: (structure: RiffStructure, state: ParserState) => boolean;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasAllTracksFromAvi = exports.getTracksFromAvi = exports.makeAviVideoTrack = exports.makeAviAudioTrack = exports.getNumberOfTracks = void 0;
4
+ const add_avc_profile_to_track_1 = require("../../add-avc-profile-to-track");
5
+ const timescale_1 = require("./timescale");
6
+ const traversal_1 = require("./traversal");
7
+ const getNumberOfTracks = (structure) => {
8
+ const avihBox = (0, traversal_1.getAvihBox)(structure);
9
+ if (avihBox) {
10
+ return avihBox.streams;
11
+ }
12
+ throw new Error('No avih box found');
13
+ };
14
+ exports.getNumberOfTracks = getNumberOfTracks;
15
+ const makeAviAudioTrack = ({ strf, index, }) => {
16
+ // 255 = AAC
17
+ if (strf.formatTag !== 255) {
18
+ throw new Error(`Unsupported audio format ${strf.formatTag}`);
19
+ }
20
+ return {
21
+ type: 'audio',
22
+ codec: 'mp4a.40.2', // According to Claude 3.5 Sonnet
23
+ codecPrivate: new Uint8Array([18, 16]),
24
+ codecWithoutConfig: 'aac',
25
+ description: new Uint8Array([18, 16]),
26
+ numberOfChannels: strf.numberOfChannels,
27
+ sampleRate: strf.sampleRate,
28
+ timescale: timescale_1.MEDIA_PARSER_RIFF_TIMESCALE,
29
+ trackId: index,
30
+ trakBox: null,
31
+ };
32
+ };
33
+ exports.makeAviAudioTrack = makeAviAudioTrack;
34
+ const makeAviVideoTrack = ({ strh, strf, index, }) => {
35
+ if (strh.handler !== 'H264') {
36
+ throw new Error(`Unsupported video codec ${strh.handler}`);
37
+ }
38
+ return {
39
+ codecPrivate: null,
40
+ codec: 'to-be-overriden-later',
41
+ codecWithoutConfig: 'h264',
42
+ codedHeight: strf.height,
43
+ codedWidth: strf.width,
44
+ width: strf.width,
45
+ height: strf.height,
46
+ type: 'video',
47
+ displayAspectHeight: strf.height,
48
+ timescale: timescale_1.MEDIA_PARSER_RIFF_TIMESCALE,
49
+ description: undefined,
50
+ trackId: index,
51
+ color: {
52
+ fullRange: null,
53
+ matrixCoefficients: null,
54
+ primaries: null,
55
+ transferCharacteristics: null,
56
+ },
57
+ displayAspectWidth: strf.width,
58
+ trakBox: null,
59
+ rotation: 0,
60
+ sampleAspectRatio: {
61
+ numerator: 1,
62
+ denominator: 1,
63
+ },
64
+ fps: strh.rate / strh.scale,
65
+ };
66
+ };
67
+ exports.makeAviVideoTrack = makeAviVideoTrack;
68
+ const getTracksFromAvi = (structure, state) => {
69
+ if (!(0, traversal_1.isRiffAvi)(structure)) {
70
+ throw new Error('Not an AVI file');
71
+ }
72
+ const videoTracks = [];
73
+ const audioTracks = [];
74
+ const otherTracks = [];
75
+ const boxes = (0, traversal_1.getStrlBoxes)(structure);
76
+ let i = 0;
77
+ for (const box of boxes) {
78
+ const strh = (0, traversal_1.getStrhBox)(box.children);
79
+ const strf = (0, traversal_1.getStrfBox)(box.children);
80
+ if (!strh || !strf) {
81
+ continue;
82
+ }
83
+ if (strf.type === 'strf-box-video') {
84
+ videoTracks.push((0, add_avc_profile_to_track_1.addAvcProfileToTrack)((0, exports.makeAviVideoTrack)({ strh, strf, index: i }), state.getAvcProfile()));
85
+ }
86
+ else if (strh.fccType === 'auds') {
87
+ audioTracks.push((0, exports.makeAviAudioTrack)({ strf, index: i }));
88
+ }
89
+ else {
90
+ throw new Error(`Unsupported track type ${strh.fccType}`);
91
+ }
92
+ i++;
93
+ }
94
+ return { audioTracks, otherTracks, videoTracks };
95
+ };
96
+ exports.getTracksFromAvi = getTracksFromAvi;
97
+ const hasAllTracksFromAvi = (structure, state) => {
98
+ if (!(0, traversal_1.isRiffAvi)(structure)) {
99
+ throw new Error('Not an AVI file');
100
+ }
101
+ const numberOfTracks = (0, exports.getNumberOfTracks)(structure);
102
+ const tracks = (0, exports.getTracksFromAvi)(structure, state);
103
+ return (tracks.videoTracks.length +
104
+ tracks.audioTracks.length +
105
+ tracks.otherTracks.length ===
106
+ numberOfTracks);
107
+ };
108
+ exports.hasAllTracksFromAvi = hasAllTracksFromAvi;
@@ -0,0 +1,2 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ export declare const isMoviAtom: (iterator: BufferIterator, ckId: string) => boolean;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMoviAtom = void 0;
4
+ const isMoviAtom = (iterator, ckId) => {
5
+ if (ckId !== 'LIST') {
6
+ return false;
7
+ }
8
+ const listType = iterator.getByteString(4);
9
+ iterator.counter.decrement(4);
10
+ return listType === 'movi';
11
+ };
12
+ exports.isMoviAtom = isMoviAtom;
@@ -0,0 +1,6 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ import type { RiffBox } from './riff-box';
3
+ export declare const parseAvih: ({ iterator, size, }: {
4
+ iterator: BufferIterator;
5
+ size: number;
6
+ }) => RiffBox;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseAvih = void 0;
4
+ const parseAvih = ({ iterator, size, }) => {
5
+ const { expectNoMoreBytes } = iterator.startBox(size);
6
+ const dwMicroSecPerFrame = iterator.getUint32Le();
7
+ const dwMaxBytesPerSec = iterator.getUint32Le();
8
+ const paddingGranularity = iterator.getUint32Le();
9
+ const flags = iterator.getUint32Le();
10
+ const totalFrames = iterator.getUint32Le();
11
+ const initialFrames = iterator.getUint32Le();
12
+ const streams = iterator.getUint32Le();
13
+ const suggestedBufferSize = iterator.getUint32Le();
14
+ const width = iterator.getUint32Le();
15
+ const height = iterator.getUint32Le();
16
+ iterator.discard(16);
17
+ expectNoMoreBytes();
18
+ return {
19
+ type: 'avih-box',
20
+ microSecPerFrame: dwMicroSecPerFrame,
21
+ maxBytesPerSecond: dwMaxBytesPerSec,
22
+ paddingGranularity,
23
+ flags,
24
+ totalFrames,
25
+ initialFrames,
26
+ streams,
27
+ suggestedBufferSize,
28
+ height,
29
+ width,
30
+ };
31
+ };
32
+ exports.parseAvih = parseAvih;
@@ -0,0 +1,13 @@
1
+ import type { BufferIterator } from '../../buffer-iterator';
2
+ import type { ParseResult, RiffStructure } from '../../parse-result';
3
+ import type { ParserContext } from '../../parser-context';
4
+ export declare const parseRiffBody: ({ iterator, structure, maxOffset, options, }: {
5
+ iterator: BufferIterator;
6
+ structure: RiffStructure;
7
+ maxOffset: number;
8
+ options: ParserContext;
9
+ }) => Promise<ParseResult<RiffStructure>>;
10
+ export declare const parseRiff: ({ iterator, options, }: {
11
+ iterator: BufferIterator;
12
+ options: ParserContext;
13
+ }) => Promise<ParseResult<RiffStructure>>;