@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
@@ -18,6 +18,6 @@ export declare const getAudioCodecStringFromTrak: (trak: TrakBox) => {
18
18
  codecString: string;
19
19
  description: Uint8Array | undefined;
20
20
  };
21
- export declare const getAudioCodecFromTrack: (track: TrakBox) => "aac" | "mp3" | "aiff";
21
+ export declare const getAudioCodecFromTrack: (track: TrakBox) => MediaParserAudioCodec;
22
22
  export declare const getAudioCodec: (boxes: AnySegment[], parserState: ParserState) => MediaParserAudioCodec | null;
23
23
  export {};
@@ -138,6 +138,9 @@ const getAudioCodecStringFromTrak = (trak) => {
138
138
  };
139
139
  exports.getAudioCodecStringFromTrak = getAudioCodecStringFromTrak;
140
140
  const getAudioCodecFromAudioCodecInfo = (codec) => {
141
+ if (codec.format === 'twos') {
142
+ return 'pcm-s16';
143
+ }
141
144
  if (codec.format === 'sowt') {
142
145
  return 'aiff';
143
146
  }
@@ -153,7 +156,7 @@ const getAudioCodecFromAudioCodecInfo = (codec) => {
153
156
  }
154
157
  throw new Error('Unknown mp4a codec: ' + codec.primarySpecificator);
155
158
  }
156
- throw new Error('Unknown audio format: ' + codec.format);
159
+ throw new Error(`Unknown audio format: ${codec.format}`);
157
160
  };
158
161
  const getAudioCodecFromTrack = (track) => {
159
162
  const audioSample = (0, exports.getAudioCodecFromTrak)(track);
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { parseMedia } from './parse-media';
4
4
  export { AudioSample, OnAudioSample, OnAudioTrack, OnVideoSample, OnVideoTrack, VideoSample, } from './webcodec-sample-types';
5
5
  export type { MediaFn } from './create/create-media';
6
6
  export { Dimensions } from './get-dimensions';
7
+ export type { ReaderInterface } from './readers/reader';
7
8
  export declare const MediaParserInternals: {
8
9
  createMedia: (writer: import("./writers/writer").WriterInterface) => Promise<import("./create/create-media").MediaFn>;
9
10
  };
@@ -13,8 +13,12 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
13
13
  hasVideoCallbacks: onVideoTrack !== null,
14
14
  signal,
15
15
  });
16
- const { reader, contentLength, name } = await readerInterface.read(src, null, signal);
16
+ const { reader, contentLength, name, supportsContentRange: readerSupportsContentRange, } = await readerInterface.read(src, null, signal);
17
17
  let currentReader = reader;
18
+ const supportsContentRange = readerSupportsContentRange &&
19
+ !(typeof process !== 'undefined' &&
20
+ typeof process.env !== 'undefined' &&
21
+ process.env.DISABLE_CONTENT_RANGE === 'true');
18
22
  const returnValue = {};
19
23
  const moreFields = more;
20
24
  let iterator = null;
@@ -27,22 +31,35 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
27
31
  nullifySamples: !(typeof process !== 'undefined' &&
28
32
  typeof process.env !== 'undefined' &&
29
33
  process.env.KEEP_SAMPLES === 'true'),
34
+ supportsContentRange,
30
35
  };
31
36
  while (parseResult === null || parseResult.status === 'incomplete') {
32
37
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
33
38
  throw new Error('Aborted');
34
39
  }
