@remotion/media-parser 4.0.210 → 4.0.212

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 (112) hide show
  1. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +12 -4
  2. package/dist/boxes/iso-base-media/mdat/mdat.js +13 -3
  3. package/dist/boxes/iso-base-media/process-box.js +46 -7
  4. package/dist/boxes/iso-base-media/traversal.d.ts +2 -7
  5. package/dist/boxes/iso-base-media/traversal.js +5 -15
  6. package/dist/boxes/webm/color.js +29 -22
  7. package/dist/boxes/webm/get-track.js +1 -16
  8. package/dist/boxes/webm/segments/parse-children.js +6 -0
  9. package/dist/buffer-iterator.d.ts +4 -1
  10. package/dist/buffer-iterator.js +31 -5
  11. package/dist/create/cluster.d.ts +8 -2
  12. package/dist/create/cluster.js +3 -2
  13. package/dist/create/create-media.d.ts +1 -1
  14. package/dist/create/create-media.js +44 -27
  15. package/dist/create/matroska-cues.d.ts +1 -1
  16. package/dist/create/matroska-cues.js +4 -5
  17. package/dist/create/matroska-trackentry.js +0 -8
  18. package/dist/esm/from-fetch.mjs +41 -6
  19. package/dist/esm/from-node.mjs +2 -1
  20. package/dist/esm/from-web-file.mjs +2 -1
  21. package/dist/esm/index.mjs +239 -106
  22. package/dist/get-audio-codec.d.ts +1 -1
  23. package/dist/get-audio-codec.js +4 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/parse-media.js +34 -25
  26. package/dist/parser-context.d.ts +1 -0
  27. package/dist/readers/from-fetch.d.ts +12 -0
  28. package/dist/readers/from-fetch.js +59 -13
  29. package/dist/readers/from-node.js +1 -0
  30. package/dist/readers/from-web-file.js +1 -0
  31. package/dist/readers/reader.d.ts +1 -0
  32. package/dist/traversal.d.ts +21 -0
  33. package/dist/traversal.js +158 -1
  34. package/package.json +2 -2
  35. package/dist/av1-codec-string.d.ts +0 -3
  36. package/dist/av1-codec-string.js +0 -91
  37. package/dist/boxes/iso-base-media/ftype.d.ts +0 -9
  38. package/dist/boxes/iso-base-media/ftype.js +0 -31
  39. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +0 -20
  40. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +0 -73
  41. package/dist/boxes/iso-base-media/stts/stts.d.ts +0 -15
  42. package/dist/boxes/iso-base-media/stts/stts.js +0 -35
  43. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +0 -14
  44. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +0 -67
  45. package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +0 -11
  46. package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +0 -14
  47. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +0 -6
  48. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +0 -9
  49. package/dist/boxes/webm/bitstream/av1/color-config.d.ts +0 -16
  50. package/dist/boxes/webm/bitstream/av1/color-config.js +0 -103
  51. package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +0 -14
  52. package/dist/boxes/webm/bitstream/av1/color-primaries.js +0 -17
  53. package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +0 -9
  54. package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +0 -17
  55. package/dist/boxes/webm/bitstream/av1/frame.d.ts +0 -0
  56. package/dist/boxes/webm/bitstream/av1/frame.js +0 -1
  57. package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +0 -51
  58. package/dist/boxes/webm/bitstream/av1/header-segment.js +0 -183
  59. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +0 -17
  60. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +0 -20
  61. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +0 -10
  62. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +0 -15
  63. package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +0 -5
  64. package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +0 -8
  65. package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +0 -8
  66. package/dist/boxes/webm/bitstream/av1/timing-info.js +0 -20
  67. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +0 -21
  68. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +0 -24
  69. package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +0 -2
  70. package/dist/boxes/webm/bitstream/av1/uvlc.js +0 -20
  71. package/dist/boxes/webm/bitstream/av1.d.ts +0 -20
  72. package/dist/boxes/webm/bitstream/av1.js +0 -118
  73. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
  74. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +0 -1
  75. package/dist/boxes/webm/segments/duration.d.ts +0 -6
  76. package/dist/boxes/webm/segments/duration.js +0 -19
  77. package/dist/boxes/webm/segments/info.d.ts +0 -9
  78. package/dist/boxes/webm/segments/info.js +0 -22
  79. package/dist/boxes/webm/segments/main.d.ts +0 -5
  80. package/dist/boxes/webm/segments/main.js +0 -2
  81. package/dist/boxes/webm/segments/muxing.d.ts +0 -6
  82. package/dist/boxes/webm/segments/muxing.js +0 -11
  83. package/dist/boxes/webm/segments/seek-head.d.ts +0 -9
  84. package/dist/boxes/webm/segments/seek-head.js +0 -22
  85. package/dist/boxes/webm/segments/seek-position.d.ts +0 -6
  86. package/dist/boxes/webm/segments/seek-position.js +0 -11
  87. package/dist/boxes/webm/segments/seek.d.ts +0 -13
  88. package/dist/boxes/webm/segments/seek.js +0 -35
  89. package/dist/boxes/webm/segments/timestamp-scale.d.ts +0 -6
  90. package/dist/boxes/webm/segments/timestamp-scale.js +0 -11
  91. package/dist/boxes/webm/segments/tracks.d.ts +0 -8
  92. package/dist/boxes/webm/segments/tracks.js +0 -21
  93. package/dist/boxes/webm/segments/unknown.d.ts +0 -6
  94. package/dist/boxes/webm/segments/unknown.js +0 -11
  95. package/dist/boxes/webm/segments/void.d.ts +0 -6
  96. package/dist/boxes/webm/segments/void.js +0 -11
  97. package/dist/boxes/webm/segments/writing.d.ts +0 -6
  98. package/dist/boxes/webm/segments/writing.js +0 -11
  99. package/dist/boxes/webm/tracks.d.ts +0 -8
  100. package/dist/boxes/webm/tracks.js +0 -21
  101. package/dist/combine-uint8array.d.ts +0 -1
  102. package/dist/combine-uint8array.js +0 -13
  103. package/dist/create/cues.d.ts +0 -0
  104. package/dist/create/cues.js +0 -1
  105. package/dist/from-web.d.ts +0 -2
  106. package/dist/from-web.js +0 -45
  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
