@remotion/media-parser 4.0.208 → 4.0.210

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 (215) hide show
  1. package/buffer.js +2 -0
  2. package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +1 -1
  3. package/dist/boxes/iso-base-media/make-track.js +14 -2
  4. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -1
  5. package/dist/boxes/iso-base-media/mdat/mdat.js +8 -3
  6. package/dist/boxes/iso-base-media/moov/moov.d.ts +2 -1
  7. package/dist/boxes/iso-base-media/moov/moov.js +2 -1
  8. package/dist/boxes/iso-base-media/process-box.d.ts +6 -3
  9. package/dist/boxes/iso-base-media/process-box.js +20 -5
  10. package/dist/boxes/iso-base-media/stsd/avcc.d.ts +1 -1
  11. package/dist/boxes/iso-base-media/stsd/avcc.js +2 -2
  12. package/dist/boxes/iso-base-media/stsd/ctts.js +2 -5
  13. package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +1 -1
  14. package/dist/boxes/iso-base-media/stsd/hvcc.js +2 -2
  15. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +2 -1
  16. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
  17. package/dist/boxes/iso-base-media/stsd/samples.d.ts +4 -2
  18. package/dist/boxes/iso-base-media/stsd/samples.js +69 -11
  19. package/dist/boxes/iso-base-media/stsd/stsd.d.ts +2 -1
  20. package/dist/boxes/iso-base-media/stsd/stsd.js +2 -1
  21. package/dist/boxes/iso-base-media/trak/trak.d.ts +2 -1
  22. package/dist/boxes/iso-base-media/trak/trak.js +2 -1
  23. package/dist/boxes/iso-base-media/traversal.d.ts +44 -0
  24. package/dist/boxes/iso-base-media/traversal.js +211 -0
  25. package/dist/boxes/webm/color.d.ts +4 -0
  26. package/dist/boxes/webm/color.js +120 -0
  27. package/dist/boxes/webm/description.js +1 -1
  28. package/dist/boxes/webm/get-ready-tracks.js +3 -3
  29. package/dist/boxes/webm/get-sample-from-block.js +1 -1
  30. package/dist/boxes/webm/get-track.js +16 -1
  31. package/dist/boxes/webm/make-track.d.ts +9 -0
  32. package/dist/boxes/webm/make-track.js +260 -0
  33. package/dist/boxes/webm/parse-ebml.js +5 -2
  34. package/dist/boxes/webm/segments/all-segments.d.ts +36 -3
  35. package/dist/boxes/webm/segments/all-segments.js +34 -6
  36. package/dist/boxes/webm/traversal.d.ts +26 -1
  37. package/dist/boxes/webm/traversal.js +214 -1
  38. package/dist/buffer-iterator.js +6 -0
  39. package/dist/create/cluster-segment.d.ts +1 -1
  40. package/dist/create/cluster-segment.js +3 -5
  41. package/dist/create/cluster.d.ts +13 -0
  42. package/dist/create/cluster.js +54 -0
  43. package/dist/create/create-media.d.ts +4 -2
  44. package/dist/create/create-media.js +87 -47
  45. package/dist/create/cues.d.ts +0 -0
  46. package/dist/create/cues.js +1 -0
  47. package/dist/create/make-duration-with-padding.d.ts +1 -0
  48. package/dist/create/make-duration-with-padding.js +15 -0
  49. package/dist/create/matroska-cues.d.ts +6 -0
  50. package/dist/create/matroska-cues.js +50 -0
  51. package/dist/create/matroska-info.d.ts +1 -2
  52. package/dist/create/matroska-info.js +3 -11
  53. package/dist/create/matroska-seek.d.ts +6 -0
  54. package/dist/create/matroska-seek.js +32 -0
  55. package/dist/create/matroska-segment.d.ts +1 -0
  56. package/dist/create/matroska-segment.js +3 -2
  57. package/dist/create/matroska-trackentry.d.ts +9 -14
  58. package/dist/create/matroska-trackentry.js +79 -94
  59. package/dist/create/timescale.d.ts +1 -0
  60. package/dist/create/timescale.js +4 -0
  61. package/dist/emit-available-info.d.ts +12 -0
  62. package/dist/emit-available-info.js +133 -0
  63. package/dist/esm/buffer.mjs +57 -0
  64. package/dist/esm/from-fetch.mjs +72 -0
  65. package/dist/esm/from-node.mjs +48 -0
  66. package/dist/esm/from-web-file.mjs +48 -0
  67. package/dist/esm/index.mjs +6689 -0
  68. package/dist/esm/web-fs.mjs +67 -0
  69. package/dist/get-audio-codec.d.ts +5 -5
  70. package/dist/get-audio-codec.js +41 -57
  71. package/dist/get-container.d.ts +4 -0
  72. package/dist/get-container.js +26 -0
  73. package/dist/get-duration.js +1 -1
  74. package/dist/get-fps.js +1 -1
  75. package/dist/get-sample-aspect-ratio.d.ts +1 -1
  76. package/dist/get-sample-aspect-ratio.js +19 -19
  77. package/dist/get-tracks.d.ts +13 -0
  78. package/dist/get-tracks.js +8 -8
  79. package/dist/get-video-codec.d.ts +5 -2
  80. package/dist/get-video-codec.js +111 -21
  81. package/dist/has-all-info.d.ts +2 -2
  82. package/dist/has-all-info.js +23 -9
  83. package/dist/index.d.ts +3 -1
  84. package/dist/options.d.ts +97 -30
  85. package/dist/parse-media.js +43 -62
  86. package/dist/parse-video.d.ts +2 -1
  87. package/dist/parse-video.js +3 -1
  88. package/dist/parser-state.js +1 -2
  89. package/dist/readers/from-fetch.js +24 -4
  90. package/dist/readers/from-node.js +13 -3
  91. package/dist/readers/from-web-file.js +14 -2
  92. package/dist/readers/reader.d.ts +6 -1
  93. package/dist/samples-from-moof.js +1 -1
  94. package/dist/traversal.d.ts +0 -21
  95. package/dist/traversal.js +1 -158
  96. package/dist/truthy.d.ts +3 -0
  97. package/dist/truthy.js +7 -0
  98. package/dist/writers/buffer.d.ts +2 -0
  99. package/dist/writers/buffer.js +58 -0
  100. package/dist/writers/web-fs.d.ts +1 -0
  101. package/dist/writers/web-fs.js +42 -18
  102. package/dist/writers/writer.d.ts +4 -2
  103. package/fetch.js +2 -0
  104. package/node.js +2 -0
  105. package/package.json +43 -8
  106. package/web-file.js +2 -0
  107. package/web-fs.js +2 -0
  108. package/.eslintrc +0 -8
  109. package/input.webm +0 -0
  110. package/src/add-new-matroska-tracks.ts +0 -23
  111. package/src/boxes/iso-base-media/base-type.ts +0 -4
  112. package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +0 -68
  113. package/src/boxes/iso-base-media/esds/esds-descriptors.ts +0 -135
  114. package/src/boxes/iso-base-media/esds/esds.ts +0 -49
  115. package/src/boxes/iso-base-media/ftyp.ts +0 -39
  116. package/src/boxes/iso-base-media/get-sample-positions-from-track.ts +0 -69
  117. package/src/boxes/iso-base-media/make-track.ts +0 -116
  118. package/src/boxes/iso-base-media/mdat/mdat.ts +0 -140
  119. package/src/boxes/iso-base-media/mdhd.ts +0 -59
  120. package/src/boxes/iso-base-media/moov/moov.ts +0 -43
  121. package/src/boxes/iso-base-media/mvhd.ts +0 -114
  122. package/src/boxes/iso-base-media/process-box.ts +0 -748
  123. package/src/boxes/iso-base-media/stsd/av1c.ts +0 -19
  124. package/src/boxes/iso-base-media/stsd/avcc.ts +0 -36
  125. package/src/boxes/iso-base-media/stsd/colr.ts +0 -49
  126. package/src/boxes/iso-base-media/stsd/ctts.ts +0 -64
  127. package/src/boxes/iso-base-media/stsd/hvcc.ts +0 -32
  128. package/src/boxes/iso-base-media/stsd/keys.ts +0 -27
  129. package/src/boxes/iso-base-media/stsd/mebx.ts +0 -54
  130. package/src/boxes/iso-base-media/stsd/pasp.ts +0 -32
  131. package/src/boxes/iso-base-media/stsd/samples.ts +0 -359
  132. package/src/boxes/iso-base-media/stsd/stco.ts +0 -52
  133. package/src/boxes/iso-base-media/stsd/stsc.ts +0 -61
  134. package/src/boxes/iso-base-media/stsd/stsd.ts +0 -55
  135. package/src/boxes/iso-base-media/stsd/stss.ts +0 -47
  136. package/src/boxes/iso-base-media/stsd/stsz.ts +0 -75
  137. package/src/boxes/iso-base-media/stsd/stts.ts +0 -62
  138. package/src/boxes/iso-base-media/tfdt.ts +0 -37
  139. package/src/boxes/iso-base-media/tfhd.ts +0 -66
  140. package/src/boxes/iso-base-media/tkhd.ts +0 -150
  141. package/src/boxes/iso-base-media/to-date.ts +0 -9
  142. package/src/boxes/iso-base-media/trak/trak.ts +0 -43
  143. package/src/boxes/iso-base-media/trun.ts +0 -74
  144. package/src/boxes/iso-base-media/void-box.ts +0 -4
  145. package/src/boxes/webm/allowed-partial-segments.ts +0 -1
  146. package/src/boxes/webm/av1-codec-private.ts +0 -113
  147. package/src/boxes/webm/description.ts +0 -104
  148. package/src/boxes/webm/ebml.ts +0 -98
  149. package/src/boxes/webm/get-ready-tracks.ts +0 -36
  150. package/src/boxes/webm/get-sample-from-block.ts +0 -125
  151. package/src/boxes/webm/get-track.ts +0 -257
  152. package/src/boxes/webm/make-header.ts +0 -253
  153. package/src/boxes/webm/parse-ebml.ts +0 -255
  154. package/src/boxes/webm/parse-webm-header.ts +0 -18
  155. package/src/boxes/webm/segments/all-segments.ts +0 -888
  156. package/src/boxes/webm/segments/block-simple-block-flags.ts +0 -52
  157. package/src/boxes/webm/segments/parse-children.ts +0 -144
  158. package/src/boxes/webm/segments/track-entry.ts +0 -38
  159. package/src/boxes/webm/segments.ts +0 -147
  160. package/src/boxes/webm/traversal.ts +0 -45
  161. package/src/buffer-iterator.ts +0 -548
  162. package/src/create/cluster-segment.ts +0 -62
  163. package/src/create/create-media.ts +0 -172
  164. package/src/create/matroska-header.ts +0 -63
  165. package/src/create/matroska-info.ts +0 -46
  166. package/src/create/matroska-segment.ts +0 -10
  167. package/src/create/matroska-trackentry.ts +0 -325
  168. package/src/get-audio-codec.ts +0 -270
  169. package/src/get-dimensions.ts +0 -47
  170. package/src/get-duration.ts +0 -103
  171. package/src/get-fps.ts +0 -113
  172. package/src/get-sample-aspect-ratio.ts +0 -204
  173. package/src/get-sample-positions.ts +0 -93
  174. package/src/get-tracks.ts +0 -147
  175. package/src/get-video-codec.ts +0 -117
  176. package/src/has-all-info.ts +0 -81
  177. package/src/index.ts +0 -18
  178. package/src/make-hvc1-codec-strings.ts +0 -55
  179. package/src/options.ts +0 -118
  180. package/src/parse-media.ts +0 -183
  181. package/src/parse-result.ts +0 -79
  182. package/src/parse-video.ts +0 -83
  183. package/src/parser-context.ts +0 -10
  184. package/src/parser-state.ts +0 -178
  185. package/src/readers/from-fetch.ts +0 -90
  186. package/src/readers/from-node.ts +0 -51
  187. package/src/readers/from-web-file.ts +0 -49
  188. package/src/readers/reader.ts +0 -15
  189. package/src/samples-from-moof.ts +0 -102
  190. package/src/test/aspect-ratio.test.ts +0 -42
  191. package/src/test/av1.test.ts +0 -108
  192. package/src/test/create-matroska.test.ts +0 -287
  193. package/src/test/duration.test.ts +0 -18
  194. package/src/test/keys.test.ts +0 -47
  195. package/src/test/matroska.test.ts +0 -463
  196. package/src/test/mvhd.test.ts +0 -94
  197. package/src/test/parse-esds.test.ts +0 -98
  198. package/src/test/parse-stco.test.ts +0 -61
  199. package/src/test/parse-stsc.test.ts +0 -104
  200. package/src/test/parse-stsz.test.ts +0 -57
  201. package/src/test/parse-stts.test.ts +0 -38
  202. package/src/test/parse-video.test.ts +0 -101
  203. package/src/test/parse-webm.test.ts +0 -17
  204. package/src/test/samples-from-moof.test.ts +0 -2496
  205. package/src/test/stream-local.test.ts +0 -743
  206. package/src/test/stream-remote.test.ts +0 -59
  207. package/src/test/stream-samples.test.ts +0 -181
  208. package/src/test/stsd.test.ts +0 -265
  209. package/src/test/tkhd.test.ts +0 -87
  210. package/src/traversal.ts +0 -528
  211. package/src/webcodec-sample-types.ts +0 -29
  212. package/src/writers/web-fs.ts +0 -50
  213. package/src/writers/writer.ts +0 -12
  214. package/tsconfig.json +0 -14
  215. package/tsconfig.tsbuildinfo +0 -1