35
- const result = await currentReader.reader.read();
36
- if (iterator) {
37
- if (!result.done) {
38
- iterator.addData(result.value);
40
+ // eslint-disable-next-line no-constant-condition
41
+ while (true) {
42
+ const result = await currentReader.reader.read();
43
+ if (iterator) {
44
+ if (!result.done) {
45
+ iterator.addData(result.value);
46
+ }
47
+ }
48
+ else {
49
+ if (result.done) {
50
+ throw new Error('Unexpectedly reached EOF');
51
+ }
52
+ iterator = (0, buffer_iterator_1.getArrayBufferIterator)(result.value, contentLength !== null && contentLength !== void 0 ? contentLength : 1000000000);
53
+ }
54
+ if (iterator.bytesRemaining() >= 0) {
55
+ break;
39
56
  }
40
- }
41
- else {
42
57
  if (result.done) {
43
- throw new Error('Unexpectedly reached EOF');
58
+ break;
44
59
  }
45
- iterator = (0, buffer_iterator_1.getArrayBufferIterator)(result.value, contentLength !== null && contentLength !== void 0 ? contentLength : 1000000000);
60
+ }
61
+ if (!iterator) {
62
+ throw new Error('Unexpected null');
46
63
  }
47
64
  if (parseResult && parseResult.status === 'incomplete') {
48
65
  parseResult = await parseResult.continueParsing();
@@ -73,28 +90,20 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
73
90
  if (parseResult &&
74
91
  parseResult.status === 'incomplete' &&
75
92
  parseResult.skipTo !== null) {
93
+ if (!supportsContentRange) {
94
+ throw new Error('Content-Range header is not supported by the reader, but was asked to seek');
95
+ }
76
96
  const { reader: newReader } = await readerInterface.read(src, parseResult.skipTo, signal);
77
97
  currentReader = newReader;
78
- iterator.skipTo(parseResult.skipTo);
98
+ iterator.skipTo(parseResult.skipTo, true);
79
99
  }
80
100
  }
81
101
  // Force assign
82
102
  (0, emit_available_info_1.emitAvailableInfo)({
83
- hasInfo: {
84
- boxes: true,
85
- durationInSeconds: true,
86
- dimensions: true,
87
- fps: true,
88
- videoCodec: true,
89
- audioCodec: true,
90
- tracks: true,
91
- rotation: true,
92
- unrotatedDimensions: true,
93
- internalStats: true,
94
- size: true,
95
- name: true,
96
- container: true,
97
- },
103
+ hasInfo: Object.keys(fields !== null && fields !== void 0 ? fields : {}).reduce((acc, key) => {
104
+ acc[key] = true;
105
+ return acc;
106
+ }, {}),
98
107
  moreFields,
99
108
  parseResult,
100
109
  state,
@@ -6,4 +6,5 @@ export type ParserContext = {
6
6
  canSkipVideoData: boolean;
7
7
  parserState: ParserState;
8
8
  nullifySamples: boolean;
9
+ supportsContentRange: boolean;
9
10
  };
@@ -1,2 +1,14 @@
1
1
  import type { ReaderInterface } from './reader';
2
+ interface ParsedContentRange {
3
+ unit: string;
4
+ start?: number | null;
5
+ end?: number | null;
6
+ size?: number | null;
7
+ }
8
+ /**
9
+ * Parse Content-Range header.
10
+ * From: https://github.com/gregberge/content-range/blob/main/src/index.ts
11
+ */
12
+ export declare function parseContentRange(input: string): ParsedContentRange | null;
2
13
  export declare const fetchReader: ReaderInterface;
14
+ export {};
@@ -1,6 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchReader = void 0;
3
+ exports.fetchReader = exports.parseContentRange = void 0;
4
+ /**
5
+ * Parse Content-Range header.
6
+ * From: https://github.com/gregberge/content-range/blob/main/src/index.ts
7
+ */
8
+ function parseContentRange(input) {
9
+ const matches = input.match(/^(\w+) ((\d+)-(\d+)|\*)\/(\d+|\*)$/);
10
+ if (!matches)
11
+ return null;
12
+ const [, unit, , start, end, size] = matches;
13
+ const range = {
14
+ unit,
15
+ start: start != null ? Number(start) : null,
16
+ end: end != null ? Number(end) : null,
17
+ size: size === '*' ? null : Number(size),
18
+ };
19
+ if (range.start === null && range.end === null && range.size === null) {
20
+ return null;
21
+ }
22
+ return range;
23
+ }
24
+ exports.parseContentRange = parseContentRange;
25
+ const validateContentRangeAndDetectIfSupported = (actualRange, parsedContentRange) => {
26
+ if (typeof actualRange === 'number' &&
27
+ (parsedContentRange === null || parsedContentRange === void 0 ? void 0 : parsedContentRange.start) !== actualRange) {
28
+ if (actualRange === 0) {
29
+ return { supportsContentRange: false };
30
+ }
31
+ throw new Error(`Range header (${actualRange}) does not match content-range header (${parsedContentRange === null || parsedContentRange === void 0 ? void 0 : parsedContentRange.start})`);
32
+ }
33
+ if (actualRange !== null &&
34
+ typeof actualRange !== 'number' &&
35
+ ((parsedContentRange === null || parsedContentRange === void 0 ? void 0 : parsedContentRange.start) !== actualRange[0] ||
36
+ (parsedContentRange === null || parsedContentRange === void 0 ? void 0 : parsedContentRange.end) !== actualRange[1])) {
37
+ throw new Error(`Range header (${actualRange}) does not match content-range header (${parsedContentRange === null || parsedContentRange === void 0 ? void 0 : parsedContentRange.start})`);
38
+ }
39
+ return { supportsContentRange: true };
40
+ };
4
41
  exports.fetchReader = {
5
42
  read: async (src, range, signal) => {
6
43
  var _a;
@@ -17,26 +54,34 @@ exports.fetchReader = {
17
54
  ' is not a URL - needs to start with http:// or https:// or blob:. If you want to read a local file, pass `reader: nodeReader` to parseMedia().'));
18
55
  }
19
56
  const controller = new AbortController();
57
+ const cache = typeof navigator !== 'undefined' &&
58
+ navigator.userAgent.includes('Cloudflare-Workers')
59
+ ? undefined
60
+ : // Disable Next.js caching
61
+ 'no-store';
62
+ const actualRange = range === null ? 0 : range;
20
63
  const res = await fetch(resolvedUrl, {
21
- headers: range === null
22
- ? {}
23
- : typeof range === 'number'
24
- ? {
25
- Range: `bytes=${range}`,
26
- }
27
- : {
28
- Range: `bytes=${`${range[0]}-${range[1]}`}`,
29
- },
64
+ headers: typeof actualRange === 'number'
65
+ ? {
66
+ Range: `bytes=${actualRange}-`,
67
+ }
68
+ : {
69
+ Range: `bytes=${`${actualRange[0]}-${actualRange[1]}`}`,
70
+ },
30
71
  signal: controller.signal,
31
- // Disable Next.js caching
32
- cache: 'no-store',
72
+ cache,
33
73
  });
74
+ const contentRange = res.headers.get('content-range');
75
+ const parsedContentRange = contentRange
76
+ ? parseContentRange(contentRange)
77
+ : null;
78
+ const { supportsContentRange } = validateContentRangeAndDetectIfSupported(actualRange, parsedContentRange);
34
79
  signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', () => {
35
80
  controller.abort();
36
81
  }, { once: true });
37
82
  if (res.status.toString().startsWith('4') ||
38
83
  res.status.toString().startsWith('5')) {
39
- throw new Error(`Server returned status code ${res.status} for ${src}`);
84
+ throw new Error(`Server returned status code ${res.status} for ${src} and range ${actualRange}`);
40
85
  }
41
86
  if (!res.body) {
42
87
  throw new Error('No body');
@@ -63,6 +108,7 @@ exports.fetchReader = {
63
108
  },
64
109
  contentLength,
65
110
  name: name !== null && name !== void 0 ? name : fallbackName,
111
+ supportsContentRange,
66
112
  };
67
113
  },
68
114
  getLength: async (src) => {
@@ -38,6 +38,7 @@ exports.nodeReader = {
38
38
  },
39
39
  contentLength: stats.size,
40
40
  name: src.split('/').pop(),
41
+ supportsContentRange: true,
41
42
  };
42
43
  },