@@ -1,17 +1,25 @@
1
1
  import type { BufferIterator } from '../../../buffer-iterator';
2
2
  import type { AnySegment } from '../../../parse-result';
3
3
  import type { ParserContext } from '../../../parser-context';
4
- export interface MdatBox {
4
+ type MdatStatus = {
5
+ status: 'samples-buffered';
6
+ } | {
7
+ status: 'samples-skipped';
8
+ } | {
9
+ status: 'samples-processed';
10
+ };
11
+ export type MdatBox = {
5
12
  type: 'mdat-box';
6
- samplesProcessed: boolean;
7
13
  boxSize: number;
8
14
  fileOffset: number;
9
- }
10
- export declare const parseMdat: ({ data, size, fileOffset, existingBoxes, options, signal, }: {
15
+ } & MdatStatus;
16
+ export declare const parseMdat: ({ data, size, fileOffset, existingBoxes, options, signal, maySkipSampleProcessing, }: {
11
17
  data: BufferIterator;
12
18
  size: number;
13
19
  fileOffset: number;
14
20
  existingBoxes: AnySegment[];
15
21
  options: ParserContext;
16
22
  signal: AbortSignal | null;
23
+ maySkipSampleProcessing: boolean;
17
24
  }) => Promise<MdatBox>;
25
+ export {};
@@ -4,14 +4,24 @@ exports.parseMdat = void 0;
4
4
  const get_tracks_1 = require("../../../get-tracks");
5
5
  const get_sample_positions_from_track_1 = require("../get-sample-positions-from-track");
6
6
  const traversal_1 = require("../traversal");
7
- const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, signal, }) => {
7
+ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, signal, maySkipSampleProcessing, }) => {
8
8
  const alreadyHas = (0, get_tracks_1.hasTracks)(existingBoxes);
9
9
  if (!alreadyHas) {
10
+ if (maySkipSampleProcessing) {
11
+ data.discard(size - (data.counter.getOffset() - fileOffset));
12
+ return Promise.resolve({
13
+ type: 'mdat-box',
14
+ boxSize: size,
15
+ status: 'samples-skipped',
16
+ fileOffset,
17
+ });
18
+ }
10
19
  data.discard(size - (data.counter.getOffset() - fileOffset));
20
+ data.disallowDiscard();
11
21
  return Promise.resolve({
12
22
  type: 'mdat-box',
13
23
  boxSize: size,
14
- samplesProcessed: false,
24
+ status: 'samples-buffered',
15
25
  fileOffset,
16
26
  });
17
27
  }
@@ -98,7 +108,7 @@ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, signa
98
108
  return Promise.resolve({
99
109
  type: 'mdat-box',
100
110
  boxSize: size,
101
- samplesProcessed: true,
111
+ status: 'samples-processed',
102
112
  fileOffset,
103
113
  });
104
114
  };