@@ -370,6 +370,12 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
370
370
  for (let i = 1; i < actualLength; i++) {
371
371
  value = (value << 8) | d[i];
372
372
  }
373
+ // Livestreamed segments sometimes have a Cluster length of 0xFFFFFFFFFFFFFF
374
+ // which we parse as -1
375
+ // this should be treated as Infinity
376
+ if (value === -1) {
377
+ return Infinity;
378
+ }
373
379
  return value;
374
380
  },
375
381
  getUint8,
@@ -1,5 +1,5 @@
1
1
  export declare const CLUSTER_MIN_VINT_WIDTH = 8;
2
- export declare const createClusterSegment: () => import("../boxes/webm/segments/all-segments").BytesAndOffset;
2
+ export declare const createClusterSegment: (timestamp: number) => import("../boxes/webm/segments/all-segments").BytesAndOffset;
3
3
  export declare const makeSimpleBlock: ({ bytes, trackNumber, timecodeRelativeToCluster, keyframe, invisible, lacing, }: {
4
4
  bytes: Uint8Array;
5
5
  trackNumber: number;
@@ -4,15 +4,15 @@ exports.makeSimpleBlock = exports.createClusterSegment = exports.CLUSTER_MIN_VIN
4
4
  const ebml_1 = require("../boxes/webm/ebml");
5
5
  const make_header_1 = require("../boxes/webm/make-header");
6
6
  exports.CLUSTER_MIN_VINT_WIDTH = 8;
7
- const createClusterSegment = () => {
7
+ const createClusterSegment = (timestamp) => {
8
8
  return (0, make_header_1.makeMatroskaBytes)({
9
9
  type: 'Cluster',
10
10
  value: [
11
11
  {
12
12
  type: 'Timestamp',
13
- minVintWidth: 4,
13
+ minVintWidth: null,
14
14
  value: {
15
- value: 0,
15
+ value: timestamp,
16
16
  byteLength: null,
17
17
  },
18
18
  },
@@ -26,8 +26,6 @@ const makeSimpleBlock = ({ bytes, trackNumber, timecodeRelativeToCluster, keyfra
26
26
  const headerByte = (Number(keyframe) << 7) | (Number(invisible) << 3) | (lacing << 1);
27
27
  const body = (0, make_header_1.combineUint8Arrays)([
28
28
  (0, ebml_1.getVariableInt)(trackNumber, null),
29
- // TODO: Cannot encode long videos because of uint16 overflow
30
- // need to make new cluster
31
29
  (0, make_header_1.serializeUint16)(timecodeRelativeToCluster),
32
30
  new Uint8Array([headerByte]),
33
31
  bytes,
@@ -0,0 +1,13 @@
1
+ import type { Writer } from '../writers/writer';
2
+ export type AudioOrVideoSample = {
3
+ timestamp: number;
4
+ type: 'key' | 'delta';
5
+ copyTo(destination: AllowSharedBufferSource): void;
6
+ byteLength: number;
7
+ duration: number | null;
8
+ };
9
+ export declare const timestampToClusterTimestamp: (timestamp: number) => number;
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;
13
+ }>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeCluster = exports.timestampToClusterTimestamp = void 0;
4
+ const ebml_1 = require("../boxes/webm/ebml");
5
+ const make_header_1 = require("../boxes/webm/make-header");
6
+ const all_segments_1 = require("../boxes/webm/segments/all-segments");
7
+ const cluster_segment_1 = require("./cluster-segment");
8
+ const timescale_1 = require("./timescale");
9
+ const maxClusterTimestamp = 2 ** 15;
10
+ const timestampToClusterTimestamp = (timestamp) => {
11
+ return Math.round((timestamp / timescale_1.CREATE_TIME_SCALE) * 1000);
12
+ };
13
+ exports.timestampToClusterTimestamp = timestampToClusterTimestamp;
14
+ const makeCluster = async (w, timestamp) => {
15
+ const cluster = (0, cluster_segment_1.createClusterSegment)((0, exports.timestampToClusterTimestamp)(timestamp));
16
+ const clusterVIntPosition = w.getWrittenByteCount() +
17
+ cluster.offsets.offset +
18
+ (0, make_header_1.matroskaToHex)(all_segments_1.matroskaElements.Cluster).byteLength;
19
+ let clusterSize = cluster.bytes.byteLength -
20
+ (0, make_header_1.matroskaToHex)(all_segments_1.matroskaElements.Cluster).byteLength -
21
+ cluster_segment_1.CLUSTER_MIN_VINT_WIDTH;
22
+ await w.write(cluster.bytes);
23
+ const addSample = async (chunk, trackNumber) => {
24
+ const arr = new Uint8Array(chunk.byteLength);
25
+ chunk.copyTo(arr);
26
+ const timecodeRelativeToCluster = (0, exports.timestampToClusterTimestamp)(chunk.timestamp) -
27
+ (0, exports.timestampToClusterTimestamp)(timestamp);
28
+ if (timecodeRelativeToCluster < 0) {
29
+ throw new Error(`timecodeRelativeToCluster is negative (track ${trackNumber})`);
30
+ }
31
+ if (timecodeRelativeToCluster > maxClusterTimestamp) {
32
+ throw new Error(`timecodeRelativeToCluster is too big: ${timecodeRelativeToCluster} > ${maxClusterTimestamp}`);
33
+ }
34
+ const keyframe = chunk.type === 'key';
35
+ const simpleBlock = (0, cluster_segment_1.makeSimpleBlock)({
36
+ bytes: arr,
37
+ invisible: false,
38
+ keyframe,
39
+ lacing: 0,
40
+ trackNumber,
41
+ timecodeRelativeToCluster,
42
+ });
43
+ clusterSize += simpleBlock.byteLength;
44
+ await w.updateDataAt(clusterVIntPosition, (0, ebml_1.getVariableInt)(clusterSize, cluster_segment_1.CLUSTER_MIN_VINT_WIDTH));
45
+ await w.write(simpleBlock);
46
+ };
47
+ const shouldMakeNewCluster = (newT, keyframe) => {
48
+ const newTimestamp = (0, exports.timestampToClusterTimestamp)(newT);
49
+ const oldTimestamp = (0, exports.timestampToClusterTimestamp)(timestamp);
50
+ return newTimestamp - oldTimestamp >= 2000 && keyframe;
51
+ };
52
+ return { addSample, shouldMakeNewCluster };
53
+ };
54
+ exports.makeCluster = makeCluster;
@@ -1,8 +1,10 @@
1
1
  import type { WriterInterface } from '../writers/writer';
2
+ import type { AudioOrVideoSample } from './cluster';
2
3
  import type { MakeTrackAudio, MakeTrackVideo } from './matroska-trackentry';
3
4
  export type MediaFn = {
4
- save: () => Promise<void>;
5
- addSample: (chunk: EncodedVideoChunk, trackNumber: number) => Promise<void>;
5
+ save: () => Promise<File>;
6
+ remove: () => Promise<void>;
7
+ addSample: (chunk: AudioOrVideoSample, trackNumber: number) => Promise<void>;
6
8
  updateDuration: (duration: number) => Promise<void>;
7
9
  addTrack: (track: Omit<MakeTrackAudio, 'trackNumber'> | Omit<MakeTrackVideo, 'trackNumber'>) => Promise<{
8
10
  trackNumber: number;
@@ -4,104 +4,144 @@ exports.createMedia = void 0;
4
4
  const ebml_1 = require("../boxes/webm/ebml");
5
5
  const make_header_1 = require("../boxes/webm/make-header");
6
6
  const all_segments_1 = require("../boxes/webm/segments/all-segments");
7
- const cluster_segment_1 = require("./cluster-segment");
7
+ const cluster_1 = require("./cluster");
8
+ const make_duration_with_padding_1 = require("./make-duration-with-padding");
9
+ const matroska_cues_1 = require("./matroska-cues");
8
10
  const matroska_header_1 = require("./matroska-header");
9
11
  const matroska_info_1 = require("./matroska-info");
12
+ const matroska_seek_1 = require("./matroska-seek");
10
13
  const matroska_segment_1 = require("./matroska-segment");
11
14
  const matroska_trackentry_1 = require("./matroska-trackentry");
15
+ const timescale_1 = require("./timescale");
12
16
  const createMedia = async (writer) => {
13
- var _a, _b, _c, _d;
17
+ var _a, _b, _c, _d, _e, _f;
14
18
  const header = (0, matroska_header_1.makeMatroskaHeader)();
15
19
  const w = await writer.createContent();
16
20
  await w.write(header.bytes);
17
21
  const matroskaInfo = (0, matroska_info_1.makeMatroskaInfo)({
18
- timescale: 1000000,
19
- // TODO: Hardcoded
20
- duration: 2658,
22
+ timescale: timescale_1.CREATE_TIME_SCALE,
21
23
  });
22
24
  const currentTracks = [];
23
- const matroskaTracks = (0, matroska_trackentry_1.makeMatroskaTracks)(currentTracks);
25
+ const seeks = [];
26
+ const cues = [];
27
+ const trackNumbers = [];
24
28
  const matroskaSegment = (0, matroska_segment_1.createMatroskaSegment)([
25
29
  matroskaInfo,
26
- ...matroskaTracks,
30
+ ...(0, matroska_seek_1.createMatroskaSeekHead)(seeks),
31
+ ...(0, matroska_trackentry_1.makeMatroskaTracks)(currentTracks),
27
32
  ]);
28
33
  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
34
  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();
35
+ const seekHeadOffset = ((_f = (_e = matroskaSegment.offsets.children.find((o) => o.field === 'SeekHead')) === null || _e === void 0 ? void 0 : _e.offset) !== null && _f !== void 0 ? _f : 0) + w.getWrittenByteCount();
36
+ if (!seekHeadOffset) {
37
+ throw new Error('could not get seek offset');
38
+ }
30
39
  if (!durationOffset) {
31
40
  throw new Error('could not get duration offset');
32
41
  }
33
42
  if (!tracksOffset) {
34
43
  throw new Error('could not get tracks offset');
35
44
  }
45
+ seeks.push({
46
+ hexString: all_segments_1.matroskaElements.Tracks,
47
+ byte: tracksOffset - seekHeadOffset,
48
+ });
49
+ const updateSeekWrite = async () => {
50
+ const updatedSeek = (0, matroska_seek_1.createMatroskaSeekHead)(seeks);
51
+ await w.updateDataAt(seekHeadOffset, (0, make_header_1.combineUint8Arrays)(updatedSeek.map((b) => b.bytes)));
52
+ };
53
+ const segmentOffset = w.getWrittenByteCount() +
54
+ (0, make_header_1.matroskaToHex)(all_segments_1.matroskaElements.Segment).byteLength;
55
+ const updateSegmentSize = async (size) => {
56
+ const data = (0, ebml_1.getVariableInt)(size, matroska_segment_1.MATROSKA_SEGMENT_MIN_VINT_WIDTH);
57
+ await w.updateDataAt(segmentOffset, data);
58
+ };
36
59
  await w.write(matroskaSegment.bytes);
37
- const cluster = (0, cluster_segment_1.createClusterSegment)();
38
- const clusterVIntPosition = w.getWrittenByteCount() +
39
- cluster.offsets.offset +
40
- (0, make_header_1.matroskaToHex)(all_segments_1.matroskaElements.Cluster).byteLength;
41
- let clusterSize = cluster.bytes.byteLength;
42
- await w.write(cluster.bytes);
43
- const addSample = async (chunk, trackNumber) => {
44
- const arr = new Uint8Array(chunk.byteLength);
45
- chunk.copyTo(arr);
46
- const simpleBlock = (0, cluster_segment_1.makeSimpleBlock)({
47
- bytes: arr,
48
- invisible: false,
49
- keyframe: chunk.type === 'key',
50
- lacing: 0,
51
- trackNumber,
52
- // TODO: Maybe this is bad, because it's in microseconds, but should be in timescale
53
- // Maybe it only works by coincidence
54
- timecodeRelativeToCluster: Math.round(chunk.timestamp / 1000),
60
+ const clusterOffset = w.getWrittenByteCount();
61
+ let currentCluster = await (0, cluster_1.makeCluster)(w, 0);
62
+ seeks.push({
63
+ hexString: all_segments_1.matroskaElements.Cluster,
64
+ byte: clusterOffset - seekHeadOffset,
65
+ });
66
+ cues.push({
67
+ time: 0,
68
+ clusterPosition: clusterOffset - seekHeadOffset,
69
+ trackNumbers,
70
+ });
71
+ const trackNumberProgresses = {};
72
+ const getClusterOrMakeNew = async (chunk) => {
73
+ const smallestProgress = Math.min(...Object.values(trackNumberProgresses));
74
+ if (!currentCluster.shouldMakeNewCluster(smallestProgress, chunk.type === 'key')) {
75
+ return currentCluster;
76
+ }
77
+ const newCluster = w.getWrittenByteCount();
78
+ cues.push({
79
+ time: smallestProgress,
80
+ clusterPosition: newCluster - seekHeadOffset,
81
+ trackNumbers,
55
82
  });
56
- clusterSize += simpleBlock.byteLength;
57
- await w.updateDataAt(clusterVIntPosition, (0, ebml_1.getVariableInt)(clusterSize, cluster_segment_1.CLUSTER_MIN_VINT_WIDTH));
58
- await w.write(simpleBlock);
83
+ currentCluster = await (0, cluster_1.makeCluster)(w, smallestProgress);
84
+ return currentCluster;
85
+ };
86
+ const addSample = async (chunk, trackNumber) => {
87
+ var _a;
88
+ trackNumberProgresses[trackNumber] = chunk.timestamp;
89
+ const cluster = await getClusterOrMakeNew(chunk);
90
+ const newDuration = Math.round((chunk.timestamp + ((_a = chunk.duration) !== null && _a !== void 0 ? _a : 0)) / 1000);
91
+ await updateDuration(newDuration);
92
+ return cluster.addSample(chunk, trackNumber);
59
93
  };
60
94
  const updateDuration = async (newDuration) => {
61
- const blocks = (0, make_header_1.padMatroskaBytes)({
62
- type: 'Duration',
63
- value: {
64
- value: newDuration,
65
- size: '64',
66
- },
67
- minVintWidth: null,
68
- },
69
- // TODO: That's too much padding
70
- 1000);
71
- await w.updateDataAt(durationOffset, (0, make_header_1.combineUint8Arrays)(blocks.map((b) => b.bytes)));
95
+ const blocks = (0, make_duration_with_padding_1.makeDurationWithPadding)(newDuration);
96
+ await w.updateDataAt(durationOffset, blocks.bytes);
72
97
  };
73
98
  const addTrack = async (track) => {
74
99
  currentTracks.push(track);
75
100
  const newTracks = (0, matroska_trackentry_1.makeMatroskaTracks)(currentTracks);
76
101
  await w.updateDataAt(tracksOffset, (0, make_header_1.combineUint8Arrays)(newTracks.map((b) => b.bytes)));
77
102
  };
78
- let operationProm = Promise.resolve();
103
+ const operationProm = { current: Promise.resolve() };
79
104
  const waitForFinishPromises = [];
80
105
  return {
81
106
  save: async () => {
82
- await w.save();
107
+ const file = await w.save();
108
+ return file;
109
+ },
110
+ remove: async () => {
111
+ await w.remove();
83
112
  },
84
113
  addSample: (chunk, trackNumber) => {
85
- operationProm = operationProm.then(() => addSample(chunk, trackNumber));
86
- return operationProm;
114
+ operationProm.current = operationProm.current.then(() => addSample(chunk, trackNumber));
115
+ return operationProm.current;
87
116
  },
88
117
  updateDuration: (duration) => {
89
- operationProm = operationProm.then(() => updateDuration(duration));
90
- return operationProm;
118
+ operationProm.current = operationProm.current.then(() => updateDuration(duration));
119
+ return operationProm.current;
91
120
  },
92
121
  addTrack: (track) => {
93
122
  const trackNumber = currentTracks.length + 1;
94
123
  const bytes = track.type === 'video'
95
124
  ? (0, matroska_trackentry_1.makeMatroskaVideoTrackEntryBytes)({ ...track, trackNumber })
96
125
  : (0, matroska_trackentry_1.makeMatroskaAudioTrackEntryBytes)({ ...track, trackNumber });
97
- operationProm = operationProm.then(() => addTrack(bytes));
98
- return operationProm.then(() => ({ trackNumber }));
126
+ operationProm.current = operationProm.current.then(() => addTrack(bytes));
127
+ trackNumbers.push(trackNumber);
128
+ return operationProm.current.then(() => ({ trackNumber }));
99
129
  },
100
130
  addWaitForFinishPromise: (promise) => {
101
131
  waitForFinishPromises.push(promise);
102
132
  },
103
133
  async waitForFinish() {
104
134
  await Promise.all(waitForFinishPromises.map((p) => p()));
135
+ await operationProm.current;
136
+ seeks.push({
137
+ hexString: all_segments_1.matroskaElements.Cues,
138
+ byte: w.getWrittenByteCount() - seekHeadOffset,
139
+ });
140
+ await updateSeekWrite();
141
+ await w.write((0, matroska_cues_1.createMatroskaCues)(cues).bytes);
142
+ const segmentSize = w.getWrittenByteCount() - segmentOffset;
143
+ await w.waitForFinish();
144
+ await updateSegmentSize(segmentSize);
105
145
  },
106
146
  };
107
147
  };
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ export declare const makeDurationWithPadding: (newDuration: number) => import("../boxes/webm/segments/all-segments").BytesAndOffset;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeDurationWithPadding = void 0;
4
+ const make_header_1 = require("../boxes/webm/make-header");
5
+ const makeDurationWithPadding = (newDuration) => {
6
+ return (0, make_header_1.makeMatroskaBytes)({
7
+ type: 'Duration',
8
+ value: {
9
+ value: newDuration,
10
+ size: '64',
11
+ },
12
+ minVintWidth: 8,
13
+ });
14
+ };
15
+ exports.makeDurationWithPadding = makeDurationWithPadding;
@@ -0,0 +1,6 @@
1
+ export type Cue = {
2
+ time: number;
3
+ clusterPosition: number;
4
+ trackNumbers: number[];
5
+ };
6
+ export declare const createMatroskaCues: (cues: Cue[]) => import("../boxes/webm/segments/all-segments").BytesAndOffset;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMatroskaCues = void 0;
4
+ const make_header_1 = require("../boxes/webm/make-header");
5
+ const cluster_1 = require("./cluster");
6
+ const createMatroskaCues = (cues) => {
7
+ return (0, make_header_1.makeMatroskaBytes)({
8
+ type: 'Cues',
9
+ minVintWidth: null,
10
+ value: cues.map((cue) => {
11
+ return {
12
+ type: 'CuePoint',
13
+ value: [
14
+ {
15
+ type: 'CueTime',
16
+ minVintWidth: null,
17
+ value: {
18
+ value: (0, cluster_1.timestampToClusterTimestamp)(cue.time),
19
+ byteLength: null,
20
+ },
21
+ },
22
+ ...cue.trackNumbers.map((trackNumber) => ({
23
+ type: 'CueTrackPositions',
24
+ value: [
25
+ {
26
+ type: 'CueTrack',
27
+ minVintWidth: null,
28
+ value: {
29
+ value: trackNumber,
30
+ byteLength: null,
31
+ },
32
+ },
33
+ {
34
+ type: 'CueClusterPosition',
35
+ minVintWidth: null,
36
+ value: {
37
+ value: cue.clusterPosition,
38
+ byteLength: null,
39
+ },
40
+ },
41
+ ],
42
+ minVintWidth: null,
43
+ })),
44
+ ],
45
+ minVintWidth: null,
46
+ };
47
+ }),
48
+ });
49
+ };
50
+ exports.createMatroskaCues = createMatroskaCues;
@@ -1,4 +1,3 @@
1
- export declare const makeMatroskaInfo: ({ timescale, duration, }: {
1
+ export declare const makeMatroskaInfo: ({ timescale }: {
2
2
  timescale: number;
3
- duration: number;
4
3
  }) => import("../boxes/webm/segments/all-segments").BytesAndOffset;
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeMatroskaInfo = void 0;
4
4
  const make_header_1 = require("../boxes/webm/make-header");
5
- const makeMatroskaInfo = ({ timescale, duration, }) => {
5
+ const make_duration_with_padding_1 = require("./make-duration-with-padding");
6
+ const makeMatroskaInfo = ({ timescale }) => {
6
7
  return (0, make_header_1.makeMatroskaBytes)({
7
8
  type: 'Info',
8
9
  value: [
@@ -24,16 +25,7 @@ const makeMatroskaInfo = ({ timescale, duration, }) => {
24
25
  value: '@remotion/media-parser',
25
26
  minVintWidth: null,
26
27
  },
27
- ...(0, make_header_1.padMatroskaBytes)({
28
- type: 'Duration',
29
- value: {
30
- value: duration,
31
- size: '64',
32
- },
33
- minVintWidth: null,
34
- },
35
- // TODO: That's too much padding
36
- 1000),
28
+ (0, make_duration_with_padding_1.makeDurationWithPadding)(0),
37
29
  ],
38
30
  minVintWidth: null,
39
31
  });
@@ -0,0 +1,6 @@
1
+ import type { MatroskaElement } from '../boxes/webm/segments/all-segments';
2
+ export type Seek = {
3
+ hexString: MatroskaElement;
4
+ byte: number;
5
+ };
6
+ export declare const createMatroskaSeekHead: (seeks: Seek[]) => import("../boxes/webm/segments/all-segments").BytesAndOffset[];
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMatroskaSeekHead = void 0;
4
+ const make_header_1 = require("../boxes/webm/make-header");
5
+ const createMatroskaSeekHead = (seeks) => {
6
+ return (0, make_header_1.padMatroskaBytes)((0, make_header_1.makeMatroskaBytes)({
7
+ type: 'SeekHead',
8
+ minVintWidth: null,
9
+ value: seeks.map((seek) => {
10
+ return {
11
+ type: 'Seek',
12
+ minVintWidth: null,
13
+ value: [
14
+ {
15
+ type: 'SeekID',
16
+ minVintWidth: null,
17
+ value: seek.hexString,
18
+ },
19
+ {
20
+ type: 'SeekPosition',
21
+ minVintWidth: null,
22
+ value: {
23
+ value: seek.byte,
24
+ byteLength: null,
25
+ },
26
+ },
27
+ ],
28
+ };
29
+ }),
30
+ }), 200);
31
+ };
32
+ exports.createMatroskaSeekHead = createMatroskaSeekHead;
@@ -1,2 +1,3 @@
1
1
  import type { BytesAndOffset } from '../boxes/webm/segments/all-segments';
2
+ export declare const MATROSKA_SEGMENT_MIN_VINT_WIDTH = 8;
2
3
  export declare const createMatroskaSegment: (children: BytesAndOffset[]) => BytesAndOffset;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createMatroskaSegment = void 0;
3
+ exports.createMatroskaSegment = exports.MATROSKA_SEGMENT_MIN_VINT_WIDTH = void 0;
4
4
  const make_header_1 = require("../boxes/webm/make-header");
5
+ exports.MATROSKA_SEGMENT_MIN_VINT_WIDTH = 8;
5
6
  const createMatroskaSegment = (children) => {
6
7
  return (0, make_header_1.makeMatroskaBytes)({
7
8
  type: 'Segment',
8
9
  value: children,
9
- minVintWidth: 8,
10
+ minVintWidth: exports.MATROSKA_SEGMENT_MIN_VINT_WIDTH,
10
11
  });
11
12
  };
12
13
  exports.createMatroskaSegment = createMatroskaSegment;
@@ -1,32 +1,27 @@
1
1
  import type { BytesAndOffset } from '../boxes/webm/segments/all-segments';
2
- export type MatroskaColorParams = {
3
- transferChracteristics: 'bt709' | 'smpte170m' | 'iec61966-2-1' | null;
4
- matrixCoefficients: 'bt709' | 'bt470bg' | 'rgb' | 'smpte170m' | null;
5
- primaries: 'bt709' | 'smpte170m' | 'bt470bg' | null;
6
- fullRange: boolean | null;
7
- };
8
- export declare const makeMatroskaColorBytes: ({ transferChracteristics, matrixCoefficients, primaries, fullRange, }: MatroskaColorParams) => BytesAndOffset;
2
+ import type { MediaParserAudioCodec, MediaParserVideoCodec, VideoTrackColorParams } from '../get-tracks';
9
3
  export declare const makeMatroskaVideoBytes: ({ color, width, height, }: {
10
- color: MatroskaColorParams;
4
+ color: VideoTrackColorParams;
11
5
  width: number;
12
6
  height: number;
13
7
  }) => BytesAndOffset;
14
8
  export type MakeTrackAudio = {
15
9
  trackNumber: number;
16
- codecId: string;
10
+ codec: MediaParserAudioCodec;
17
11
  numberOfChannels: number;
18
12
  sampleRate: number;
19
13
  type: 'audio';
14
+ codecPrivate: Uint8Array | null;
20
15
  };
21
16
  export type MakeTrackVideo = {
22
- color: MatroskaColorParams;
17
+ color: VideoTrackColorParams;
23
18
  width: number;
24
19
  height: number;
25
- defaultDuration: number;
26
20
  trackNumber: number;
27
- codecId: string;
21
+ codec: MediaParserVideoCodec;
28
22
  type: 'video';
23
+ codecPrivate: Uint8Array | null;
29
24
  };
30
- export declare const makeMatroskaAudioTrackEntryBytes: ({ trackNumber, codecId, numberOfChannels: audioChannels, sampleRate, }: MakeTrackAudio) => BytesAndOffset;
31
- export declare const makeMatroskaVideoTrackEntryBytes: ({ color, width, height, defaultDuration, trackNumber, codecId, }: MakeTrackVideo) => BytesAndOffset;
25
+ export declare const makeMatroskaAudioTrackEntryBytes: ({ trackNumber, codec, numberOfChannels, sampleRate, codecPrivate, }: MakeTrackAudio) => BytesAndOffset;
26
+ export declare const makeMatroskaVideoTrackEntryBytes: ({ color, width, height, trackNumber, codec, codecPrivate, }: MakeTrackVideo) => BytesAndOffset;
32
27
  export declare const makeMatroskaTracks: (tracks: BytesAndOffset[]) => BytesAndOffset[];