43
44
  getLength: async (src) => {
@@ -35,6 +35,7 @@ exports.webFileReader = {
35
35
  },
36
36
  contentLength: file.size,
37
37
  name: file.name,
38
+ supportsContentRange: true,
38
39
  });
39
40
  };
40
41
  reader.onerror = (error) => {
@@ -6,6 +6,7 @@ type ReadResult = {
6
6
  reader: Reader;
7
7
  contentLength: number | null;
8
8
  name: string;
9
+ supportsContentRange: boolean;
9
10
  };
10
11
  type ReadContent = (src: string | File, range: [number, number] | number | null, signal: AbortSignal | undefined) => Promise<ReadResult>;
11
12
  type GetLength = (src: string | File) => Promise<number>;
@@ -14,6 +14,7 @@ import type { TfhdBox } from './boxes/iso-base-media/tfhd';
14
14
  import type { TkhdBox } from './boxes/iso-base-media/tkhd';
15
15
  import type { TrakBox } from './boxes/iso-base-media/trak/trak';
16
16
  import type { TrunBox } from './boxes/iso-base-media/trun';
17
+ import type { AudioSegment, ClusterSegment, CodecIdSegment, DisplayHeightSegment, DisplayWidthSegment, HeightSegment, MainSegment, TimestampScaleSegment, TrackEntry, TrackTypeSegment, VideoSegment, WidthSegment } from './boxes/webm/segments/all-segments';
17
18
  import type { AnySegment, IsoBaseMediaBox, RegularBox } from './parse-result';
18
19
  export declare const getFtypBox: (segments: AnySegment[]) => FtypBox | null;
19
20
  export declare const getMoovBox: (segments: AnySegment[]) => MoovBox | null;
@@ -35,6 +36,26 @@ 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[];
39
+ export declare const getClusterSegment: (segment: MainSegment) => ClusterSegment | null;
40
+ export declare const getTracksSegment: (segment: MainSegment) => {
41
+ type: "Tracks";
42
+ value: import("./boxes/webm/segments/all-segments").PossibleEbml[];
43
+ minVintWidth: number | null;
44
+ } | null;
45
+ export declare const getTimescaleSegment: (segment: MainSegment) => TimestampScaleSegment | null;
46
+ export declare const getVideoSegment: (track: TrackEntry) => VideoSegment | null;
47
+ export declare const getAudioSegment: (track: TrackEntry) => AudioSegment | null;
48
+ export declare const getSampleRate: (track: TrackEntry) => number | null;
49
+ export declare const getNumberOfChannels: (track: TrackEntry) => number;
50
+ export declare const getBitDepth: (track: TrackEntry) => number | null;
51
+ export declare const getPrivateData: (track: TrackEntry) => Uint8Array | null;
52
+ export declare const getWidthSegment: (track: TrackEntry) => WidthSegment | null;
53
+ export declare const getHeightSegment: (track: TrackEntry) => HeightSegment | null;
54
+ export declare const getDisplayWidthSegment: (track: TrackEntry) => DisplayWidthSegment | null;
55
+ export declare const getDisplayHeightSegment: (track: TrackEntry) => DisplayHeightSegment | null;
56
+ export declare const getTrackTypeSegment: (track: TrackEntry) => TrackTypeSegment | null;
57
+ export declare const getTrackId: (track: TrackEntry) => number;
58
+ export declare const getCodecSegment: (track: TrackEntry) => CodecIdSegment | null;
38
59
  export declare const hasSkippedMdatProcessing: (anySegment: AnySegment[]) => {
39
60
  skipped: false;
40
61
  fileOffset?: undefined;
package/dist/traversal.js CHANGED
@@ -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.hasSkippedMdatProcessing = exports.getCodecSegment = exports.getTrackId = exports.getTrackTypeSegment = exports.getDisplayHeightSegment = exports.getDisplayWidthSegment = exports.getHeightSegment = exports.getWidthSegment = exports.getPrivateData = exports.getBitDepth = exports.getNumberOfChannels = exports.getSampleRate = exports.getAudioSegment = exports.getVideoSegment = exports.getTimescaleSegment = exports.getTracksSegment = exports.getClusterSegment = 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,6 +188,163 @@ const getTrunBoxes = (segment) => {
188
188
  return trunBoxes;
189
189
  };
190
190
  exports.getTrunBoxes = getTrunBoxes;
191
+ const getClusterSegment = (segment) => {
192
+ const clusterSegment = segment.value.find((b) => b.type === 'Cluster');
193
+ return clusterSegment !== null && clusterSegment !== void 0 ? clusterSegment : null;
194
+ };
195
+ exports.getClusterSegment = getClusterSegment;
196
+ const getTracksSegment = (segment) => {
197
+ const tracksSegment = segment.value.find((b) => b.type === 'Tracks');
198
+ if (!tracksSegment || tracksSegment.type !== 'Tracks') {
199
+ return null;
200
+ }
201
+ return tracksSegment;
202
+ };
203
+ exports.getTracksSegment = getTracksSegment;
204
+ const getTimescaleSegment = (segment) => {
205
+ const infoSegment = segment.value.find((b) => b.type === 'Info');
206
+ if (!infoSegment || infoSegment.type !== 'Info') {
207
+ return null;
208
+ }
209
+ const timescale = infoSegment.value.find((b) => b.type === 'TimestampScale');
210
+ if (!timescale || timescale.type !== 'TimestampScale') {
211
+ return null;
212
+ }
213
+ return timescale;
214
+ };
215
+ exports.getTimescaleSegment = getTimescaleSegment;
216
+ const getVideoSegment = (track) => {
217
+ const videoSegment = track.value.find((b) => b.type === 'Video');
218
+ if (!videoSegment || videoSegment.type !== 'Video') {
219
+ return null;
220
+ }
221
+ return videoSegment !== null && videoSegment !== void 0 ? videoSegment : null;
222
+ };
223
+ exports.getVideoSegment = getVideoSegment;
224
+ const getAudioSegment = (track) => {
225
+ const audioSegment = track.value.find((b) => b.type === 'Audio');
226
+ if (!audioSegment || audioSegment.type !== 'Audio') {
227
+ return null;
228
+ }
229
+ return audioSegment !== null && audioSegment !== void 0 ? audioSegment : null;
230
+ };
231
+ exports.getAudioSegment = getAudioSegment;
232
+ const getSampleRate = (track) => {
233
+ const audioSegment = (0, exports.getAudioSegment)(track);
234
+ if (!audioSegment) {
235
+ return null;
236
+ }
237
+ const samplingFrequency = audioSegment.value.find((b) => b.type === 'SamplingFrequency');
238
+ if (!samplingFrequency || samplingFrequency.type !== 'SamplingFrequency') {
239
+ return null;
240
+ }
241
+ return samplingFrequency.value.value;
242
+ };
243
+ exports.getSampleRate = getSampleRate;
244
+ const getNumberOfChannels = (track) => {
245
+ const audioSegment = (0, exports.getAudioSegment)(track);
246
+ if (!audioSegment) {
247
+ throw new Error('Could not find audio segment');
248
+ }
249
+ const channels = audioSegment.value.find((b) => b.type === 'Channels');
250
+ if (!channels || channels.type !== 'Channels') {
251
+ return 1;
252
+ }
253
+ return channels.value.value;
254
+ };
255
+ exports.getNumberOfChannels = getNumberOfChannels;
256
+ const getBitDepth = (track) => {
257
+ const audioSegment = (0, exports.getAudioSegment)(track);
258
+ if (!audioSegment) {
259
+ return null;
260
+ }
261
+ const bitDepth = audioSegment.value.find((b) => b.type === 'BitDepth');
262
+ if (!bitDepth || bitDepth.type !== 'BitDepth') {
263
+ return null;
264
+ }
265
+ return bitDepth.value.value;
266
+ };
267
+ exports.getBitDepth = getBitDepth;
268
+ const getPrivateData = (track) => {
269
+ const privateData = track.value.find((b) => b.type === 'CodecPrivate');
270
+ if (!privateData || privateData.type !== 'CodecPrivate') {
271
+ return null;
272
+ }
273
+ return privateData.value;
274
+ };
275
+ exports.getPrivateData = getPrivateData;
276
+ const getWidthSegment = (track) => {
277
+ const videoSegment = (0, exports.getVideoSegment)(track);
278
+ if (!videoSegment) {
279
+ return null;
280
+ }
281
+ const width = videoSegment.value.find((b) => b.type === 'PixelWidth');
282
+ if (!width || width.type !== 'PixelWidth') {
283
+ return null;
284
+ }
285
+ return width;
286
+ };
287
+ exports.getWidthSegment = getWidthSegment;
288
+ const getHeightSegment = (track) => {
289
+ const videoSegment = (0, exports.getVideoSegment)(track);
290
+ if (!videoSegment) {
291
+ return null;
292
+ }
293
+ const height = videoSegment.value.find((b) => b.type === 'PixelHeight');
294
+ if (!height || height.type !== 'PixelHeight') {
295
+ return null;
296
+ }
297
+ return height;
298
+ };
299
+ exports.getHeightSegment = getHeightSegment;
300
+ const getDisplayWidthSegment = (track) => {
301
+ const videoSegment = (0, exports.getVideoSegment)(track);
302
+ if (!videoSegment) {
303
+ return null;
304
+ }
305
+ const displayWidth = videoSegment.value.find((b) => b.type === 'DisplayWidth');
306
+ if (!displayWidth || displayWidth.type !== 'DisplayWidth') {
307
+ return null;
308
+ }
309
+ return displayWidth;
310
+ };
311
+ exports.getDisplayWidthSegment = getDisplayWidthSegment;
312
+ const getDisplayHeightSegment = (track) => {
313
+ const videoSegment = (0, exports.getVideoSegment)(track);
314
+ if (!videoSegment) {
315
+ return null;
316
+ }
317
+ const displayHeight = videoSegment.value.find((b) => b.type === 'DisplayHeight');
318
+ if (!displayHeight || displayHeight.type !== 'DisplayHeight') {
319
+ return null;
320
+ }
321
+ return displayHeight;
322
+ };
323
+ exports.getDisplayHeightSegment = getDisplayHeightSegment;
324
+ const getTrackTypeSegment = (track) => {
325
+ const trackType = track.value.find((b) => b.type === 'TrackType');
326
+ if (!trackType || trackType.type !== 'TrackType') {
327
+ return null;
328
+ }
329
+ return trackType;
330
+ };
331
+ exports.getTrackTypeSegment = getTrackTypeSegment;
332
+ const getTrackId = (track) => {
333
+ const trackId = track.value.find((b) => b.type === 'TrackNumber');
334
+ if (!trackId || trackId.type !== 'TrackNumber') {
335
+ throw new Error('Expected track number segment');
336
+ }
337
+ return trackId.value.value;
338
+ };
339
+ exports.getTrackId = getTrackId;
340
+ const getCodecSegment = (track) => {
341
+ const codec = track.value.find((b) => b.type === 'CodecID');
342
+ if (!codec || codec.type !== 'CodecID') {
343
+ return null;
344
+ }
345
+ return codec;
346
+ };
347
+ exports.getCodecSegment = getCodecSegment;
191
348
  const hasSkippedMdatProcessing = (anySegment) => {
192
349
  const mdat = anySegment.find((b) => b.type === 'mdat-box');
193
350
  if (!mdat) {
package/package.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
4
4
  },
5
5
  "name": "@remotion/media-parser",
6
- "version": "4.0.210",
6
+ "version": "4.0.212",
7
7
  "main": "dist/index.js",
8
8
  "sideEffects": false,
9
9
  "devDependencies": {
10
10
  "@types/wicg-file-system-access": "2023.10.5",
11
- "@remotion/renderer": "4.0.210"
11
+ "@remotion/renderer": "4.0.212"
12
12
  },
13
13
  "publishConfig": {
14
14
  "access": "public"
@@ -1,3 +0,0 @@
1
- import type { ColorParameterBox } from './boxes/iso-base-media/stsd/colr';
2
- import type { Av1BitstreamHeaderSegment } from './boxes/webm/bitstream/av1/header-segment';
3
- export declare const constructAv1CodecString: (av1BitstreamHeader: Av1BitstreamHeaderSegment, colrAtom: ColorParameterBox | null) => string;
@@ -1,91 +0,0 @@
1
- "use strict";
2
- // https://aomediacodec.github.io/av1-isobmff/#codecsparam
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.constructAv1CodecString = void 0;
5
- const constructAv1CodecString = (av1BitstreamHeader, colrAtom) => {
6
- let str = 'av01.';
7
- // Profile
8
- str += av1BitstreamHeader.seq_profile;
9
- str += '.';
10
- // Level
11
- // The level parameter value SHALL equal the first level value indicated by seq_level_idx in the Sequence Header OBU
12
- str += av1BitstreamHeader.seq_level[0].seq_level_idx
13
- .toString()
14
- .padStart(2, '0');
15
- // Tier
16
- // The tier parameter value SHALL be equal to M when the first seq_tier value in the Sequence Header OBU is equal to 0, and H when it is equal to 1
17
- str += av1BitstreamHeader.seq_level[0].seq_tier ? 'H' : 'M';
18
- str += '.';
19
- // bitDepth
20
- // The bitDepth parameter value SHALL equal the value of BitDepth variable as defined in [AV1] derived from the Sequence Header OBU
21
- str += av1BitstreamHeader.color_config.bitDepth.toString().padStart(2, '0');
22
- str += '.';
23
- // monochrome
24
- // The monochrome parameter value, represented by a single digit decimal, SHALL equal the value of mono_chrome in the Sequence Header OBU
25
- str += av1BitstreamHeader.color_config.mono_chrome ? '1' : '0';
26
- str += '.';
27
- // The chromaSubsampling parameter value, represented by a three-digit decimal,
28
- // SHALL have its first digit equal to subsampling_x
29
- str += av1BitstreamHeader.color_config.subsampling_x ? '1' : '0';
30
- // and its second digit equal to subsampling_y.
31
- str += av1BitstreamHeader.color_config.subsampling_y ? '1' : '0';
32
- // If both subsampling_x and subsampling_y are set to 1, then the third digit SHALL be equal to chroma_sample_position, otherwise it SHALL be set to 0
33
- str +=
34
- av1BitstreamHeader.color_config.subsampling_x &&
35
- av1BitstreamHeader.color_config.subsampling_y
36
- ? av1BitstreamHeader.color_config.chroma_sample_position === 1
37
- ? '1'
38
- : '0'
39
- : '0';
40
- str += '.';
41
- // The colorPrimaries, transferCharacteristics, matrixCoefficients, and videoFullRangeFlag parameter values are set as follows:
42
- // If a colr box with colour_type set to nclx is present, the colorPrimaries, transferCharacteristics, matrixCoefficients, and videoFullRangeFlag parameter values SHALL equal the values of matching fields in the colr box.
43
- if (colrAtom) {
44
- str += colrAtom.primaries.toString().padStart(2, '0');
45
- str += '.';
46
- str += colrAtom.transfer.toString().padStart(2, '0');
47
- str += '.';
48
- str += colrAtom.matrixIndex.toString().padStart(2, '0');
49
- str += '.';
50
- str += colrAtom.fullRangeFlag ? '1' : '0';
51
- }
52
- // Otherwise, a colr box with colour_type set to nclx is absent.
53
- // If the color_description_present_flag is set to 1 in the Sequence Header OBU, the colorPrimaries, transferCharacteristics, and matrixCoefficients parameter values SHALL equal the values of matching fields in the Sequence Header OBU.
54
- else if (av1BitstreamHeader.color_config.color_description_present_flag) {
55
- str += av1BitstreamHeader.color_config.color_primaries
56
- .toString()
57
- .padStart(2, '0');
58
- str += '.';
59
- str += av1BitstreamHeader.color_config.transfer_characteristics
60
- .toString()
61
- .padStart(2, '0');
62
- str += '.';
63
- str += av1BitstreamHeader.color_config.matrix_coefficients
64
- .toString()
65
- .padStart(2, '0');
66
- str += '.';
67
- // The videoFullRangeFlag parameter value SHALL equal the color_range flag in the Sequence Header OBU.
68
- str += av1BitstreamHeader.color_config.color_range ? '1' : '0';
69
- }
70
- else {
71
- // Otherwise, the color_description_present_flag is set to 0 in the Sequence Header OBU. The colorPrimaries, transferCharacteristics, and matrixCoefficients parameter values SHOULD be set to the default values below.
72
- // colorPrimaries 01 (ITU-R BT.709)
73
- str += '01';
74
- str += '.';
75
- // transferCharacteristics 01 (ITU-R BT.709)
76
- str += '01';
77
- str += '.';
78
- // matrixCoefficients 00 (ITU-R BT.709)
79
- str += '01';
80
- str += '.';
81
- // videoFullRangeFlag 0 (studio swing representation)
82
- str += '0';
83
- }
84
- // If the codecs parameter string ends with ".0.110.01.01.01.0" (containing all the default values below), that trailing part of the string SHOULD be omitted.
85
- const suffix = '.0.110.01.01.01.0';
86
- if (str.endsWith(suffix)) {
87
- str = str.slice(0, -suffix.length);
88
- }
89
- return str;
90
- };
91
- exports.constructAv1CodecString = constructAv1CodecString;
@@ -1,9 +0,0 @@
1
- import type { BaseBox } from './base-type';
2
- export interface FtypBox extends BaseBox {
3
- type: 'ftyp-box';
4
- majorBrand: string;
5
- minorVersion: number;
6
- compatibleBrands: string[];
7
- }
8
- export declare const fourByteToNumber: (data: ArrayBuffer, from: number) => number;
9
- export declare const parseFtyp: (data: ArrayBuffer, offset: number) => FtypBox;
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseFtyp = exports.fourByteToNumber = void 0;
4
- const fourByteToNumber = (data, from) => {
5
- const view = new DataView(data);
6
- return ((view.getUint8(from + 0) << 24) |
7
- (view.getUint8(from + 1) << 16) |
8
- (view.getUint8(from + 2) << 8) |
9
- view.getUint8(from + 3));
10
- };
11
- exports.fourByteToNumber = fourByteToNumber;
12
- const parseFtyp = (data, offset) => {
13
- const majorBrand = new TextDecoder().decode(data.slice(8, 12)).trim();
14
- const minorVersion = (0, exports.fourByteToNumber)(data, 12);
15
- const rest = data.slice(16);
16
- const types = rest.byteLength / 4;
17
- const compatibleBrands = [];
18
- for (let i = 0; i < types; i++) {
19
- const fourBytes = rest.slice(i * 4, i * 4 + 4);
20
- compatibleBrands.push(new TextDecoder().decode(fourBytes).trim());
21
- }
22
- return {
23
- type: 'ftyp-box',
24
- majorBrand,
25
- minorVersion,
26
- compatibleBrands,
27
- offset,
28
- boxSize: data.byteLength,
29
- };
30
- };
31
- exports.parseFtyp = parseFtyp;