@@ -67,8 +67,9 @@ const parseMdatPartially = async ({ iterator, boxSize, fileOffset, parsedBoxes,
67
67
  existingBoxes: parsedBoxes,
68
68
  options,
69
69
  signal,
70
+ maySkipSampleProcessing: options.supportsContentRange,
70
71
  });
71
- if (box.samplesProcessed &&
72
+ if ((box.status === 'samples-processed' || box.status === 'samples-buffered') &&
72
73
  box.fileOffset + boxSize === iterator.counter.getOffset()) {
73
74
  return {
74
75
  type: 'complete',
@@ -115,7 +116,8 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
115
116
  const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber(littleEndian) : boxSizeRaw;
116
117
  if (bytesRemaining < boxSize) {
117
118
  if (boxType === 'mdat') {
118
- const shouldSkip = options.canSkipVideoData || !(0, get_tracks_1.hasTracks)(parsedBoxes);
119
+ const shouldSkip = (options.canSkipVideoData || !(0, get_tracks_1.hasTracks)(parsedBoxes)) &&
120
+ options.supportsContentRange;
119
121
  if (shouldSkip) {
120
122
  const skipTo = fileOffset + boxSize;
121
123
  const bytesToSkip = skipTo - iterator.counter.getOffset();
@@ -127,7 +129,7 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
127
129
  type: 'mdat-box',
128
130
  boxSize,
129
131
  fileOffset,
130
- samplesProcessed: false,
132
+ status: 'samples-skipped',
131
133
  },
132
134
  size: boxSize,
133
135
  skipTo: fileOffset + boxSize,
@@ -457,7 +459,11 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
457
459
  existingBoxes: parsedBoxes,
458
460
  options,
459
461
  signal,
462
+ maySkipSampleProcessing: options.supportsContentRange,
460
463
  });
464
+ if (box === null) {
465
+ throw new Error('Unexpected null');
466
+ }
461
467
  return {
462
468
  type: 'complete',
463
469
  box,
@@ -555,12 +561,19 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
555
561
  if (result.box.type === 'mdat-box' && alreadyHasMdat) {
556
562
  boxes = boxes.filter((b) => b.type !== 'mdat-box');
557
563
  boxes.push(result.box);
564
+ iterator.allowDiscard();
565
+ if (result.box.status !== 'samples-processed') {
566
+ throw new Error('unexpected');
567
+ }
558
568
  break;
559
569
  }
560
570
  else {
561
571
  boxes.push(result.box);
562
572
  }
563
573
  if (result.skipTo !== null) {
574
+ if (!options.supportsContentRange) {
575
+ throw new Error('Content-Range header is not supported by the reader, but was asked to seek');
576
+ }
564
577
  return {
565
578
  status: 'incomplete',
566
579
  segments: boxes,
@@ -579,18 +592,44 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
579
592
  skipTo: result.skipTo,
580
593
  };
581
594
  }
595
+ if (iterator.bytesRemaining() < 0) {
596
+ return {
597
+ status: 'incomplete',
598
+ segments: boxes,
599
+ continueParsing: () => {
600
+ return (0, exports.parseBoxes)({
601
+ iterator,
602
+ maxBytes,
603
+ allowIncompleteBoxes,
604
+ initialBoxes: boxes,
605
+ options,
606
+ continueMdat: false,
607
+ littleEndian,
608
+ signal,
609
+ });
610
+ },
611
+ skipTo: null,
612
+ };
613
+ }
582
614
  iterator.removeBytesRead();
583
615
  }
584
- const mdatState = (0, traversal_1.hasSkippedMdatProcessing)(boxes);
585
- if (mdatState.skipped && !options.canSkipVideoData) {
616
+ const mdatState = (0, traversal_1.getMdatBox)(boxes);
617
+ const skipped = (mdatState === null || mdatState === void 0 ? void 0 : mdatState.status) === 'samples-skipped' &&
618
+ !options.canSkipVideoData &&
619
+ options.supportsContentRange;
620
+ const buffered = (mdatState === null || mdatState === void 0 ? void 0 : mdatState.status) === 'samples-buffered' && !options.canSkipVideoData;
621
+ if (skipped || buffered) {
586
622
  return {
587
623
  status: 'incomplete',
588
624
  segments: boxes,
589
625
  continueParsing: () => {
626
+ if (buffered) {
627
+ iterator.skipTo(mdatState.fileOffset, false);
628
+ }
590
629
  return (0, exports.parseBoxes)({
591
630
  iterator,
592
631
  maxBytes,
593
- allowIncompleteBoxes,
632
+ allowIncompleteBoxes: false,
594
633
  initialBoxes: boxes,
595
634
  options,
596
635
  continueMdat: false,
@@ -598,7 +637,7 @@ const parseBoxes = async ({ iterator, maxBytes, allowIncompleteBoxes, initialBox
598
637
  signal,
599
638
  });
600
639
  },
601
- skipTo: mdatState.fileOffset,
640
+ skipTo: skipped ? mdatState.fileOffset : null,
602
641
  };
603
642
  }
604
643
  return {
@@ -1,5 +1,6 @@
1
1
  import type { AnySegment, IsoBaseMediaBox, RegularBox } from '../../parse-result';
2
2
  import type { FtypBox } from './ftyp';
3
+ import type { MdatBox } from './mdat/mdat';
3
4
  import type { MdhdBox } from './mdhd';
4
5
  import type { MoovBox } from './moov/moov';
5
6
  import type { MvhdBox } from './mvhd';
@@ -35,10 +36,4 @@ export declare const getStssBox: (trakBox: TrakBox) => StssBox | null;
35
36
  export declare const getTfdtBox: (segment: IsoBaseMediaBox) => TfdtBox | null;
36
37
  export declare const getTfhdBox: (segment: IsoBaseMediaBox) => TfhdBox | null;
37
38
  export declare const getTrunBoxes: (segment: IsoBaseMediaBox) => TrunBox[];
38
- export declare const hasSkippedMdatProcessing: (anySegment: AnySegment[]) => {
39
- skipped: false;
40
- fileOffset?: undefined;
41
- } | {
42
- skipped: boolean;
43
- fileOffset: number;
44
- };
39
+ export declare const getMdatBox: (anySegment: AnySegment[]) => MdatBox | null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasSkippedMdatProcessing = exports.getTrunBoxes = exports.getTfhdBox = exports.getTfdtBox = exports.getStssBox = exports.getStscBox = exports.getStszBox = exports.getCttsBox = exports.getSttsBox = exports.getStcoBox = exports.getVideoDescriptors = exports.getStsdBox = exports.getStblBox = exports.getMdhdBox = exports.getMdiaBox = exports.getTkhdBox = exports.getTraks = exports.getMvhdBox = exports.getMoofBox = exports.getMoovBox = exports.getFtypBox = void 0;
3
+ exports.getMdatBox = exports.getTrunBoxes = exports.getTfhdBox = exports.getTfdtBox = exports.getStssBox = exports.getStscBox = exports.getStszBox = exports.getCttsBox = exports.getSttsBox = exports.getStcoBox = exports.getVideoDescriptors = exports.getStsdBox = exports.getStblBox = exports.getMdhdBox = exports.getMdiaBox = exports.getTkhdBox = exports.getTraks = exports.getMvhdBox = exports.getMoofBox = exports.getMoovBox = exports.getFtypBox = void 0;
4
4
  const getFtypBox = (segments) => {
5
5
  const ftypBox = segments.find((s) => s.type === 'ftyp-box');
6
6
  if (!ftypBox || ftypBox.type !== 'ftyp-box') {
@@ -188,24 +188,14 @@ const getTrunBoxes = (segment) => {
188
188
  return trunBoxes;
189
189
  };
190
190
  exports.getTrunBoxes = getTrunBoxes;
191
- const hasSkippedMdatProcessing = (anySegment) => {
191
+ const getMdatBox = (anySegment) => {
192
192
  const mdat = anySegment.find((b) => b.type === 'mdat-box');
193
193
  if (!mdat) {
194
- return {
195
- skipped: false,
196
- };
194
+ return null;
197
195
  }
198
196
  if (mdat.type !== 'mdat-box') {
199
197
  throw new Error('Expected mdat-box');
200
198
  }
201
- if (mdat.samplesProcessed) {
202
- return {
203
- skipped: false,
204
- };
205
- }
206
- return {
207
- skipped: true,
208
- fileOffset: mdat.fileOffset,
209
- };
199
+ return mdat;
210
200
  };
211
- exports.hasSkippedMdatProcessing = hasSkippedMdatProcessing;
201
+ exports.getMdatBox = getMdatBox;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeMatroskaColorBytes = exports.parseColorSegment = void 0;
4
+ const truthy_1 = require("../../truthy");
4
5
  const make_header_1 = require("./make-header");
5
6
  const traversal_1 = require("./traversal");
6
7
  const parseColorSegment = (colourSegment) => {
@@ -82,30 +83,36 @@ const makeMatroskaColorBytes = ({ transferCharacteristics, matrixCoefficients, p
82
83
  type: 'Colour',
83
84
  minVintWidth: null,
84
85
  value: [
85
- {
86
- type: 'TransferCharacteristics',
87
- value: {
88
- value: transferChracteristicsValue,
89
- byteLength: null,
86
+ transferChracteristicsValue === 2
87
+ ? null
88
+ : {
89
+ type: 'TransferCharacteristics',
90
+ value: {
91
+ value: transferChracteristicsValue,
92
+ byteLength: null,
93
+ },
94
+ minVintWidth: null,
90
95
  },
91
- minVintWidth: null,
92
- },
93
- {
94
- type: 'MatrixCoefficients',
95
- value: {
96
- value: matrixCoefficientsValue,
97
- byteLength: null,
96
+ matrixCoefficientsValue === 2
97
+ ? null
98
+ : {
99
+ type: 'MatrixCoefficients',
100
+ value: {
101
+ value: matrixCoefficientsValue,
102
+ byteLength: null,
103
+ },
104
+ minVintWidth: null,
98
105
  },
99
- minVintWidth: null,
100
- },
101
- {
102
- type: 'Primaries',
103
- value: {
104
- value: primariesValue,
105
- byteLength: null,
106
+ primariesValue === 2
107
+ ? null
108
+ : {
109
+ type: 'Primaries',
110
+ value: {
111
+ value: primariesValue,
112
+ byteLength: null,
113
+ },
114
+ minVintWidth: null,
106
115
  },
107
- minVintWidth: null,
108
- },
109
116
  {
110
117
  type: 'Range',
111
118
  value: {
@@ -114,7 +121,7 @@ const makeMatroskaColorBytes = ({ transferCharacteristics, matrixCoefficients, p
114
121
  },
115
122
  minVintWidth: null,
116
123
  },
117
- ],
124
+ ].filter(truthy_1.truthy),
118
125
  });
119
126
  };
120
127
  exports.makeMatroskaColorBytes = makeMatroskaColorBytes;
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getTrack = void 0;
4
4
  const buffer_iterator_1 = require("../../buffer-iterator");
5
5
  const make_hvc1_codec_strings_1 = require("../../make-hvc1-codec-strings");
6
+ const traversal_1 = require("../../traversal");
6
7
  const av1_codec_private_1 = require("./av1-codec-private");
7
8
  const description_1 = require("./description");
8
9
  const track_entry_1 = require("./segments/track-entry");
9
- const traversal_1 = require("./traversal");
10
10
  const getDescription = (track) => {
11
11
  const codec = (0, traversal_1.getCodecSegment)(track);
12
12
  if (!codec) {
@@ -128,7 +128,6 @@ const getTrack = ({ timescale, track, }) => {
128
128
  const displayHeight = (0, traversal_1.getDisplayHeightSegment)(track);
129
129
  const displayWidth = (0, traversal_1.getDisplayWidthSegment)(track);
130
130
  const codec = (0, traversal_1.getCodecSegment)(track);
131
- const codecPrivate = (0, traversal_1.getPrivateData)(track);
132
131
  if (!codec) {
133
132
  return null;
134
133
  }
@@ -161,24 +160,11 @@ const getTrack = ({ timescale, track, }) => {
161
160
  : width.value.value,
162
161
  rotation: 0,
163
162
  trakBox: null,
164
- codecPrivate,
165
- // TODO: Parse colors
166
- color: {
167
- // TODO: Set transferCharacteristics
168
- transferCharacteristics: null,
169
- // TODO matrixCoefficients
170
- matrixCoefficients: null,
171
- // TODO primaries
172
- primaries: null,
173
- // TODO fullRange
174
- fullRange: null,
175
- },
176
163
  };
177
164
  }
178
165
  if ((0, track_entry_1.trackTypeToString)(trackType.value.value) === 'audio') {
179
166
  const sampleRate = (0, traversal_1.getSampleRate)(track);
180
167
  const numberOfChannels = (0, traversal_1.getNumberOfChannels)(track);
181
- const codecPrivate = (0, traversal_1.getPrivateData)(track);
182
168
  if (sampleRate === null) {
183
169
  throw new Error('Could not find sample rate or number of channels');
184
170
  }
@@ -191,7 +177,6 @@ const getTrack = ({ timescale, track, }) => {
191
177
  sampleRate,
192
178
  description: (0, description_1.getAudioDescription)(track),
193
179
  trakBox: null,
194
- codecPrivate,
195
180
  };
196
181
  }
197
182
  return null;
@@ -34,6 +34,9 @@ const continueParsingfunction = ({ result, iterator, children, wrap, parserConte
34
34
  const offset = iterator.counter.getOffset();
35
35
  const continued = await result.continueParsing();
36
36
  if (continued.status === 'incomplete') {
37
+ if (!parserContext.supportsContentRange) {
38
+ throw new Error('Content-Range header is not supported by the reader, but was asked to seek');
39
+ }
37
40
  return {
38
41
  status: 'incomplete',
39
42
  continueParsing: continueParsingfunction({
@@ -70,6 +73,9 @@ const expectChildren = async ({ iterator, length, initialChildren, wrap, parserC
70
73
  wrap,
71
74
  });
72
75
  if (child.status === 'incomplete') {
76
+ if (!parserContext.supportsContentRange) {
77
+ throw new Error('Content-Range header is not supported by the reader, but was asked to seek');
78
+ }
73
79
  return {
74
80
  status: 'incomplete',
75
81
  continueParsing: continueParsingfunction({
@@ -5,13 +5,14 @@ export declare class OffsetCounter {
5
5
  getOffset(): number;
6
6
  getDiscardedOffset(): number;
7
7
  setDiscardedOffset(offset: number): void;
8
+ getDiscardedBytes(): number;
8
9
  discardBytes(amount: number): void;
9
10
  decrement(amount: number): void;
10
11
  }
11
12
  export declare const getArrayBufferIterator: (initialData: Uint8Array, maxBytes: number | null) => {
12
13
  startReadingBits: () => void;
13
14
  stopReadingBits: () => void;
14
- skipTo: (offset: number) => void;
15
+ skipTo: (offset: number, reset: boolean) => void;
15
16
  addData: (newData: Uint8Array) => void;
16
17
  counter: OffsetCounter;
17
18
  peekB: (length: number) => void;
@@ -53,5 +54,7 @@ export declare const getArrayBufferIterator: (initialData: Uint8Array, maxBytes:
53
54
  getInt32: () => number;
54
55
  destroy: () => void;
55
56
  isMp3: () => boolean;
57
+ disallowDiscard: () => void;
58
+ allowDiscard: () => void;
56
59
  };
57
60
  export type BufferIterator = ReturnType<typeof getArrayBufferIterator>;
@@ -37,6 +37,9 @@ class OffsetCounter {
37
37
  setDiscardedOffset(offset) {
38
38
  __classPrivateFieldSet(this, _OffsetCounter_discardedBytes, offset, "f");
39
39
  }
40
+ getDiscardedBytes() {
41
+ return __classPrivateFieldGet(this, _OffsetCounter_discardedBytes, "f");
42
+ }
40
43
  discardBytes(amount) {
41
44
  __classPrivateFieldSet(this, _OffsetCounter_discardedBytes, __classPrivateFieldGet(this, _OffsetCounter_discardedBytes, "f") + amount, "f");
42
45
  }
@@ -73,11 +76,18 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
73
76
  data.set(initialData);
74
77
  let view = new DataView(data.buffer);
75
78
  const counter = makeOffsetCounter();
79
+ let discardAllowed = true;
76
80
  const getSlice = (amount) => {
77
81
  const value = data.slice(counter.getDiscardedOffset(), counter.getDiscardedOffset() + amount);
78
82
  counter.increment(amount);
79
83
  return value;
80
84
  };
85
+ const disallowDiscard = () => {
86
+ discardAllowed = false;
87
+ };
88
+ const allowDiscard = () => {
89
+ discardAllowed = true;
90
+ };
81
91
  const getUint8 = () => {
82
92
  const val = view.getUint8(counter.getDiscardedOffset());
83
93
  counter.increment(1);
@@ -191,8 +201,11 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
191
201
  return matchesPattern(mpegPattern)(data.subarray(0, 4));
192
202
  };
193
203
  const removeBytesRead = () => {
204
+ if (!discardAllowed) {
205
+ return;
206
+ }
194
207
  const bytesToRemove = counter.getDiscardedOffset();
195
- // Only to this operation if it is really worth it 😇
208
+ // Only do this operation if it is really worth it 😇
196
209
  if (bytesToRemove < 100000) {
197
210
  return;
198
211
  }
@@ -202,12 +215,23 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
202
215
  buf.resize(newData.byteLength);
203
216
  view = new DataView(data.buffer);
204
217
  };
205
- const skipTo = (offset) => {
218
+ const skipTo = (offset, reset) => {
206
219
  const becomesSmaller = offset < counter.getOffset();
207
220
  if (becomesSmaller) {
208
- buf.resize(0);
209
- counter.decrement(counter.getOffset() - offset);
210
- counter.setDiscardedOffset(offset);
221
+ if (reset) {
222
+ buf.resize(0);
223
+ counter.decrement(counter.getOffset() - offset);
224
+ counter.setDiscardedOffset(offset);
225
+ }
226
+ else {
227
+ const toDecrement = counter.getOffset() - offset;
228
+ const newOffset = counter.getOffset() - toDecrement;
229
+ counter.decrement(toDecrement);
230
+ const c = counter.getDiscardedBytes();
231
+ if (c > newOffset) {
232
+ throw new Error('already discarded too many bytes');
233
+ }
234
+ }
211
235
  }
212
236
  else {
213
237
  const currentOffset = counter.getOffset();
@@ -452,6 +476,8 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
452
476
  getInt32,
453
477
  destroy,
454
478
  isMp3,
479
+ disallowDiscard,
480
+ allowDiscard,
455
481
  };
456
482
  };
457
483
  exports.getArrayBufferIterator = getArrayBufferIterator;
@@ -8,6 +8,12 @@ export type AudioOrVideoSample = {
8
8
  };
9
9
  export declare const timestampToClusterTimestamp: (timestamp: number) => number;
10
10
  export declare const makeCluster: (w: Writer, timestamp: number) => Promise<{
11
- addSample: (chunk: AudioOrVideoSample, trackNumber: number) => Promise<void>;
12
- shouldMakeNewCluster: (newT: number, keyframe: boolean) => boolean;
11
+ addSample: (chunk: AudioOrVideoSample, trackNumber: number) => Promise<{
12
+ timecodeRelativeToCluster: number;
13
+ }>;
14
+ shouldMakeNewCluster: ({ isVideo, keyframe, newT, }: {
15
+ newT: number;
16
+ keyframe: boolean;
17
+ isVideo: boolean;
18
+ }) => boolean;
13
19
  }>;
@@ -43,11 +43,12 @@ const makeCluster = async (w, timestamp) => {
43
43
  clusterSize += simpleBlock.byteLength;
44
44
  await w.updateDataAt(clusterVIntPosition, (0, ebml_1.getVariableInt)(clusterSize, cluster_segment_1.CLUSTER_MIN_VINT_WIDTH));
45
45
  await w.write(simpleBlock);
46
+ return { timecodeRelativeToCluster };
46
47
  };
47
- const shouldMakeNewCluster = (newT, keyframe) => {
48
+ const shouldMakeNewCluster = ({ isVideo, keyframe, newT, }) => {
48
49
  const newTimestamp = (0, exports.timestampToClusterTimestamp)(newT);
49
50
  const oldTimestamp = (0, exports.timestampToClusterTimestamp)(timestamp);
50
- return newTimestamp - oldTimestamp >= 2000 && keyframe;
51
+ return newTimestamp - oldTimestamp >= 2000 && keyframe && isVideo;
51
52
  };
52
53
  return { addSample, shouldMakeNewCluster };
53
54
  };
@@ -4,7 +4,7 @@ import type { MakeTrackAudio, MakeTrackVideo } from './matroska-trackentry';
4
4
  export type MediaFn = {
5
5
  save: () => Promise<File>;
6
6
  remove: () => Promise<void>;
7
- addSample: (chunk: AudioOrVideoSample, trackNumber: number) => Promise<void>;
7
+ addSample: (chunk: AudioOrVideoSample, trackNumber: number, isVideo: boolean) => Promise<void>;
8
8
  updateDuration: (duration: number) => Promise<void>;
9
9
  addTrack: (track: Omit<MakeTrackAudio, 'trackNumber'> | Omit<MakeTrackVideo, 'trackNumber'>) => Promise<{
10
10
  trackNumber: number;