@remotion/media-parser 4.0.205 → 4.0.207

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 (127) hide show
  1. package/dist/boxes/iso-base-media/stsd/ctts.js +8 -1
  2. package/dist/boxes/iso-base-media/stsd/samples.d.ts +6 -3
  3. package/dist/boxes/iso-base-media/stsd/samples.js +6 -6
  4. package/dist/boxes/webm/ebml.d.ts +1 -1
  5. package/dist/boxes/webm/make-header.d.ts +6 -2
  6. package/dist/boxes/webm/make-header.js +102 -18
  7. package/dist/boxes/webm/parse-ebml.js +9 -3
  8. package/dist/boxes/webm/segments/all-segments.d.ts +70 -12
  9. package/dist/boxes/webm/segments/all-segments.js +43 -5
  10. package/dist/boxes/webm/segments.js +2 -2
  11. package/dist/create/create-media.d.ts +6 -0
  12. package/dist/create/create-media.js +35 -17
  13. package/dist/create/matroska-info.js +3 -1
  14. package/dist/create/matroska-trackentry.d.ts +13 -3
  15. package/dist/create/matroska-trackentry.js +78 -3
  16. package/dist/index.d.ts +5 -0
  17. package/dist/index.js +5 -1
  18. package/dist/options.d.ts +1 -1
  19. package/dist/parse-media.js +1 -1
  20. package/dist/traversal.d.ts +1 -1
  21. package/package.json +13 -8
  22. package/src/boxes/iso-base-media/stsd/ctts.ts +10 -1
  23. package/src/boxes/iso-base-media/stsd/samples.ts +12 -9
  24. package/src/boxes/webm/make-header.ts +132 -24
  25. package/src/boxes/webm/parse-ebml.ts +11 -3
  26. package/src/boxes/webm/segments/all-segments.ts +67 -7
  27. package/src/boxes/webm/segments.ts +2 -2
  28. package/src/create/cluster-segment.ts +62 -0
  29. package/src/create/create-media.ts +172 -0
  30. package/src/create/matroska-header.ts +63 -0
  31. package/src/create/matroska-info.ts +46 -0
  32. package/src/create/matroska-segment.ts +10 -0
  33. package/src/create/matroska-trackentry.ts +325 -0
  34. package/src/index.ts +9 -0
  35. package/src/options.ts +1 -1
  36. package/src/parse-media.ts +1 -1
  37. package/src/test/av1.test.ts +1 -1
  38. package/src/test/create-matroska.test.ts +31 -6
  39. package/src/test/duration.test.ts +1 -1
  40. package/src/test/matroska.test.ts +35 -5
  41. package/src/test/parse-video.test.ts +1 -1
  42. package/src/test/parse-webm.test.ts +1 -1
  43. package/src/test/stream-local.test.ts +1 -1
  44. package/src/test/stream-samples.test.ts +1 -1
  45. package/src/writers/web-fs.ts +50 -0
  46. package/src/writers/writer.ts +12 -0
  47. package/tsconfig.tsbuildinfo +1 -1
  48. package/dist/av1-codec-string.d.ts +0 -3
  49. package/dist/av1-codec-string.js +0 -91
  50. package/dist/boxes/iso-base-media/ftype.d.ts +0 -9
  51. package/dist/boxes/iso-base-media/ftype.js +0 -31
  52. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +0 -20
  53. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +0 -73
  54. package/dist/boxes/iso-base-media/stts/stts.d.ts +0 -15
  55. package/dist/boxes/iso-base-media/stts/stts.js +0 -35
  56. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +0 -14
  57. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +0 -67
  58. package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +0 -11
  59. package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +0 -14
  60. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +0 -6
  61. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +0 -9
  62. package/dist/boxes/webm/bitstream/av1/color-config.d.ts +0 -16
  63. package/dist/boxes/webm/bitstream/av1/color-config.js +0 -103
  64. package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +0 -14
  65. package/dist/boxes/webm/bitstream/av1/color-primaries.js +0 -17
  66. package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +0 -9
  67. package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +0 -17
  68. package/dist/boxes/webm/bitstream/av1/frame.d.ts +0 -0
  69. package/dist/boxes/webm/bitstream/av1/frame.js +0 -1
  70. package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +0 -51
  71. package/dist/boxes/webm/bitstream/av1/header-segment.js +0 -183
  72. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +0 -17
  73. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +0 -20
  74. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +0 -10
  75. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +0 -15
  76. package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +0 -5
  77. package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +0 -8
  78. package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +0 -8
  79. package/dist/boxes/webm/bitstream/av1/timing-info.js +0 -20
  80. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +0 -21
  81. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +0 -24
  82. package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +0 -2
  83. package/dist/boxes/webm/bitstream/av1/uvlc.js +0 -20
  84. package/dist/boxes/webm/bitstream/av1.d.ts +0 -20
  85. package/dist/boxes/webm/bitstream/av1.js +0 -118
  86. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
  87. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +0 -1
  88. package/dist/boxes/webm/segments/duration.d.ts +0 -6
  89. package/dist/boxes/webm/segments/duration.js +0 -19
  90. package/dist/boxes/webm/segments/info.d.ts +0 -9
  91. package/dist/boxes/webm/segments/info.js +0 -22
  92. package/dist/boxes/webm/segments/main.d.ts +0 -5
  93. package/dist/boxes/webm/segments/main.js +0 -2
  94. package/dist/boxes/webm/segments/muxing.d.ts +0 -6
  95. package/dist/boxes/webm/segments/muxing.js +0 -11
  96. package/dist/boxes/webm/segments/seek-head.d.ts +0 -9
  97. package/dist/boxes/webm/segments/seek-head.js +0 -22
  98. package/dist/boxes/webm/segments/seek-position.d.ts +0 -6
  99. package/dist/boxes/webm/segments/seek-position.js +0 -11
  100. package/dist/boxes/webm/segments/seek.d.ts +0 -13
  101. package/dist/boxes/webm/segments/seek.js +0 -35
  102. package/dist/boxes/webm/segments/timestamp-scale.d.ts +0 -6
  103. package/dist/boxes/webm/segments/timestamp-scale.js +0 -11
  104. package/dist/boxes/webm/segments/tracks.d.ts +0 -8
  105. package/dist/boxes/webm/segments/tracks.js +0 -21
  106. package/dist/boxes/webm/segments/unknown.d.ts +0 -6
  107. package/dist/boxes/webm/segments/unknown.js +0 -11
  108. package/dist/boxes/webm/segments/void.d.ts +0 -6
  109. package/dist/boxes/webm/segments/void.js +0 -11
  110. package/dist/boxes/webm/segments/writing.d.ts +0 -6
  111. package/dist/boxes/webm/segments/writing.js +0 -11
  112. package/dist/boxes/webm/tracks.d.ts +0 -8
  113. package/dist/boxes/webm/tracks.js +0 -21
  114. package/dist/combine-uint8array.d.ts +0 -1
  115. package/dist/combine-uint8array.js +0 -13
  116. package/dist/from-web.d.ts +0 -2
  117. package/dist/from-web.js +0 -45
  118. package/dist/get-video-metadata.d.ts +0 -2
  119. package/dist/get-video-metadata.js +0 -44
  120. package/dist/read-and-increment-offset.d.ts +0 -28
  121. package/dist/read-and-increment-offset.js +0 -177
  122. package/dist/understand-vorbis.d.ts +0 -1
  123. package/dist/understand-vorbis.js +0 -12
  124. /package/src/{from-fetch.ts → readers/from-fetch.ts} +0 -0
  125. /package/src/{from-node.ts → readers/from-node.ts} +0 -0
  126. /package/src/{from-web-file.ts → readers/from-web-file.ts} +0 -0
  127. /package/src/{reader.ts → readers/reader.ts} +0 -0
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseCtts = void 0;
4
4
  const parseCtts = ({ iterator, offset, size, }) => {
5
5
  const version = iterator.getUint8();
6
- if (version !== 0) {
6
+ if (version !== 0 && version !== 1) {
7
7
  throw new Error(`Unsupported CTTS version ${version}`);
8
8
  }
9
9
  const flags = iterator.getSlice(3);
@@ -11,7 +11,14 @@ const parseCtts = ({ iterator, offset, size, }) => {
11
11
  const entries = [];
12
12
  for (let i = 0; i < entryCount; i++) {
13
13
  const sampleCount = iterator.getUint32();
14
+ // V1 = signed, V0 = unsigned
15
+ // however some files are buggy
16
+ // Let's do the same thing as mp4box but uint32, based on our test set of videos
17
+ // https://github.com/gpac/mp4box.js/blob/c6cc468145bc5b031b866446111f29c8b620dbe6/src/parsing/ctts.js#L2
14
18
  const sampleOffset = iterator.getUint32();
19
+ if (sampleOffset < 0) {
20
+ throw new Error('ctts box uses negative values without using version 1');
21
+ }
15
22
  entries.push({
16
23
  sampleCount,
17
24
  sampleOffset,
@@ -5,9 +5,6 @@ type SampleBase = {
5
5
  format: string;
6
6
  offset: number;
7
7
  dataReferenceIndex: number;
8
- version: number;
9
- revisionLevel: number;
10
- vendor: number[];
11
8
  size: number;
12
9
  };
13
10
  export type AudioSample = SampleBase & {
@@ -22,6 +19,9 @@ export type AudioSample = SampleBase & {
22
19
  bytesPerFrame: number | null;
23
20
  bitsPerSample: number | null;
24
21
  children: AnySegment[];
22
+ version: number;
23
+ revisionLevel: number;
24
+ vendor: number[];
25
25
  };
26
26
  export type VideoSample = SampleBase & {
27
27
  type: 'video';
@@ -37,6 +37,9 @@ export type VideoSample = SampleBase & {
37
37
  depth: number;
38
38
  colorTableId: number;
39
39
  descriptors: AnySegment[];
40
+ version: number;
41
+ revisionLevel: number;
42
+ vendor: number[];
40
43
  };
41
44
  type UnknownSample = SampleBase & {
42
45
  type: 'unknown';
@@ -74,9 +74,6 @@ const processSample = async ({ iterator, options, }) => {
74
74
  // 6 reserved bytes
75
75
  iterator.discard(6);
76
76
  const dataReferenceIndex = iterator.getUint16();
77
- const version = iterator.getUint16();
78
- const revisionLevel = iterator.getUint16();
79
- const vendor = iterator.getSlice(4);
80
77
  if (!isVideo && !isAudio) {
81
78
  const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
82
79
  iterator.discard(bytesRemainingInBox);
@@ -85,15 +82,15 @@ const processSample = async ({ iterator, options, }) => {
85
82
  type: 'unknown',
86
83
  offset: fileOffset,
87
84
  dataReferenceIndex,
88
- version,
89
- revisionLevel,
90
- vendor: [...Array.from(new Uint8Array(vendor))],
91
85
  size: boxSize,
92
86
  format: boxFormat,
93
87
  },
94
88
  };
95
89
  }
96
90
  if (isAudio) {
91
+ const version = iterator.getUint16();
92
+ const revisionLevel = iterator.getUint16();
93
+ const vendor = iterator.getSlice(4);
97
94
  if (version === 0) {
98
95
  const numberOfChannels = iterator.getUint16();
99
96
  const sampleSize = iterator.getUint16();
@@ -185,6 +182,9 @@ const processSample = async ({ iterator, options, }) => {
185
182
  throw new Error(`Unsupported version ${version}`);
186
183
  }
187
184
  if (isVideo) {
185
+ const version = iterator.getUint16();
186
+ const revisionLevel = iterator.getUint16();
187
+ const vendor = iterator.getSlice(4);
188
188
  const temporalQuality = iterator.getUint32();
189
189
  const spacialQuality = iterator.getUint32();
190
190
  const width = iterator.getUint16();
@@ -1,2 +1,2 @@
1
- export declare const measureEBMLVarInt: (value: number) => 1 | 2 | 3 | 4 | 5 | 6;
1
+ export declare const measureEBMLVarInt: (value: number) => 1 | 4 | 2 | 6 | 5 | 3;
2
2
  export declare const getVariableInt: (value: number, minWidth: number | null) => Uint8Array;
@@ -1,4 +1,8 @@
1
- import type { PossibleEbmlOrUint8Array } from './segments/all-segments';
1
+ import type { BytesAndOffset, PossibleEbmlOrUint8Array } from './segments/all-segments';
2
+ import { matroskaElements } from './segments/all-segments';
2
3
  export declare const webmPattern: Uint8Array;
3
- export declare const makeMatroskaBytes: (fields: PossibleEbmlOrUint8Array) => Uint8Array;
4
+ export declare const matroskaToHex: (matrId: (typeof matroskaElements)[keyof typeof matroskaElements]) => Uint8Array;
5
+ export declare const makeMatroskaBytes: (fields: PossibleEbmlOrUint8Array) => BytesAndOffset;
6
+ export declare const padMatroskaBytes: (fields: PossibleEbmlOrUint8Array, totalLength: number) => BytesAndOffset[];
4
7
  export declare const combineUint8Arrays: (arrays: Uint8Array[]) => Uint8Array;
8
+ export declare function serializeUint16(value: number): Uint8Array;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.combineUint8Arrays = exports.makeMatroskaBytes = exports.webmPattern = void 0;
3
+ exports.serializeUint16 = exports.combineUint8Arrays = exports.padMatroskaBytes = exports.makeMatroskaBytes = exports.matroskaToHex = exports.webmPattern = void 0;
4
4
  const ebml_1 = require("./ebml");
5
5
  const all_segments_1 = require("./segments/all-segments");
6
6
  exports.webmPattern = new Uint8Array([0x1a, 0x45, 0xdf, 0xa3]);
@@ -12,6 +12,7 @@ const matroskaToHex = (matrId) => {
12
12
  }
13
13
  return numbers;
14
14
  };
15
+ exports.matroskaToHex = matroskaToHex;
15
16
  function putUintDynamic(number, minimumLength) {
16
17
  if (number < 0) {
17
18
  throw new Error('This function is designed for non-negative integers only.');
@@ -25,26 +26,51 @@ function putUintDynamic(number, minimumLength) {
25
26
  }
26
27
  return bytes;
27
28
  }
28
- const makeFromHeaderStructure = (fields) => {
29
- if (fields instanceof Uint8Array) {
29
+ const makeFromStructure = (fields) => {
30
+ if ('bytes' in fields) {
30
31
  return fields;
31
32
  }
32
33
  const arrays = [];
33
34
  const struct = all_segments_1.ebmlMap[(0, all_segments_1.getIdForName)(fields.type)];
34
35
  if (struct.type === 'uint8array') {
35
- return fields.value;
36
+ return {
37
+ bytes: fields.value,
38
+ offsets: { offset: 0, children: [], field: fields.type },
39
+ };
36
40
  }
37
41
  if (struct.type === 'children') {
42
+ const children = [];
43
+ let bytesWritten = 0;
38
44
  for (const item of fields.value) {
39
- arrays.push((0, exports.makeMatroskaBytes)(item));
45
+ const { bytes, offsets } = (0, exports.makeMatroskaBytes)(item);
46
+ arrays.push(bytes);
47
+ children.push((0, all_segments_1.incrementOffsetAndChildren)(offsets, bytesWritten));
48
+ bytesWritten += bytes.byteLength;
40
49
  }
41
- return (0, exports.combineUint8Arrays)(arrays);
50
+ return {
51
+ bytes: (0, exports.combineUint8Arrays)(arrays),
52
+ offsets: { offset: 0, children, field: fields.type },
53
+ };
42
54
  }
43
55
  if (struct.type === 'string') {
44
- return new TextEncoder().encode(fields.value);
56
+ return {
57
+ bytes: new TextEncoder().encode(fields.value),
58
+ offsets: {
59
+ children: [],
60
+ offset: 0,
61
+ field: fields.type,
62
+ },
63
+ };
45
64
  }
46
65
  if (struct.type === 'uint') {
47
- return putUintDynamic(fields.value.value, fields.value.byteLength);
66
+ return {
67
+ bytes: putUintDynamic(fields.value.value, fields.value.byteLength),
68
+ offsets: {
69
+ children: [],
70
+ offset: 0,
71
+ field: fields.type,
72
+ },
73
+ };
48
74
  }
49
75
  if (struct.type === 'hex-string') {
50
76
  const hex = fields.value.substring(2);
@@ -53,33 +79,84 @@ const makeFromHeaderStructure = (fields) => {
53
79
  const byte = parseInt(hex.substring(i, i + 2), 16);
54
80
  arr[i / 2] = byte;
55
81
  }
56
- return arr;
82
+ return {
83
+ bytes: arr,
84
+ offsets: {
85
+ children: [],
86
+ offset: 0,
87
+ field: fields.type,
88
+ },
89
+ };
57
90
  }
58
91
  if (struct.type === 'float') {
59
92
  const value = fields.value;
60
93
  if (value.size === '32') {
61
94
  const dataView = new DataView(new ArrayBuffer(4));
62
95
  dataView.setFloat32(0, value.value);
63
- return new Uint8Array(dataView.buffer);
96
+ return {
97
+ bytes: new Uint8Array(dataView.buffer),
98
+ offsets: {
99
+ children: [],
100
+ offset: 0,
101
+ field: fields.type,
102
+ },
103
+ };
64
104
  }
65
105
  const dataView2 = new DataView(new ArrayBuffer(8));
66
106
  dataView2.setFloat64(0, value.value);
67
- return new Uint8Array(dataView2.buffer);
107
+ return {
108
+ bytes: new Uint8Array(dataView2.buffer),
109
+ offsets: {
110
+ children: [],
111
+ offset: 0,
112
+ field: fields.type,
113
+ },
114
+ };
68
115
  }
69
116
  throw new Error('Unexpected type');
70
117
  };
71
118
  const makeMatroskaBytes = (fields) => {
72
- if (fields instanceof Uint8Array) {
119
+ if ('bytes' in fields) {
73
120
  return fields;
74
121
  }
75
- const value = makeFromHeaderStructure(fields);
76
- return (0, exports.combineUint8Arrays)([
77
- matroskaToHex((0, all_segments_1.getIdForName)(fields.type)),
78
- (0, ebml_1.getVariableInt)(value.length, fields.minVintWidth),
79
- value,
80
- ]);
122
+ const value = makeFromStructure(fields);
123
+ const header = (0, exports.matroskaToHex)((0, all_segments_1.getIdForName)(fields.type));
124
+ const size = (0, ebml_1.getVariableInt)(value.bytes.length, fields.minVintWidth);
125
+ const bytes = (0, exports.combineUint8Arrays)([header, size, value.bytes]);
126
+ return {
127
+ bytes,
128
+ offsets: {
129
+ offset: value.offsets.offset,
130
+ field: value.offsets.field,
131
+ children: value.offsets.children.map((c) => {
132
+ return (0, all_segments_1.incrementOffsetAndChildren)(c, header.byteLength + size.byteLength);
133
+ }),
134
+ },
135
+ };
81
136
  };
82
137
  exports.makeMatroskaBytes = makeMatroskaBytes;
138
+ const padMatroskaBytes = (fields, totalLength) => {
139
+ const regular = (0, exports.makeMatroskaBytes)(fields);
140
+ const paddingLength = totalLength -
141
+ regular.bytes.byteLength -
142
+ (0, exports.matroskaToHex)(all_segments_1.matroskaElements.Void).byteLength;
143
+ if (paddingLength < 0) {
144
+ throw new Error('ooops');
145
+ }
146
+ const padding = (0, exports.makeMatroskaBytes)({
147
+ type: 'Void',
148
+ value: new Uint8Array(paddingLength).fill(0),
149
+ minVintWidth: null,
150
+ });
151
+ return [
152
+ regular,
153
+ {
154
+ bytes: padding.bytes,
155
+ offsets: (0, all_segments_1.incrementOffsetAndChildren)(padding.offsets, regular.bytes.length),
156
+ },
157
+ ];
158
+ };
159
+ exports.padMatroskaBytes = padMatroskaBytes;
83
160
  const combineUint8Arrays = (arrays) => {
84
161
  if (arrays.length === 0) {
85
162
  return new Uint8Array([]);
@@ -100,3 +177,10 @@ const combineUint8Arrays = (arrays) => {
100
177
  return result;
101
178
  };
102
179
  exports.combineUint8Arrays = combineUint8Arrays;
180
+ function serializeUint16(value) {
181
+ const buffer = new ArrayBuffer(2);
182
+ const view = new DataView(buffer);
183
+ view.setUint16(0, value);
184
+ return new Uint8Array(buffer);
185
+ }
186
+ exports.serializeUint16 = serializeUint16;
@@ -22,9 +22,11 @@ const parseEbml = async (iterator, parserContext) => {
22
22
  }
23
23
  if (hasInMap.type === 'uint') {
24
24
  const beforeUintOffset = iterator.counter.getOffset();
25
- const value = iterator.getUint(size);
25
+ const value = size === 0 ? 0 : iterator.getUint(size);
26
+ const { name } = hasInMap;
26
27
  return {
27
- type: hasInMap.name,
28
+ // To work around TS limit
29
+ type: name,
28
30
  value: {
29
31
  value,
30
32
  byteLength: iterator.counter.getOffset() - beforeUintOffset,
@@ -41,7 +43,11 @@ const parseEbml = async (iterator, parserContext) => {
41
43
  };
42
44
  }
43
45
  if (hasInMap.type === 'float') {
44
- const value = size === 4 ? iterator.getFloat32() : iterator.getFloat64();
46
+ const value = size === 0
47
+ ? 0.0
48
+ : size === 4
49
+ ? iterator.getFloat32()
50
+ : iterator.getFloat64();
45
51
  return {
46
52
  type: hasInMap.name,
47
53
  value: {
@@ -312,8 +312,8 @@ export declare const ebmlReadVersion: {
312
312
  type: "uint";
313
313
  };
314
314
  export declare const ebmlMaxIdLength: {
315
- name: "EBMLMaxIDLength";
316
- type: "uint";
315
+ readonly name: "EBMLMaxIDLength";
316
+ readonly type: "uint";
317
317
  };
318
318
  export declare const ebmlMaxSizeLength: {
319
319
  name: "EBMLMaxSizeLength";
@@ -454,7 +454,31 @@ export declare const trackUID: {
454
454
  };
455
455
  export declare const color: {
456
456
  readonly name: "Colour";
457
- readonly type: "uint8array";
457
+ readonly type: "children";
458
+ };
459
+ export declare const transfer: {
460
+ readonly name: "TransferCharacteristics";
461
+ readonly type: "uint";
462
+ };
463
+ export declare const matrix: {
464
+ readonly name: "MatrixCoefficients";
465
+ readonly type: "uint";
466
+ };
467
+ export declare const primaries: {
468
+ readonly name: "Primaries";
469
+ readonly type: "uint";
470
+ };
471
+ export declare const range: {
472
+ readonly name: "Range";
473
+ readonly type: "uint";
474
+ };
475
+ export declare const ChromaSitingHorz: {
476
+ readonly name: "ChromaSitingHorz";
477
+ readonly type: "uint";
478
+ };
479
+ export declare const ChromaSitingVert: {
480
+ readonly name: "ChromaSitingVert";
481
+ readonly type: "uint";
458
482
  };
459
483
  export declare const language: {
460
484
  readonly name: "Language";
@@ -486,7 +510,7 @@ export declare const videoSegment: {
486
510
  };
487
511
  export declare const flagDefault: {
488
512
  readonly name: "FlagDefault";
489
- readonly type: "uint8array";
513
+ readonly type: "uint";
490
514
  };
491
515
  export declare const referenceBlock: {
492
516
  readonly name: "ReferenceBlock";
@@ -559,19 +583,19 @@ export type FloatWithSize = {
559
583
  };
560
584
  export type UintWithSize = {
561
585
  value: number;
562
- byteLength: number;
586
+ byteLength: number | null;
563
587
  };
564
588
  export type EbmlValue<T extends Ebml, Child = PossibleEbml> = T extends EbmlWithUint ? UintWithSize : T extends EbmlWithString ? string : T extends EbmlWithFloat ? FloatWithSize : T extends EbmlWithHexString ? string : T extends EbmlWithUint8Array ? Uint8Array : T extends EbmlWithChildren ? Child[] : never;
565
589
  export type EbmlValueOrUint8Array<T extends Ebml> = Uint8Array | EbmlValue<T, PossibleEbmlOrUint8Array>;
566
590
  export type EbmlParsed<T extends Ebml> = {
567
591
  type: T['name'];
568
592
  value: EbmlValue<T>;
569
- minVintWidth: number;
593
+ minVintWidth: number | null;
570
594
  };
571
595
  export type EbmlParsedOrUint8Array<T extends Ebml> = {
572
596
  type: T['name'];
573
597
  value: EbmlValueOrUint8Array<T>;
574
- minVintWidth: number;
598
+ minVintWidth: number | null;
575
599
  };
576
600
  export declare const ebmlMap: {
577
601
  readonly "0x1a45dfa3": {
@@ -599,8 +623,8 @@ export declare const ebmlMap: {
599
623
  type: "uint";
600
624
  };
601
625
  readonly "0x42f2": {
602
- name: "EBMLMaxIDLength";
603
- type: "uint";
626
+ readonly name: "EBMLMaxIDLength";
627
+ readonly type: "uint";
604
628
  };
605
629
  readonly "0x42f3": {
606
630
  name: "EBMLMaxSizeLength";
@@ -764,7 +788,7 @@ export declare const ebmlMap: {
764
788
  };
765
789
  readonly "0x55b0": {
766
790
  readonly name: "Colour";
767
- readonly type: "uint8array";
791
+ readonly type: "children";
768
792
  };
769
793
  readonly "0x22b59c": {
770
794
  readonly name: "Language";
@@ -796,7 +820,7 @@ export declare const ebmlMap: {
796
820
  };
797
821
  readonly "0x88": {
798
822
  readonly name: "FlagDefault";
799
- readonly type: "uint8array";
823
+ readonly type: "uint";
800
824
  };
801
825
  readonly "0xfb": {
802
826
  readonly name: "ReferenceBlock";
@@ -834,12 +858,46 @@ export declare const ebmlMap: {
834
858
  readonly name: "Cluster";
835
859
  readonly type: "children";
836
860
  };
861
+ readonly "0x55ba": {
862
+ readonly name: "TransferCharacteristics";
863
+ readonly type: "uint";
864
+ };
865
+ readonly "0x55b1": {
866
+ readonly name: "MatrixCoefficients";
867
+ readonly type: "uint";
868
+ };
869
+ readonly "0x55bb": {
870
+ readonly name: "Primaries";
871
+ readonly type: "uint";
872
+ };
873
+ readonly "0x55b9": {
874
+ readonly name: "Range";
875
+ readonly type: "uint";
876
+ };
877
+ readonly "0x55b7": {
878
+ readonly name: "ChromaSitingHorz";
879
+ readonly type: "uint";
880
+ };
881
+ readonly "0x55b8": {
882
+ readonly name: "ChromaSitingVert";
883
+ readonly type: "uint";
884
+ };
837
885
  };
838
886
  export type PossibleEbml = Prettify<{
839
887
  [key in keyof typeof ebmlMap]: EbmlParsed<(typeof ebmlMap)[key]>;
840
888
  }[keyof typeof ebmlMap]>;
889
+ export type OffsetAndChildren = {
890
+ offset: number;
891
+ children: OffsetAndChildren[];
892
+ field: keyof typeof matroskaElements;
893
+ };
894
+ export declare const incrementOffsetAndChildren: (offset: OffsetAndChildren, increment: number) => OffsetAndChildren;
895
+ export type BytesAndOffset = {
896
+ bytes: Uint8Array;
897
+ offsets: OffsetAndChildren;
898
+ };
841
899
  export type PossibleEbmlOrUint8Array = Prettify<{
842
900
  [key in keyof typeof ebmlMap]: EbmlParsedOrUint8Array<(typeof ebmlMap)[key]>;
843
- }[keyof typeof ebmlMap]> | Uint8Array;
901
+ }[keyof typeof ebmlMap]> | BytesAndOffset;
844
902
  export type EbmlMapKey = keyof typeof ebmlMap;
845
903
  export {};
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.flagDefault = exports.videoSegment = exports.audioSegment = exports.maxBlockAdditionIdSegment = exports.blockAdditionsSegment = exports.codecPrivate = exports.defaultDuration = exports.language = exports.color = exports.trackUID = exports.trackNumber = exports.tags = exports.tagSegment = exports.flagLacing = exports.displayHeight = exports.displayWidth = exports.bitDepth = exports.interlaced = exports.alphaMode = exports.channels = exports.samplingFrequency = exports.titleType = exports.infoType = exports.writingApp = exports.timestampScale = exports.duration = exports.muxingApp = exports.heightType = exports.widthType = exports.trackType = exports.codecID = exports.voidHeader = exports.seekHead = exports.seek = exports.seekPosition = exports.seekId = exports.matroskaHeader = exports.docTypeReadVersion = exports.docTypeVersion = exports.docType = exports.ebmlMaxSizeLength = exports.ebmlMaxIdLength = exports.ebmlReadVersion = exports.ebmlVersion = exports.getIdForName = exports.getSegmentName = exports.knownIdsWithThreeLength = exports.knownIdsWithTwoLength = exports.knownIdsWithOneLength = exports.matroskaElements = void 0;
4
- exports.ebmlMap = exports.cluster = exports.segment = exports.blockGroup = exports.simpleBlock = exports.block = exports.timestampEntry = exports.tracks = exports.trackEntry = exports.trackTimestampScale = exports.codecName = exports.blockElement = exports.referenceBlock = void 0;
3
+ exports.defaultDuration = exports.language = exports.ChromaSitingVert = exports.ChromaSitingHorz = exports.range = exports.primaries = exports.matrix = exports.transfer = exports.color = exports.trackUID = exports.trackNumber = exports.tags = exports.tagSegment = exports.flagLacing = exports.displayHeight = exports.displayWidth = exports.bitDepth = exports.interlaced = exports.alphaMode = exports.channels = exports.samplingFrequency = exports.titleType = exports.infoType = exports.writingApp = exports.timestampScale = exports.duration = exports.muxingApp = exports.heightType = exports.widthType = exports.trackType = exports.codecID = exports.voidHeader = exports.seekHead = exports.seek = exports.seekPosition = exports.seekId = exports.matroskaHeader = exports.docTypeReadVersion = exports.docTypeVersion = exports.docType = exports.ebmlMaxSizeLength = exports.ebmlMaxIdLength = exports.ebmlReadVersion = exports.ebmlVersion = exports.getIdForName = exports.getSegmentName = exports.knownIdsWithThreeLength = exports.knownIdsWithTwoLength = exports.knownIdsWithOneLength = exports.matroskaElements = void 0;
4
+ exports.incrementOffsetAndChildren = exports.ebmlMap = exports.cluster = exports.segment = exports.blockGroup = exports.simpleBlock = exports.block = exports.timestampEntry = exports.tracks = exports.trackEntry = exports.trackTimestampScale = exports.codecName = exports.blockElement = exports.referenceBlock = exports.flagDefault = exports.videoSegment = exports.audioSegment = exports.maxBlockAdditionIdSegment = exports.blockAdditionsSegment = exports.codecPrivate = void 0;
5
5
  exports.matroskaElements = {
6
6
  Header: '0x1a45dfa3',
7
7
  EBMLMaxIDLength: '0x42f2',
@@ -437,7 +437,31 @@ exports.trackUID = {
437
437
  };
438
438
  exports.color = {
439
439
  name: 'Colour',
440
- type: 'uint8array',
440
+ type: 'children',
441
+ };
442
+ exports.transfer = {
443
+ name: 'TransferCharacteristics',
444
+ type: 'uint',
445
+ };
446
+ exports.matrix = {
447
+ name: 'MatrixCoefficients',
448
+ type: 'uint',
449
+ };
450
+ exports.primaries = {
451
+ name: 'Primaries',
452
+ type: 'uint',
453
+ };
454
+ exports.range = {
455
+ name: 'Range',
456
+ type: 'uint',
457
+ };
458
+ exports.ChromaSitingHorz = {
459
+ name: 'ChromaSitingHorz',
460
+ type: 'uint',
461
+ };
462
+ exports.ChromaSitingVert = {
463
+ name: 'ChromaSitingVert',
464
+ type: 'uint',
441
465
  };
442
466
  exports.language = {
443
467
  name: 'Language',
@@ -469,7 +493,7 @@ exports.videoSegment = {
469
493
  };
470
494
  exports.flagDefault = {
471
495
  name: 'FlagDefault',
472
- type: 'uint8array',
496
+ type: 'uint',
473
497
  };
474
498
  exports.referenceBlock = {
475
499
  name: 'ReferenceBlock',
@@ -630,4 +654,18 @@ exports.ebmlMap = {
630
654
  name: 'Cluster',
631
655
  type: 'children',
632
656
  },
633
- };
657
+ [exports.matroskaElements.TransferCharacteristics]: exports.transfer,
658
+ [exports.matroskaElements.MatrixCoefficients]: exports.matrix,
659
+ [exports.matroskaElements.Primaries]: exports.primaries,
660
+ [exports.matroskaElements.Range]: exports.range,
661
+ [exports.matroskaElements.ChromaSitingHorz]: exports.ChromaSitingHorz,
662
+ [exports.matroskaElements.ChromaSitingVert]: exports.ChromaSitingVert,
663
+ };
664
+ const incrementOffsetAndChildren = (offset, increment) => {
665
+ return {
666
+ offset: offset.offset + increment,
667
+ children: offset.children.map((c) => (0, exports.incrementOffsetAndChildren)(c, increment)),
668
+ field: offset.field,
669
+ };
670
+ };
671
+ exports.incrementOffsetAndChildren = incrementOffsetAndChildren;
@@ -4,8 +4,8 @@ exports.expectSegment = void 0;
4
4
  const parse_ebml_1 = require("./parse-ebml");
5
5
  const parse_children_1 = require("./segments/parse-children");
6
6
  const parseSegment = async ({ segmentId, iterator, length, parserContext, headerReadSoFar, }) => {
7
- if (length === 0) {
8
- throw new Error(`Expected length of ${segmentId} to be greater than 0`);
7
+ if (length < 0) {
8
+ throw new Error(`Expected length of ${segmentId} to be greater or equal 0`);
9
9
  }
10
10
  iterator.counter.decrement(headerReadSoFar);
11
11
  const offset = iterator.counter.getOffset();
@@ -1,7 +1,13 @@
1
1
  import type { WriterInterface } from '../writers/writer';
2
+ import type { MakeTrackAudio, MakeTrackVideo } from './matroska-trackentry';
2
3
  export type MediaFn = {
3
4
  save: () => Promise<void>;
4
5
  addSample: (chunk: EncodedVideoChunk, trackNumber: number) => Promise<void>;
5
6
  updateDuration: (duration: number) => Promise<void>;
7
+ addTrack: (track: Omit<MakeTrackAudio, 'trackNumber'> | Omit<MakeTrackVideo, 'trackNumber'>) => Promise<{
8
+ trackNumber: number;
9
+ }>;
10
+ addWaitForFinishPromise: (promise: () => Promise<void>) => void;
11
+ waitForFinish: () => Promise<void>;
6
12
  };
7
13
  export declare const createMedia: (writer: WriterInterface) => Promise<MediaFn>;
@@ -10,33 +10,29 @@ const matroska_info_1 = require("./matroska-info");
10
10
  const matroska_segment_1 = require("./matroska-segment");
11
11
  const matroska_trackentry_1 = require("./matroska-trackentry");
12
12
  const createMedia = async (writer) => {
13
- var _a, _b;
13
+ var _a, _b, _c, _d;
14
14
  const header = (0, matroska_header_1.makeMatroskaHeader)();
15
15
  const w = await writer.createContent();
16
16
  await w.write(header.bytes);
17
17
  const matroskaInfo = (0, matroska_info_1.makeMatroskaInfo)({
18
18
  timescale: 1000000,
19
+ // TODO: Hardcoded
19
20
  duration: 2658,
20
21
  });
21
- const matroskaTrackEntry = (0, matroska_trackentry_1.makeMatroskaVideoTrackEntryBytes)({
22
- color: {
23
- transferChracteristics: 'bt709',
24
- matrixCoefficients: 'bt709',
25
- primaries: 'bt709',
26
- fullRange: true,
27
- },
28
- width: 1920,
29
- height: 1080,
30
- defaultDuration: 2658,
31
- trackNumber: 1,
32
- codecId: 'V_VP8',
33
- });
34
- const matroskaTracks = (0, matroska_trackentry_1.makeMatroskaTracks)([matroskaTrackEntry]);
35
- const matroskaSegment = (0, matroska_segment_1.createMatroskaSegment)([matroskaInfo, matroskaTracks]);
22
+ const currentTracks = [];
23
+ const matroskaTracks = (0, matroska_trackentry_1.makeMatroskaTracks)(currentTracks);
24
+ const matroskaSegment = (0, matroska_segment_1.createMatroskaSegment)([
25
+ matroskaInfo,
26
+ ...matroskaTracks,
27
+ ]);
36
28
  const durationOffset = ((_b = (_a = matroskaSegment.offsets.children[0].children.find((c) => c.field === 'Duration')) === null || _a === void 0 ? void 0 : _a.offset) !== null && _b !== void 0 ? _b : 0) + w.getWrittenByteCount();
29
+ const tracksOffset = ((_d = (_c = matroskaSegment.offsets.children.find((o) => o.field === 'Tracks')) === null || _c === void 0 ? void 0 : _c.offset) !== null && _d !== void 0 ? _d : 0) + w.getWrittenByteCount();
37
30
  if (!durationOffset) {
38
31
  throw new Error('could not get duration offset');
39
32
  }
33
+ if (!tracksOffset) {
34
+ throw new Error('could not get tracks offset');
35
+ }
40
36
  await w.write(matroskaSegment.bytes);
41
37
  const cluster = (0, cluster_segment_1.createClusterSegment)();
42
38
  const clusterVIntPosition = w.getWrittenByteCount() +
@@ -69,10 +65,18 @@ const createMedia = async (writer) => {
69
65
  size: '64',
70
66
  },
71
67
  minVintWidth: null,
72
- }, 1000);
68
+ },
69
+ // TODO: That's too much padding
70
+ 1000);
73
71
  await w.updateDataAt(durationOffset, (0, make_header_1.combineUint8Arrays)(blocks.map((b) => b.bytes)));
74
72
  };
73
+ const addTrack = async (track) => {
74
+ currentTracks.push(track);
75
+ const newTracks = (0, matroska_trackentry_1.makeMatroskaTracks)(currentTracks);
76
+ await w.updateDataAt(tracksOffset, (0, make_header_1.combineUint8Arrays)(newTracks.map((b) => b.bytes)));
77
+ };
75
78
  let operationProm = Promise.resolve();
79
+ const waitForFinishPromises = [];
76
80
  return {
77
81
  save: async () => {
78
82
  await w.save();
@@ -85,6 +89,20 @@ const createMedia = async (writer) => {
85
89
  operationProm = operationProm.then(() => updateDuration(duration));
86
90
  return operationProm;
87
91
  },
92
+ addTrack: (track) => {
93
+ const trackNumber = currentTracks.length + 1;
94
+ const bytes = track.type === 'video'
95
+ ? (0, matroska_trackentry_1.makeMatroskaVideoTrackEntryBytes)({ ...track, trackNumber })
96
+ : (0, matroska_trackentry_1.makeMatroskaAudioTrackEntryBytes)({ ...track, trackNumber });
97
+ operationProm = operationProm.then(() => addTrack(bytes));
98
+ return operationProm.then(() => ({ trackNumber }));
99
+ },
100
+ addWaitForFinishPromise: (promise) => {
101
+ waitForFinishPromises.push(promise);
102
+ },
103
+ async waitForFinish() {
104
+ await Promise.all(waitForFinishPromises.map((p) => p()));
105
+ },
88
106
  };
89
107
  };
90
108
  exports.createMedia = createMedia;
@@ -31,7 +31,9 @@ const makeMatroskaInfo = ({ timescale, duration, }) => {
31
31
  size: '64',
32
32
  },
33
33
  minVintWidth: null,
34
- }, 1000),
34
+ },
35
+ // TODO: That's too much padding
36
+ 1000),
35
37
  ],
36
38
  minVintWidth: null,
37
39
  });